import java.lang.Integer;

class McCarthy {

    int [] memory;
    static int calls;

    int McCarthy_rekursiv(int n) {
        ++calls;
        
        if(n>100) return n-10;
        else return McCarthy_rekursiv(McCarthy_rekursiv(n+11));
    }
    
    void initMemoization(int n) {
        if(n<111) n=112;
        memory=new int [n+1];
        for(int i=0;i<n+1;++i) 
            memory[i]=-1;
    }
    
    int McCarthy_rek_mem(int n) {
        int result=0;
        ++calls;
        
        if(memory[n]!=-1) return memory[n];
        else {
            if(n>100) result=n-10;
            else result=McCarthy_rek_mem(McCarthy_rek_mem(n+11));
            memory[n]=result;
            return result;
        }
    }


    
    int McCarthy_rek_mem_opt(int n) {
        int result=0;
        ++calls;
        
        int inner;

        if(n>100) result=n-10;
        else {
            if(memory[n+11]!=-1) {
                inner=memory[n+11];
            } else {
                inner=McCarthy_rek_mem_opt(n+11);
            }

            if(memory[inner]!=-1) {
                result=memory[inner];
            } else {
                result=McCarthy_rek_mem_opt(inner);
            }
        }
        memory[n]=result;
        return result;
    }

    public static void main(String args[]) {
        int n=(new Integer(args[0])).intValue();
        
        McCarthy a=new McCarthy();
        
        System.out.println("Rekursive Berechnung");
        int rek=a.McCarthy_rekursiv(n);
        System.out.println(rek);

        System.out.println("Rekursive Berechnung mit memoization");
        calls=0;
        a.initMemoization(n);
        int mem=a.McCarthy_rek_mem(n);
        System.out.println(mem);
        System.out.println("Hat "+calls+" mal die Funktion aufgerufen");

        System.out.println("Rekursive Berechnung mit memoization und optimierung");
        calls=0;
        a.initMemoization(n);
        mem=a.McCarthy_rek_mem_opt(n);
        System.out.println(mem);
        System.out.println("Hat "+calls+" mal die Funktion aufgerufen");

    }
}
