import java.util.ArrayList;
public class Lecture18 {

    private int work;
    private int num_calls;
    private ArrayList<Integer> ns;
    
    public Lecture18() {
        work = 0;
        num_calls = 0;
        ns = new ArrayList<Integer>();
    }
    
    public int getWork() { return work; }
    public int getNumCalls() { return num_calls; }
    public ArrayList<Integer> getNs() { return ns; }

    public void foo1(int n) {
        if (n == 0) {
            this.work++;
            return;
        }
        this.work++;
        foo1( n-1 );
    } // end foo1
    
    public void foo2(int n) {
        if (n == 0) {
            // do a constant amount of work
            this.work++;
            return;
        }
        // do a constant amount of work
        this.work++;
        foo2( n - 1 );
        foo2( n - 1 );
    }
    
    public void foo3( int n ) {
        if (n == 0) {
            // do a constant amount of work
            this.work++;
            return;
        }
        // do a constant amount of work
        this.work++;
        foo3( n/2 );
    }
    
    public void foo4( int n ) {
        if (n == 0) {
            // do a constant amount of work
            this.work++;
            return;
        }
        // do a constant amount of work
        this.work++;
        foo4( n/2 );
        foo4( n/2 );
    }
    
    public void foo5( int n ) {
        this.num_calls++;
        if (n == 0) {
            // do a constant amount of work
            this.work++;
            return;
        }
        // do n amount of work
        for (int i = 0; i < n; i++) {
            this.work++;
        }
        this.ns.add( n );
        foo5( n/2 );
        foo5( n/2 );
    }
    
    public static void main( String[] args ) {
        int[] ns = {1,2,4,8,100};
        for (int i = 0; i < ns.length; i++) {
            Lecture18 obj = new Lecture18();
            obj.foo5( ns[i] );
            System.out.println( "foo5(" + ns[i] + ") takes " + obj.getWork() + " work" );
            System.out.println( "num calls is " + obj.getNumCalls() );
            System.out.println( obj.getNs() );
        }
    }
    
}