Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
980 connectés 

  FORUM HardWare.fr
  Programmation
  Algo

  Factoriel

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Factoriel

n°1246635
Profil sup​primé
Posté le 16-11-2005 à 11:42:25  answer
 

Salut
 
Je voudrais connaitre l'algo pour faire un factoriel...
 
Merci

mood
Publicité
Posté le 16-11-2005 à 11:42:25  profilanswer
 

n°1246636
elianor
bannie 17 fois
Posté le 16-11-2005 à 11:45:25  profilanswer
 

Pose le calcul de la factorielle de manière simple, et regarde la répétition.


---------------
JE JE SUIS LIBERTINEEEEEEEEEEE JE SUIS UNE CATINNNNNNNNN §§§§§§§§
n°1246639
Profil sup​primé
Posté le 16-11-2005 à 11:48:14  answer
 

Excusez moi j'ai posté trop vite:
J'ai trouvé la réponse:  
[fixed]
fact = 1
Pour i de 1 à x
   fact = fact * i
Fin Pour

n°1249229
Pfv3
Posté le 20-11-2005 à 07:27:52  profilanswer
 

disons que c'était pas compliqué!

n°1249264
Lamarmotte
Posté le 20-11-2005 à 12:35:27  profilanswer
 

factoriel(n)
   if n=1
      return 1
   else
       return n * factoriel(n-1)
   end if
end function

n°1249341
betsamee
Asterisk Zeperyl
Posté le 20-11-2005 à 16:18:14  profilanswer
 

en effet la recursion c'est plus joli

n°1249343
sircam
I Like Trains
Posté le 20-11-2005 à 16:21:34  profilanswer
 

betsamee a écrit :

en effet la recursion c'est plus joli


Ouais, mais bon, dans la pratique, c'est malheureusement à éviter. [:djswad]


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
n°1249351
betsamee
Asterisk Zeperyl
Posté le 20-11-2005 à 16:29:59  profilanswer
 

sircam a écrit :

Ouais, mais bon, dans la pratique, c'est malheureusement à éviter. [:djswad]


question reelement innocente (je me rappeles plus trop de mes cours de C++ ca fait un bail) :
pourquoi la recursion serait a eviter dans un cas pareil ? (est ce pour eviter de tomber dans des appels infinis si la fonction est mal codee?)
pour calculer une factorielle ca semble tout a fait etre le cas typique de recursion

n°1249355
Pfv3
Posté le 20-11-2005 à 16:37:44  profilanswer
 

c'est que la récursion empile des appels de fonctions sur la pile d'appel et que passé un certain niveau de récursion imbriqué le programme crash.
 
Mais il faudrait que le nombre soit très grand pour faire suffisament d'appels  récursifs imbriqués pour que Factoriel crash.
 
D'autre part, souvent il y a un coût à chaque appel de méthode, et par conséquent, la première méthode serait peut-être plus efficace (tout dépend aussi des optimisations du compilateur / jvm)
 
Je te répond en général pour un langage comme Java ou C++.  Je ne suis pas sur de la limite dans un langage comme  LISP .

Message cité 2 fois
Message édité par Pfv3 le 20-11-2005 à 16:40:03
n°1249357
betsamee
Asterisk Zeperyl
Posté le 20-11-2005 à 16:42:30  profilanswer
 

Pfv3 a écrit :

c'est que la récursion empile des appels de fonctions sur la pile d'appel et que passé un certain niveau de récursion imbriqué le programme crash.
 
Mais il faudrait que le nombre soit très grand pour faire suffisament d'appels  récursifs imbriqués pour que Factoriel crash.
 
D'autre part, souvent il y a un coût à chaque appel de méthode, et par conséquent, la première méthode serait peut-être plus efficace (tout dépend aussi des optimisations du compilateur / jvm)
 
Je te répond en général pour un langage comme Java ou C++.  Je ne suis pas sur de la limite dans un langage comme  LISP .


ok  :jap:  

mood
Publicité
Posté le 20-11-2005 à 16:42:30  profilanswer
 

n°1249370
masklinn
í dag viðrar vel til loftárása
Posté le 20-11-2005 à 17:01:15  profilanswer
 

Pfv3 a écrit :

c'est que la récursion empile des appels de fonctions sur la pile d'appel et que passé un certain niveau de récursion imbriqué le programme crash.
 
D'autre part, souvent il y a un coût à chaque appel de méthode, et par conséquent, la première méthode serait peut-être plus efficace (tout dépend aussi des optimisations du compilateur / jvm)


Et plus le langage est de haut niveau plus ça coûte cher :o
 
En Java, ça coûte déjà bonbon, mais dans des langages comme Python ou Ruby, un appel de fonction coûte extrèmement cher.
 
Demo:

>>> def fact1(n):
    out = 1
    for i in xrange(1, n+1):
        out*=i
    return out
 
>>> def fact2(n):
    if n == 1:
        return 1
    else:
        return n*fact2(n-1)
 
 
>>> import timeit
>>> t1 = timeit.Timer(stmt="fact1(20)",setup="from __main__ import fact1" )
>>> t2 = timeit.Timer(stmt="fact2(20)",setup="from __main__ import fact2" )
>>> t1.repeat(3,1000000)
[7.4510148636209408, 7.4105803949943336, 7.4756079334105365]
>>> t2.repeat(3,1000000)
[13.908458197899463, 13.881459515105973, 13.934193591643634]
>>>


timeit.Timer permet (en python) de timer des mini bouts de code, ici on calcule factoriel(20) avec chacune des deux méthodes.
 
timeit.Timer.repeat(x,y) permet de lancer x "runs" de y exécutions du code du Timer associé, et renvoie le temps pour chacun de ces runs (la somme des temps des y exécutions).
 
Donc ici on fait 3 runs, chaque run comptant un million d'exécution de factoriel(20).
 
Et la différence en temps d'exécution (le résultat est en secondes) est d'un rapport 2 [:pingouino]


Message édité par masklinn le 20-11-2005 à 17:03:18

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1249391
sircam
I Like Trains
Posté le 20-11-2005 à 17:39:29  profilanswer
 

De plus, indépendemment de la question de pile d'appel, certains traitements récursifs sont coûteux en soi, p.e. les manip de chaînes (cette rq ne s'applique pas à factoriel).
 
Si tu fais un traitement récursif sur une chaîne, et que appelles ta fn récursivement avec des bouts de sous-chaîne, ça va te coûter un max et ta pile d'appel deviendra un problème secondaire face aux affres de la conso mémoire que tu vas te taper.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
n°1249401
Trap D
Posté le 20-11-2005 à 17:58:04  profilanswer
 

Tu veux parler des chaînes locales aux fonctions ?
Tu m'arrêtes si je dis une co****rie, mais ta pile d'appel, c'est bien la pile d'exécution, non, donc les chaînes locales en augmentent aussi la taille ?

n°1249412
sircam
I Like Trains
Posté le 20-11-2005 à 18:22:53  profilanswer
 

Ouaip, c'est plus correct et plus précis. Je tentais de faire une distinction entre le coût de l'appel récursif sensu stricto et les coûts connexes. Ces derniers peuvent devenir prohibitifs dans certains cas.


---------------
Now Playing: {SYNTAX ERROR AT LINE 1210}
n°1249422
pains-aux-​raisins
Fatal error
Posté le 20-11-2005 à 18:52:41  profilanswer
 

Masklinn >> flûte, python c'est pourri alors !
Je croyais qu'il héritait d'un noyau en C où justement les appels de fonctions sont peu cher.
Bon, heureusement que pour ce que j'en fait avec j'ai pas besoin qu'il soit trop véloce mais là je suis déçu. :/

Message cité 1 fois
Message édité par pains-aux-raisins le 20-11-2005 à 18:53:06
n°1249425
masklinn
í dag viðrar vel til loftárása
Posté le 20-11-2005 à 19:03:59  profilanswer
 

pains-aux-raisins a écrit :

Masklinn >> flûte, python c'est pourri alors !


[:petrus75]

Citation :

Je croyais qu'il héritait d'un noyau en C où justement les appels de fonctions sont peu cher.


T'as fumé?
 
Et en Python, une fonction est un objet de première classe, je ne vois même pas comment tu pourrais utiliser directement des fonctions C [:petrus75]

Citation :

Bon, heureusement que pour ce que j'en fait avec j'ai pas besoin qu'il soit trop véloce mais là je suis déçu. :/


[:petrus75]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1249446
pains-aux-​raisins
Fatal error
Posté le 20-11-2005 à 20:23:58  profilanswer
 

ouaip, ben vu la tendance actuelle, bientot les interpréteurs devront génèrer mille instructions machine pour additionner 1 et 2...
c'est le progrès quoi [:spamafote]

n°1249457
masklinn
í dag viðrar vel til loftárása
Posté le 20-11-2005 à 21:08:49  profilanswer
 

pains-aux-raisins a écrit :

ouaip, ben vu la tendance actuelle, bientot les interpréteurs devront génèrer mille instructions machine pour additionner 1 et 2...
c'est le progrès quoi [:spamafote]


J'crois que t'as un peu de mal avec le concept de niveaux de langages, et du choix à faire entre simplicité du code/vitesse de développement et vitesse d'exécution/conso mémoire [:petrus75]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1249461
pains-aux-​raisins
Fatal error
Posté le 20-11-2005 à 21:16:15  profilanswer
 

masklinn a écrit :

J'crois que t'as un peu de mal avec le concept de niveaux de langages, et du choix à faire entre simplicité du code/vitesse de développement et vitesse d'exécution/conso mémoire [:petrus75]


Tu m'a pas pris aux sérieux j'espère ?  :heink:
Je pense savoir faire la différence entre les différents niveaux de langage au moins aussi bien que toi.
Si je préconise dans ma boite du python, du .NET et autre technique RAD c'est que j'ai également posé la problèmatique ;)


Message édité par pains-aux-raisins le 20-11-2005 à 21:16:57
n°1249539
tropicano
Posté le 21-11-2005 à 01:53:15  profilanswer
 

Ben j'ai fait un petit test en OCaml  :pt1cable:  
Voici le source:

Code :
  1. (*#load "nums.cma";;*)
  2. open Num ;;
  3. open String ;;
  4. let n_depart = 20000;;
  5. let rec fact_num_r n accu =
  6.    if  n <=/  (Int 0) then  accu
  7.    else  (fact_num_r ( n -/ (Int 1)) ( Num.( */ ) n accu ) ) ;;
  8. let n_r = Num.Int n_depart;;
  9. let accu_r = Num.Int 1 ;;
  10. let debut_r = Sys.time ();;
  11. let rr = fact_num_r n_r accu_r;;
  12. let fin_r = Sys.time ();;
  13. (*let res_r =
  14.   let x = Num.string_of_num rr in (String.sub x 0 50) ^ "..." ;;*)
  15. let temp_total_r = fin_r -. debut_r;;
  16. let fact_num_i n =
  17.   let result = ref (Num.Int 1) in
  18.   for i = 2 to n do
  19.     result := Num.( */ ) (Num.num_of_int i) !result
  20.    done;
  21.    !result;;
  22. let n_i = n_depart;;
  23. let debut_i = Sys.time ();;
  24. let ri = fact_num_i n_i;;
  25. let fin_i = Sys.time ();;
  26. (*let res_i =
  27.   let y = Num.string_of_num ri in (String.sub y 0 50) ^ "..." ;;*)
  28. let temp_total_i = fin_i -. debut_i;;
  29. (=/) rr ri ;;
  30. "Le résultat comporte: "^(string_of_int (length (Num.string_of_num rr) )) ^(" chiffres" );;
  31. "Temps pour fact de "^(string_of_int n_depart)^" en récursif: "^(string_of_float temp_total_r)^(" sec" );;
  32. "Temps pour fact de "^(string_of_int n_depart)^" en impératif: "^(string_of_float temp_total_i)^(" sec" );;


 
 
Et voilà ce que ca donne:
# - : string = "Le résultat comporte: 19 chiffres"
# - : string = "Temps pour fact de 20 en récursif: 0. sec"
# - : string = "Temps pour fact de 20 en impératif: 0. sec"
 
# - : string = "Le résultat comporte: 375 chiffres"
# - : string = "Temps pour fact de 200 en récursif: 0.0100000000002 sec"
# - : string = "Temps pour fact de 200 en impératif: 0. sec"
 
# - : string = "Le résultat comporte: 5736 chiffres"
# - : string = "Temps pour fact de 2000 en récursif: 0.09 sec"
# - : string = "Temps pour fact de 2000 en impératif: 0.08 sec"
 
# - : string = "Le résultat comporte: 77338 chiffres"
# - : string = "Temps pour fact de 20000 en récursif: 7.31 sec"
# - : string = "Temps pour fact de 20000 en impératif: 6.539 sec"
 
# - : string = "Le résultat comporte: 213237 chiffres"
# - : string = "Temps pour fact de 50000 en récursif: 78.903 sec"
# - : string = "Temps pour fact de 50000 en impératif: 74.367 sec"
 
Bon c'est vrai que l'impératif est un poil plus rapide, mais bon c'est pas trop flagrant. Faut commencer à  aller  
chercher de grosse factorielle pour voir un écart se creuser.

n°1249548
matafan
Posté le 21-11-2005 à 06:23:13  profilanswer
 

En C avec libgmp sous linux, ça donne (je viens de découvrir libgmp, donc on peut surement faire mieux) :

Code :
  1. #include <sys/times.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <gmp.h>
  5. void
  6. fact_rec(unsigned long x, mpz_t *y)
  7. {
  8. if (x == 1) {
  9.  mpz_init_set_ui(*y, 1);
  10. } else {
  11.  mpz_t z;
  12.  mpz_init(z);
  13.  fact_rec(x - 1, &z);
  14.  mpz_mul_ui(*y, z, x);
  15.  mpz_clear(z);
  16. }
  17. }
  18. void
  19. fact_iter(unsigned long x, mpz_t *y)
  20. {
  21. unsigned long i;
  22. mpz_set_ui(*y, 1);
  23. for (i = 1; i <= x; i++) {
  24.  mpz_mul_ui(*y, *y, i);
  25. }
  26. }
  27. int
  28. main(int argc, char **argv)
  29. {
  30. int rc;
  31. char *endptr;
  32. long x, i;
  33. mpz_t y;
  34. struct tms t1, t2;
  35. clock_t cpu;
  36. if (argc != 3) {
  37.  fprintf(stderr, "Usage: fact <n> [i|r]\n" );
  38.  exit(1);
  39. }
  40. x = strtol(argv[1], &endptr, 10);
  41. if (*endptr != '\0' || x < 1) {
  42.  fprintf(stderr, "Invalid number \"%s\"\n", argv[1]);
  43.  exit(1);
  44. }
  45. mpz_init(y);
  46. times(&t1);
  47. if (*argv[2] == 'r') {
  48.  fact_rec(x, &y);
  49. } else if (*argv[2] == 'i') {
  50.  fact_iter(x, &y);
  51. } else {
  52.  fprintf(stderr, "Invalid selector %c\n", *argv[2]);
  53.  exit(1);
  54. }
  55. times(&t2);
  56. cpu = (t2.tms_utime + t2.tms_stime) - (t1.tms_utime + t1.tms_stime);
  57. gmp_printf("%lu! = %Zu\n", x, y);
  58. printf("%lu! has %lu digits\n", x, mpz_sizeinbase(y, 10));
  59. printf("CPU time: %f\n", ((double)cpu)/sysconf(_SC_CLK_TCK));
  60. return 0;
  61. }


Ce qui donne (je ne colle pas les factorielles ici) :

$ ./fact 50000 r
50000! has 213237 digits
CPU time: 3.660000
$ ./fact 50000 i
50000! has 213237 digits
CPU time: 3.460000
 
$ ./fact 123456 r
123456! has 574965 digits
CPU time: 31.920000
$ ./fact 123456 i
123456! has 574965 digits
CPU time: 22.690000


On voit que le récursif est de plus en plus à la traîne quand les nombres deviennent grands : seulement 5% plus lent pour 50000, mais 40% plus lent pour 123456. Pour 500000, je segfault en récursif par manque de pile... Il faudrait jouer avec les options de ld pour allouer une stack plus grande.


Message édité par matafan le 21-11-2005 à 06:32:18
n°1263483
lbasic
Posté le 10-12-2005 à 11:11:24  profilanswer
 

Histoire de completer le sujet et confirmer que le BASIC s'il est facile à apprendre, est tout sauf rapide.
 

Code :
  1. t1=time$("seconds" )
  2. r=fact(20000)
  3. t2=time$("seconds" )
  4. temp=t2-t1
  5. r$=str$(r)
  6. print temp; " sec"
  7. print "longueur : ";len(r$);" chiffres"
  8. wait
  9. function fact(k)
  10.     if k>1 then
  11.         n=k
  12.         do
  13.             n=n-1
  14.             k=k*n
  15.             scan
  16.      
  17.         loop while n>1
  18.     else
  19.         k=1
  20.     end if
  21.     fact=k
  22.     end function


 
resultat pour 20000!
 
125 sec
longueur : 77338 chiffres
 
Pour 50000! il tourne encore .....
 
@++


Message édité par lbasic le 10-12-2005 à 11:13:34

---------------
Liberty BASIC France : http://www.lbasic.fr
n°1263516
lbasic
Posté le 10-12-2005 à 12:20:06  profilanswer
 

et voila le resultat !
 
880 sec
longueur : 213237 chiffres
 
no comment please !


---------------
Liberty BASIC France : http://www.lbasic.fr
n°2105310
kiwiguigou
Posté le 07-10-2011 à 22:30:45  profilanswer
 

Bonjour à tous.
 
Dans le cadre d'un exercice de programmation basique, nous cherchons à mettre un place un programme permettant de calculer une suite de la forme :  
 
S=x+(x^3/3!)+(x^5/5!)....
 
Je cherche donc par conséquent à déterminer programmer la factorielle de la forme suivante : (2i+1)!
 
J'ai donc fais ceci (langage fortran95)
 
fact=1
DO i=2*i+1,N
fact=fact*i
END DO  
 
De manière à essayer d'avoir uniquement les factorielles impaires. Mais je ne suis pas convaincu du résultat, puisque quand N est pair, il me donne quand même une factorielle paire ...
A l'avance, je vous remercie.

n°2105315
mrbebert
Posté le 07-10-2011 à 23:12:50  profilanswer
 

Je ne connais pas trop ce langage mais je ne suis pas sur que la suite des "i" soit bien la bonne.
Plutôt :
 
fact=1
DO i=i+1,N  
fact=fact*(2*i+1)
END DO
:??:


---------------
Doucement le matin, pas trop vite le soir.
n°2105340
kiwiguigou
Posté le 08-10-2011 à 13:25:02  profilanswer
 

Merci de ta réponse.
 
Je viens de le programmer, cela ne semble pas marcher non plus.

n°2105341
gilou
Modérateur
Modzilla
Posté le 08-10-2011 à 14:04:14  profilanswer
 

Bon déjà je comprends pas trop ce que vous faites:
pour calculer la factorielle de 2N+1, on fait:
fact = 1  
DO i = 1, 2*N+1
fact = fact*i  
END DO  
Parce que dans une factorielle, il y a tous les facteurs, qu'ils soient impairs ou pair.
 
Et d'autre part, si en Fortran, on veut faire une boucle sur les nombres impairs inférieurs ou égal à N, on fait
DO i = 1, N, 2
...
END DO  
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2105377
Profil sup​primé
Posté le 08-10-2011 à 20:00:54  answer
 

Revoici Jovalise...
 
Décidément les résultat sont surprenant, Gilou !
 
Voilà le mon code avec Ada
 

Code :
  1. -- Sum function for S=X+(x^3/3!)+(x^5/5!).
  2. -- where X expected on command arguments.
  3.  
  4. with Ada.Command_Line;
  5. use Ada.Command_Line;
  6. with Text_Io;
  7. use Text_Io;
  8.  
  9. procedure Main is
  10.  
  11.   subtype My_integer_Type is Long_Long_integer range 0..Long_Long_Integer'Last;
  12.  
  13.   function Facto(Input : in My_Integer_Type) return My_Integer_Type is
  14.   begin
  15.      if Input = 1 then
  16.         return 1;
  17.      else
  18.         return Input * facto(Input-1);
  19.      end if;
  20.   end Facto;
  21.  
  22.  
  23.   X : Integer;
  24.  
  25.   Odd : integer := 3;
  26.  
  27.   S : My_Integer_Type := 0;
  28.  
  29. begin
  30.  
  31.   if Argument_Count /= 1 then
  32.      raise Program_Error;
  33.   end if;
  34.   X := Integer'Value(Argument(1));
  35.   S := My_Integer_Type(X);
  36.   Put_line(Character'Val(13)  & "S=" & My_Integer_Type'Image(S));
  37.   loop
  38.      S := My_Integer_Type(X) +
  39.        (My_Integer_Type(X**Odd)/Facto(My_Integer_Type(Odd)));
  40.  
  41.      Odd := Odd + 2;
  42.      Put_line(Character'Val(13)  & "S=" & My_Integer_Type'Image(S));
  43.   end loop;
  44. exception
  45.   when Constraint_Error =>
  46.      New_Line;
  47.      Put_Line("Argument error..." );
  48.  
  49. end Main;


 
 
Et voici les résultat pour X alant de 1 à 9
 

S= 1
 
S= 1
 
S= 1
 
S= 1
 
S= 1
 
S= 1
 
S= 1
 
S= 1
 
S= 1
 
S= 1
 
Argument error...
 
S= 2
 
S= 3
 
S= 2
 
S= 2
 
S= 2
 
S= 2
 
S= 2
 
S= 2
 
S= 2
 
S= 2
 
Argument error...
 
S= 3
 
S= 7
 
S= 5
 
S= 3
 
S= 3
 
S= 3
 
S= 3
 
S= 3
 
S= 3
 
S= 3
 
Argument error...
 
S= 4
 
S= 14
 
S= 12
 
S= 7
 
S= 4
 
S= 4
 
S= 4
 
S= 4
 
S= 4
 
S= 4
 
Argument error...
 
S= 5
 
S= 25
 
S= 31
 
S= 20
 
S= 10
 
S= 6
 
S= 5
 
S= 5
 
Argument error...
 
S= 6
 
S= 42
 
S= 70
 
S= 61
 
S= 33
 
S= 15
 
S= 6
 
S= 6
 
S= 6
 
Argument error...
 
S= 7
 
S= 64
 
S= 147
 
S= 170
 
S= 118
 
S= 56
 
Argument error...
 
S= 8
 
S= 93
 
S= 281
 
S= 424
 
S= 377
 
S= 8
 
S= 8
 
S= 8
 
S= 8
 
S= 8
 
Argument error...
 
S= 9
 
S= 130
 
S= 501
 
S= 958
 
S= 1076
 
S= 41
 
Argument error...

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Algo

  Factoriel

 

Sujets relatifs
Plus de sujets relatifs à : Factoriel


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR