/* Calcul de n! par methodes recursive          */
/* et iteratives                                */
/* Mesures de temps                             */

public class FonctionsFactorielAvecMinuteur {

/* Fonction de calcul et retour                 */
/* de n! par methode récursive                  */
/* Définition:                                  */
/*  - 0! = 1                                    */
/*  - n! = (n-1)!*n si n > 0                    */
/* n : valeur pour laquelle n! est calculé      */

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

/* Fonction de calcul et retour                 */
/* de n! par methode itérative                  */
/* Définition:                                  */
/*  - 0! = 1                                    */
/*  - n! = 1 * 2 * 3 * ... * n si n > 0         */
/* n : valeur pour laquelle n! est calculé      */

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

  public static void main(String [] args) {
    Ecran.afficherln("             Iteratif                    Recursif");
    Ecran.afficherln("  n   temps moyen temps moyen/n   temps moyen temps moyen/n");
    for ( int n = 100 ; n <= 10000 ; n += 100 ) {
      Ecran.formater("%3d :",n);
      { Utilitaires.Minuteur minuteur = new Utilitaires.Minuteur();
        minuteur.temps = 5000;
        minuteur.lancement();
        long cpt = 0;
        long ti = System.nanoTime();
        while ( minuteur.enCours == true ) {
          factorielIteratif(n);
          cpt++; }
        long tf = System.nanoTime();
        tf -= cpt*15;
        Ecran.formater(" %8.3f ns",(double) (tf-ti)/cpt);
        Ecran.formater(" %11.3f",((double) (tf-ti)/cpt)/n); }
      { Utilitaires.Minuteur minuteur = new Utilitaires.Minuteur();
        minuteur.temps = 5000;
        minuteur.lancement();
        long cpt = 0;
        long ti = System.nanoTime();
        while ( minuteur.enCours == true ) {
          factorielRecursif(n);
          cpt++; }
        long tf = System.nanoTime();
        tf -= cpt*15;
        Ecran.formater(" %12.3f ns",(double) (tf-ti)/cpt);
        Ecran.formater(" %11.3f",((double) (tf-ti)/cpt)/n); }
      Ecran.sautDeLigne();
    }
  }
}