/* Calcul de factoriel                         */
/* Evaluation du temps d'execution             */  

public class TestFactoriel {

/////////////////////////////////////////////////

/* Calcul de n! par methode recursive          */
/*  - 0! = 1                                   */
/*  - n! = (n-1)!*n                            */

  static long factorielRecursif(int n) {
    if ( n == 0 ) {
      return 1; }
      else {
      return factorielRecursif(n-1)*n; }
  }

/* Calcul de n! par methode sequentielle       */

  static long factorielSequentiel(int n) {
    long res = 1;
    if ( n > 1 )
      for ( int i = 2 ; i <= n ; i++ ) {
        res = res*i; }
    return res;
  }

  static void testsFactoriel(int temps,int ni,int nf,int inc) {
    Ecran.afficherln("Itératif   récursif");
    Ecran.formater("%6s%21s%12s%14s%14s%14s%12s%14s%14s%14s\n",
                   "Niveau","Resultat","Appels","Temps total",
                   "Temps moyen","o(n)",
                   "Appels","Temps total","Temps moyen","o(n)");
    for ( int nu = ni ; nu <= nf ; nu = nu+inc ) {
      long n  = factorielSequentiel(nu);
      { Utilitaires.Minuteur mntr = new Utilitaires.Minuteur();
        mntr.temps = temps*1000;
        mntr.lancement();
        long i = 0;
        long ti = System.nanoTime();
        do {
          factorielSequentiel(nu);
          i++; }
        while ( mntr.enCours );
        long t = System.nanoTime()-ti;
        Ecran.formater("%6d%21d%12d%14d%14.3f%14.4f",
                       nu,n,i,t,(double) t/i,(double) t/i/nu); }
      { Utilitaires.Minuteur mntr = new Utilitaires.Minuteur();
        mntr.temps = temps*1000;
        mntr.lancement();
        long i = 0;
        long ti = System.nanoTime();
        do {
          factorielRecursif(nu);
          i++; }
        while ( mntr.enCours );
        long t = System.nanoTime()-ti;
        Ecran.formater("%12d%14d%14.3f%14.4f\n",
                       i,t,(double) t/i,(double) t/i/nu); } }
  }

/////////////////////////////////////////////////
  
/* Programme principal                         */

  public static void main(String [] args) {
    Ecran.afficher("Nombre de secondes de test? ");
    int temps = Clavier.saisirInt();
    Ecran.afficher("Niveau initial?   ");
    int ni = Clavier.saisirInt();
    Ecran.afficher("Niveau de fin ?   ");
    int nf = Clavier.saisirInt();
    Ecran.afficher("Increment     ?   ");
    int inc = Clavier.saisirInt();
    testsFactoriel(temps,ni,nf,inc);
  }
}