public class Fact {
  public static int fact(int n) {
    int res = 1;
    for (int i=1; i<=n; i++) {
      res  = res*i;
    }
    return res;
  }
  public static int factRec(int n) {
    if (n==0) return 1;
    return n*factRec(n-1); // pas une récursive terminal
  }
  public static int factRecDepliee(int n) {
    System.out.println("appel à depliee("+n+")");
    if (n==0) return 1;
    int v = factRecDepliee(n-1);
    v = v*n;
    System.out.println("calcul de v="+v);
    return v; // la dernière instruction c'est une multiplication
  }
  public static int factRecTerminaleNormalisee(int n) {
    return factRecTerminale(n,1);
  }
  public static int factRecTerminale(int n,int f) {
    System.out.println("terminale("+n+","+f+")");
    if (n==0) return f;
    return factRecTerminale(n-1,n*f);
  }
  public static int factRecTerminaleDeRec(int n,int f) {
    while (n!=0) {
      f = f*n;
      n = n-1;
    }
    return f;
  }
  public static void main(String []args) {
    /*
    System.out.println(fact(10));
    System.out.println(factRec(10));
    f(10);
    //    fRec(0,10);
    fRecNormalisee(10);
    */
    System.out.println(factRecDepliee(10));
    System.out.println(factRecTerminaleNormalisee(10));
  }
  public static void f(int n) {
    for (int i=0; i<n; i++) {
      System.out.println("valeur de i="+i); // corps de la boucle
    }
  }
  public static void fRecNormalisee(int n) {
    fRec(0,n); // initialisation de i à 0
  }
  public static void fRec(int i,int n) {
    if (i==n) return; // fin de la "boucle"
    System.out.println("valeur de i="+i); // corps de la boucle
    // appel récursif terminal (il n'y a rien d'autre qui suit)
    fRec(i+1,n); // pas suivant de la boucle
  }
  public static void fRecDerec(int i,int n) {
    while (i!=n) {
      System.out.println("valeur de i="+i);
      i = i+1;
    }
  }
}