Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Exercice] La factorielle et ses analogues

Traitement de grands nombres et récursivité

    17 mars 2011 à 19:54:29

    La factorielle et ses analogues

    Traitement de grands nombres et récursivité
    </span>

    En mathématiques, la factorielle d'un entier naturel n, notée <math>\(n!\)</math> est le produit des nombres entiers strictement positifs inférieurs ou égaux à n. Mais saviez-vous qu'il existe des fonctions analogues à la factorielle ? Primorielle, multifactorielles, hyperfactorielle, superfactorielle, sous-factorielle etc, la famille est grande ; je vous propose aujourd'hui d'en découvrir quelques unes, pythonniquement bien sûr.

    La factorielle


    Rappel


    Factorielle Expression Resultat
    <math>\(1!\)</math> <math>\(1\)</math> <math>\(1\)</math>
    <math>\(2!\)</math> <math>\(1 \times 2\)</math> <math>\(2\)</math>
    <math>\(3!\)</math> <math>\(1 \times 2 \times 3\)</math> <math>\(6\)</math>
    <math>\(...\)</math> <math>\(...\)</math> <math>\(...\)</math>

    Soit n un entier naturel. Sa factorielle est formellement définie par :
    <math>\(n! = \prod_{i=1}^{n} = 1 \times 2 \times 3 \times ... \times (n-1) \times n\)</math>
    Par convention :
    <math>\(0! = 1\)</math>

    Commençons en douceur


    Exercice № 1 : Créez une fonction fac(n) qui renvoi la factorielle de n. Le but étant de faire un code concis et —relativement— rapide

    Superfactorielle


    Définition


    Factorielle Expression Resultat
    <math>\(1\$\\)</math> <math>\(1\)</math> <math>\(1\)</math>
    <math>\(2\$\\)</math> <math>\(2^2\)</math> <math>\(6\)</math>
    <math>\(3\$\\)</math> <math>\(6^{6^{6^{6^{6^6}}}}\)</math> <math>\(8.02\times 10^{6050}\)</math>
    <math>\(...\)</math> <math>\(...\)</math> <math>\(...\)</math>

    On peut définir la superfactorielle de n, notée <math>\(n\$\\)</math> ($ étant un signe factoriel ! portant un S superposé) comme :

    <math>\(n\$\equiv \begin{matrix} \underbrace{ n!^{{n!}^{{\cdot}^{{\cdot}^{{\cdot}^{n!}}}}}} \\ n! \end{matrix}\)</math>

    Ainsi, on a pour <math>\(3\$\\)</math> :
    <math>\(3\$= 6^{6^{6^{6^{6^6}}}} \!= 8.02\times 10^{6050}\)</math>

    Codons enfin


    Exercice № 2 : Créez une fonction superfac(n) qui renvoi la superfactorielle de n.

    Si vous implantez la formule sans réfléchir, ça ne marchera pas : Vous ne pouvez pas utiliser de moyens "conventionnels" pour résoudre ce problème. Trouver un autre moyen qui ne nécessite pas de traiter directement de très grand nombre


    Bonne chance !

    Texte extrait des articles Wikipédia Factorielle et Analogues de la factorielle
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      17 mars 2011 à 20:13:36

      Pour la factorielle je sors quelquechose d'un peu plus original que j'ai dans mes fichiers et que j'avais récupéré je ne sais plus où. On peut guère faire plus rapide, donc ça peut être un défi.

      def factorial(n):
          try:
              n = int(n)
          except:
              raise "prob bob"
          assert n >= 0, "n doit etre superieur a 0"
      
          fact = {0: 1, 1: 1, 2: 2, 3: 6, 4: 24, 5: 120, 6: 720, 7: 5040, 8: 40320, 9: 362880,
                  10: 3628800, 11: 39916800, 12: 479001600, 13: 6227020800L, 14: 87178291200L,
                  15: 1307674368000L, 16: 20922789888000L, 17: 355687428096000L, 18: 6402373705728000L,
                  19: 121645100408832000L, 20: 2432902008176640000L, 21: 51090942171709440000L,
                  22: 1124000727777607680000L, 23: 25852016738884976640000L, 24: 620448401733239439360000L,
                  25: 15511210043330985984000000L, 26: 403291461126605635584000000L,
                  27: 10888869450418352160768000000L, 28: 304888344611713860501504000000L,
                  29: 8841761993739701954543616000000L, 30: 265252859812191058636308480000000L}
          if n <= 30:
              return fact[n]
          else:
              total = 1L
              while n > 1:
                  total *= n
                  n -= 1
              return total
      


      Pour l'originalité voilà.

      Par contre la superfactorielle j'ai jamais vu, pas le niveau maths pour le faire, par contre je vais quand même le tenter. Je vais regarder des docs en maths pour voir si je comprend un peu mieux, car c'est vieux pour moi toutes ces notations.

      Edit : D'où viennent les 6 de ton exemple, je ne comprend pas par rapport à ta formule de base.

      Ma version superfactorial mais conventionnel malheureusement

      def superfactorial(n):
          from operator import mul
          liste = []
          for i in range(n, 1, -1):
              liste.append(factorial(i)) # fonction ci-dessus
          return reduce(mul, liste)
      
      • Partager sur Facebook
      • Partager sur Twitter
        17 mars 2011 à 21:03:28


        Très moyennement convaincu par cet exercice.



        Le calcul de la factorielle est d'un classicisme ... Sans compter que c'est une fonction standard depuis Python 2.6. Donc on commence vraiment en douceur et même avec une pente très faible.


        Et puis tout d'un coup, on se retrouve au pied du mur avec ton 2ème exo, pas très cool cette façon de faire. Et les contours restent quand même assez flous puisque tu dis


        Citation : Yohan88

        Créez une fonction superfac(n) qui renvoi la superfactorielle de n.



        et on croit comprendre en te lisant que la réponse est


        Citation : Yohan88



        Ainsi, on a pour <math>\(3\$\\)</math> :
        <math>\(3\$= 6^{6^{6^{6^{6^6}}}} \!= 8.02\times 10^{6050}\)</math>



        ce qui n'est pas du tout comparable à l'exo précédent (où tu demandes de retourner la factorielle) car cette fois il s'agit d'une approximation.

        Par ailleurs, avant de poser des exercices sur un forum qui va être lu par des dizaine de personnes, tu devrais quand même vérifier ce que tu demandes et te montrer plus précis pour que tes lecteurs ne perdent pas leur temps à essayer de spéculer sur ce que tu veux leur faire montrer. Or, je ne sais pas si tu as conscience de l'ambiguïté que comporte ta notation 6 exposant 6 exposant 6 etc : t'es-tu posé la question de la priorité de l'opérateur d'exponentiation ? Ce n'est pas suffisamment usuel pour qu'on omette de fournir ce renseignement.



        Bref, je crois que ton exercice nécessite au moins une sérieuse reformulation.

        Citation : fred1599

        On peut guère faire plus rapide,



        Décidément, c'est la série : pas clair car faut-il comprendre que tu veux dire On ne peut faire guère plus rapide ou au contraire qu'on peut faire plus rapide ?



        Citation : fred1599


        Pour l'originalité voilà.



        Pour l'originalité, je reste sur ma faim, c'est classiquement ce qu'on appelle des precomputed lookup tables. Sinon, on peut faire assez facilement beaucoup plus rapide que le calcul que tu proposes si on veut calculer des factorielles un peu grandes, genre 500! voire plus



        Citation : fred1599


        Je vais regarder des docs en maths pour voir si je comprend un peu mieux, car c'est vieux pour moi toutes ces notations.



        Ces histoires de superfactorielles n'ont rien de classique et donc soit c'est trivial soit c'est très dur.


        Citation : fred1599


        Edit : D'où viennent les 6 de ton exemple, je ne comprend pas par rapport à ta formule de base.



        6 vient du fait que c'est factorielle 3 et qu'on veut calculer superfactorielle(3). mais c'est vrai que ses explications ne sont pas claires si on ne connait pas.


        Citation : fred1599


        def superfactorial(n):
            from operator import mul
            liste = []
            for i in range(n, 1, -1):
                liste.append(factorial(i)) # fonction ci-dessus
            return reduce(mul, liste)
        


        Chez moi ça renvoie 12. Et par ailleurs, je sais pas comment tu te débrouilles pour, à chaque fois, donner du code super compliqué pour faire des choses très simples !


        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          17 mars 2011 à 21:16:38

          Citation

          Chez moi ça renvoie 12. Et par ailleurs, je sais pas comment tu te débrouilles pour, à chaque fois, donner du code super compliqué pour faire des choses très simples !



          Comment ça peut te donner 12 alors que je ne donne pas n???

          Citation

          6 vient du fait que c'est factorielle 3 et qu'on veut calculer superfactorielle(3)



          ça ne l'est pas plus pour moi. Compréhensible je veux dire

          Citation

          Ces histoires de superfactorielles n'ont rien de classique et donc soit c'est trivial soit c'est très dur.



          C'est ni l'un ni l'autre en ce qui me concerne, c'est une question de point de vue. Ne me compare pas à tes étudiants, j'ai beaucoup plus d'âge qu'eux et donc plus de recul pour comprendre ce genre de choses. Par contre j'aurais jamais les automatismes et les raccourcis logiques que pourra prendre un étudiant en apprenant ça 8 heures sur 24 pendant 5 années.

          • Partager sur Facebook
          • Partager sur Twitter
            17 mars 2011 à 21:32:59

            Citation : fred1599


            Comment ça peut te donner 12 alors que je ne donne pas n???



            Ben oui mais moi j'ai pris la valeur de n que le PO a donné, à savoir 3 (c'est vrai que j'aurais pu préciser).


            Citation : fred1599


            Citation

            6 vient du fait que c'est factorielle 3 et qu'on veut calculer superfactorielle(3)



            ça ne l'est pas plus pour moi. Compréhensible je veux dire



            Bien, alors je vais essayer moi aussi d'être plus clair. Pour calculer superfactorielle(3), tu commences par calculer factorielle(3) qui vaut N=6. Ensuite, tu fais un echafaudage de N "étages" qui valent chacun N. Par étage il faut comprendre comme dans <math>\(a^b\)</math> (b est à l'"étage"), qu'on élève à la puissance de façon successive. Donc, notre superfactorielle(3) vaut 6 puissance 6 puissance 6 puissance 6 puissance 6 puissance 6 ce qui se note
            <math>\(6^{6^{6^{6^{6^6}}}}\)</math>

            et il y a 6 étages de 6. Le problème, et c'est peut-être là la source de ton incompréhension, c'est qu'en fait l'expression 6 puissance 6 puissance 6 puissance 6 puissance 6 puissance 6 peut s'évaluer de deux façons différentes et j'ai l'impression que le PO n'en a pas conscience.
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              17 mars 2011 à 21:49:06

              Citation

              Bien, alors je vais essayer moi aussi d'être plus clair. Pour calculer superfactorielle(3), tu commences par calculer factorielle(3) qui vaut N=6. Ensuite, tu fais un echafaudage de N "étages" qui valent chacun N. Par étage il faut comprendre comme dans a^b (b est à l'"étage"), qu'on élève à la puissance de façon successive. Donc, notre superfactorielle(3) vaut 6 puissance 6 puissance 6 puissance 6 puissance 6 puissance 6 ce qui se note



              Ok j'ai compris

              Citation

              Ben oui mais moi j'ai pris la valeur de n que le PO a donné, à savoir 3 (c'est vrai que j'aurais pu préciser).



              Oui ensuite j'ai compris ce que tu voulais dire, et moi je n'ai pas lu jusqu'au bout l'article de wikipedia.

              En tout cas j'ai appris quelquechose ce soir, et concrètement c'est utile pour quel genre de chose ces superfactorielles?
              • Partager sur Facebook
              • Partager sur Twitter
                17 mars 2011 à 22:27:34

                Citation : fred1599


                concrètement c'est utile pour quel genre de chose ces superfactorielles?



                Très concrètement oui, ça sert à faire du buzz sur le sdz ;)
                • Partager sur Facebook
                • Partager sur Twitter
                  18 mars 2011 à 10:05:34

                  D'abord, une factorielle récursive avec un décorateur:
                  def cache(func):
                      dico = {0:1, 1:1, 2:2}
                      def aux(n):
                          if n in dico:
                              return dico[n]
                          else:
                              foo = func(n)
                              dico[n] = foo
                              return foo
                      return aux
                  
                  @cache
                  def fac(n):
                      assert n>=0
                      return n*fac(n-1)
                  


                  Je réflechis encore un peu pour la superfactorielle :o

                  Edit: peut-être pas très rapide, mais court.
                  def superfac(n):
                      foo = fac(n)
                      return reduce(pow, [foo]*foo)
                  


                  Edit: j'up pour montrer ma nouvelle factorielle :p
                  def fac(n, cache={0:1, 1:1, 2:2, 3:6}, verbose = False):
                      if n in cache:
                          return cache[n]
                      foo = max(filter(lambda a:a<n, cache.keys()))
                      bar = cache[foo]
                      if verbose:
                          print "%d ! = %d" % (foo, bar)
                      for i in xrange(foo+1, n+1):
                          bar = bar * i
                          if verbose:
                              print "%d ! = %d" % (i, bar)
                      return bar
                  
                  • Partager sur Facebook
                  • Partager sur Twitter
                  yjltg.
                    18 mars 2011 à 17:11:08

                    Citation : fred1599

                    Pour la factorielle je sors quelquechose d'un peu plus original que j'ai dans mes fichiers et que j'avais récupéré je ne sais plus où. On peut guère faire plus rapide, donc ça peut être un défi.

                    def factorial(n):
                        try:
                            n = int(n)
                        except:
                            raise "prob bob"
                        assert n >= 0, "n doit etre superieur a 0"
                    
                        fact = {0: 1, 1: 1, 2: 2, 3: 6, 4: 24, 5: 120, 6: 720, 7: 5040, 8: 40320, 9: 362880,
                                10: 3628800, 11: 39916800, 12: 479001600, 13: 6227020800L, 14: 87178291200L,
                                15: 1307674368000L, 16: 20922789888000L, 17: 355687428096000L, 18: 6402373705728000L,
                                19: 121645100408832000L, 20: 2432902008176640000L, 21: 51090942171709440000L,
                                22: 1124000727777607680000L, 23: 25852016738884976640000L, 24: 620448401733239439360000L,
                                25: 15511210043330985984000000L, 26: 403291461126605635584000000L,
                                27: 10888869450418352160768000000L, 28: 304888344611713860501504000000L,
                                29: 8841761993739701954543616000000L, 30: 265252859812191058636308480000000L}
                        if n <= 30:
                            return fact[n]
                        else:
                            total = 1L
                            while n > 1:
                                total *= n
                                n -= 1
                            return total
                    



                    Pour l'originalité voilà.

                    Par contre la superfactorielle j'ai jamais vu, pas le niveau maths pour le faire, par contre je vais quand même le tenter. Je vais regarder des docs en maths pour voir si je comprend un peu mieux, car c'est vieux pour moi toutes ces notations.

                    Edit : D'où viennent les 6 de ton exemple, je ne comprend pas par rapport à ta formule de base.

                    Ma version superfactorial mais conventionnel malheureusement

                    def superfactorial(n):
                        from operator import mul
                        liste = []
                        for i in range(n, 1, -1):
                            liste.append(factorial(i)) # fonction ci-dessus
                        return reduce(mul, liste)
                    

                    Je ne suis pas vraiment d'accord avec "l'originalité" de la première fonction et avec le fait qu'on ne puisse pas faire plus rapide. Premièrement, les lignes 2 à 7 n'ont pas un grand intérêt : elles ne servent qu'à s'assurer que l'argument donné peut bien être casté en entier positif. Bon, pourquoi pas, mais dans le cas de l'exercice, on peut aussi se dire qu'on ne va pas donner d'argument débile genre "cc savon" à la factorielle.
                    Ensuite, la fonction elle-même se base juste sur le fait qu'au lieu d'avoir 0 comme cas de base dont la factorielle vaut 1, on monte jusqu'à 30. Algorithmiquement, on a exactement la même complexité : pour des valeurs "grandes" de n, on doit quand même faire O(n) multiplications : seules les 30 dernières ne seront pas faites. Asymptotiquement, c'est négligeable.
                    Dans le même ordre d'idée, on pourrait aller plus vite : en faisant confiance à la sélection dans un dictionnaires (pourquoi un dictionnaire et pas une liste d'ailleurs ?), il suffit de mémoriser plus de factorielles. Par exemple, si on mémorise les 1000 premières, le calcul de 1000! sera "instantané".

                    Il existe par contre des méthodes algorithmiquement bien plus rapides pour calculer n! : je ne suis pas un expert dans ce domaine, mais je crois qu'on peut par exemple partir sur une décomposition en facteurs premiers.
                    Voici un lien qui en parle un peu : ici. En haut, il y a un onglet "source code" : la première fait 86 lignes :) (à relativiser : c'est un langage plus verbeux que python, et il y a aussi pas mal de contrôles comme ceux que tu as écrits).

                    Note que pour ta méthode, déterminer son efficacité devrait aussi se baser sur une analyse précise du temps de calcul d'une multiplication et de sélection dans un dictionnaire. Malheureusement, en Python c'est assez obscur :(

                    Citation : candide

                    Citation : fred1599


                    concrètement c'est utile pour quel genre de chose ces superfactorielles?



                    Très concrètement oui, ça sert à faire du buzz sur le sdz ;)


                    Tout comme tous les exercices, y compris ceux que tu proposes.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 mars 2011 à 18:35:04

                      Citation : Maxibolt


                      Tout comme tous les exercices, y compris ceux que tu proposes.




                      Non, les quelques exercices que j'ai pu proposer sur le forum C et sur le forum Python sont autrement plus consistants et soignés que l'exercice proposé par le PO et ils ont conduit à des discussions et évolutions des solutions proposées avec investissement de connaissances algorithmique et de connaissances du langage.


                      Ce post est vide parce que l'exercice est vide.

                      La factorielle est d'une banalité sans nom et quant à la superfactorielle, j'ai envie de l'appeler la supercherielle !

                      1°) le PO ne s'est même pas posé la question de la priorité de l'opérateur d'exponentiation,
                      2°) le PO a recopié Wikipédia qui s'est planté dans le calcul de la superfactorielle,
                      3°) Un calcul facile montre qu'on ne pourra pas calculer superfactorielle(4) : son nombre de chiffres vaut environ (24**25)*log10(24) qui est lui-même un nombre de l'ordre de 35 chiffres (je vous laisse vérifer que mon petit calcul de nombre de chiffres marche pour la superfactorielle(3)).

                      Bref, surtout un exercice très improvisé.
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        18 mars 2011 à 22:25:38

                        Ouais ba on va pas se fouler pour la factorielle, on utilise gmpy :-°

                        import gmpy
                        
                        def factorial(f):
                            return gmpy.fac(f)
                        


                        Ce qui m'embête dans la superfactorielle, c'est que l'exercice est très limité dans la faisabilité, sachant qu'à partir de 4 les temps de calculs sont très très longs, voir illimités.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          19 mars 2011 à 1:36:31

                          Citation : candide

                          Citation : Maxibolt


                          Tout comme tous les exercices, y compris ceux que tu proposes.




                          Non, les quelques exercices que j'ai pu proposer sur le forum C et sur le forum Python sont autrement plus consistants et soignés que l'exercice proposé par le PO et ils ont conduit à des discussions et évolutions des solutions proposées avec investissement de connaissances algorithmique et de connaissances du langage.


                          Ce post est vide parce que l'exercice est vide.

                          La factorielle est d'une banalité sans nom et quant à la superfactorielle, j'ai envie de l'appeler la supercherielle !

                          1°) le PO ne s'est même pas posé la question de la priorité de l'opérateur d'exponentiation,
                          2°) le PO a recopié Wikipédia qui s'est planté dans le calcul de la superfactorielle,
                          3°) Un calcul facile montre qu'on ne pourra pas calculer superfactorielle(4) : son nombre de chiffres vaut environ (24**25)*log10(24) qui est lui-même un nombre de l'ordre de 35 chiffres (je vous laisse vérifer que mon petit calcul de nombre de chiffres marche pour la superfactorielle(3)).

                          Bref, surtout un exercice très improvisé.


                          1°) Si tu proposes un exercice qui te demande de calculer x + y * z, tu vas préciser la priorité de * sur + ? Non ? Hé ben là c'est pareil.
                          2°) Le PO n'est pas responsable des erreurs de wikipédia, et contrairement à toi qui ne peux pas te permettre de donner à tes élèves de fac un exercice que tu ne connais pas, il n'est pas notre professeur. Si ça te gêne qu'il ait dit "exercice : calculer la superfactorielle" au lieu de "atelier : calculons la superfactorielle", tu n'as qu'à faire un effort d'imagination pour te placer dans le cas favorable ;)
                          3°) Certes, mais il existe des façons plus agréables et respectueuses de le montrer.
                          L'exercice est peut-être improvisé, et alors ? En quoi est-ce un problème ?

                          Enfin, le fait que la superfactorielle soit incalculable sur nos machines n'exclut pas la recherche d'algorithmes adaptés - même si de fait, ça perd de son intérêt. Et contrairement à ce que tu sembles dire, il est possible d'avoir une réelle discussion algorithmique ici (par ailleurs plus intéressante que sur les sujets python - je ne visite pas le forum C- que tu proposais, où la discussion n'avait souvent rien d'algorithmique et se bornait à tenter de trouver l'astuce qui compensera le plus les défauts de performance de python, quitte à faire des calculs algorithmiquement stupides) : tu peux par exemple lire en entier le post que tu as cité.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            21 mars 2011 à 20:15:58

                            Bonjour. Je ne comprends pas le calcul de 2$ dans le tableau présent dans le premier post.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              21 mars 2011 à 22:54:20

                              Citation : Zebrure

                              Bonjour. Je ne comprends pas le calcul de 2$ dans le tableau présent dans le premier post.




                              la valeur donnée est fausse, c'est bien sûr 4 et non 6.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 mars 2011 à 4:08:31

                                Citation : Yohan88



                                Ainsi, on a pour <math>\(3\$\\)</math> :
                                <math>\(3\$= 6^{6^{6^{6^{6^6}}}} \!= 8.02\times 10^{6050}\)</math>





                                En Python, l'exponentiation a une associativité de droite à gauche (le moins naturel pour nous qui lisons de gauche à droite), cf. la doc officielle de Python, en sorte que, en Python, le nombre dont tu parlais s'écrit
                                >>> ((((6**6)**6)**6)**6)**6
                                801905114177186421268233247183671872285611243790287670326429840266965276859090994232722804099071308208566642345342525473839197857922206826881247686613054597643639074114299814658910570299338387275018144418060451356204425587436618355894265899469206493496576567060902508216857234809659411883436856907262181406555792173257484458552977375606894392453200909034506894234184478236418421979962663479216120643800922939369420248674473362609602187661563551041157505739642033306712744000213561038789775549335115383195493100990320977797431849066454349854112351669394350351724119648421429675482501486302736500144621886523347992629826999974724330860189653089828532182794794248240477416274638167362282413526807854514320952096682617889397115584667137201322422937457729214489407907405518444344340089061930346769872400573045001311080100230425970533942745847972064970363330555794582550644070075448682407064391762605241178885977478172470439245614352782718873090563810918058676016196022517960964002392982148152622058158104958518830487349863461522737045419079805176828913337987237167998461268815906214056666240308532663321889986375962262141989078341225419274892934633471601337630145021177561682163361588301146273292029772181095793682371661321565671179250200873481397054591452273317157196303425228704984654767851075710532634534940796785677558890950799401875263511992661902169258890278086716291023843497372147231848593552275703330179333395157137953888601584226588131426100524625525615311244683340215525755193173697123985498932994880224661923242660863038692352636818818091446575100518750311622740988660944192795623802082203241025300988864720691114284336174884722725160551906710564699824148484730470707902578930619626494023221095499047958286617225276486876179287677463797214957475199592111410409161111024724320181524607190511675442364059199832339531178389332438871670894278123643702026198922090184989766828514386825218944751917133528352820304932965893847129193929732262192111912880919222840357641983028044015106742642713134002917504796175868158080020653346101062376128143166925008124162624778493310053821947745097837762493928482536937358487491224793636348213860230948090092608071270697036421316013417589210684049327427491895567716870540159334726003182535675968082210912512117117036411988561552555424135025992192431252311247070107037564320408519913415791972361428643569407291782230769633403762980911951260235335468415654697223881790965348650156255150470465709634202169556242801373930782315697735699489821418879261442079714412155375949060050935369523298480393127780154774697206538820578852481294171389639340821243198793285107034663451816584313178509573270340714717653972268811979935455568659825920079977104240044757023571324964943766412817014787831726000431239296277568149403379174685366513529096824121631549336050517240784764044158530092410468898790882906726991168235676755052595083949405892993514487989629327303507999701858400364951812663411243218524311814960565403396906101566037518454582866326674740652656967374738643546913572072027015270654024870872914125274032777679768834616330289620042855458464404935752253141307743949799679373788177021131263060724194551523232678825949835712984835004658258078967038721817894573819554326478723879110512134676175579870238496958283594595247111635504199858696576767040558179086446871276735764539552108394244368401906598270272523213985019325867597404117299522896174182781347656228133260501669599573840643828131130837868317552037425215982186057658406291543623646877113038178380490129752610988187060310837787799219303381539699528293723206372177059719935531506073859021197524406579643039883039728628836461474751067864431977032358675848360773708387211420116787599737621317224241346875009176863639530452676627730931378159457365569487241901935734071637648678771531953675914311001534496147038332750307708867979198279698026903039770263012642154401276299002427289117685602673262358039948743624480371236137632544504304823818957992107773203870105130812284336956828027729321903579499814164578180299915045407689667530374597860119037107839602699845102433609954824008871263055281424268092422912559273889700924995226448267306343535545322900135542162984089368300143981387952516535890373585769044768270079232745085310534780379433679641764412570375902770137404074177820073270088260988742823688892707845709507869126201853287365775198969687579436875786108977542040269149258582213880806730504418248217557255761673402533058045211820437282641288015597565632574887136806808091337017274509640585947630061378243713693613162003445998800513844020356593674967439236032719297765887804559453426094291753338337320872533167029618779345490908355556740326053560776376448793273729369475913183616635968036303958961312252848799884953039291437629677310491001983631561495387558374254249597009726836978531354929462178177642763033790164067445673502415866746505721852575827258860644876762985518399443861444129789611155823260748613960983738802730799807870324833863673572794179621716686213597175126065963043765314408250036111188043650982973774434447477841745166609106376305766597815630308332278922332012868449774553692733717992022275716188668002733820424048869010692647287753683032329124547512690629495028349649028761229072342231520826626527689967862367744521152658974319063649327835030970627742864238920810668385925185216817124523427167003892110153204070727224612710173873389921936290442205620640819677053163599111244195701659784290628033387794423384897379043640715550904349542341988051448696644729119321923974170788984946987136512729765351867471308995876186529082842949528120694579172451660355612447630749890773691802401321948599241617171873740187460875541452669196018430458379320978910452677708740121149389289049260368909671797571587872574361576403325458450829959641703568470576948819313050657979060435743564740553565911085870118497098825973672356583186516354715506718750007325734787689281138147193205163931032061943134231140199543095420684425751639787908398865190601747112700042196582032481766506799648617686643106868998527331337192639617847034473260672095881810378587492712587519328256L
                                >>> 6**6**6**6**6**6 # mortel
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  31 mars 2011 à 9:30:54

                                  C'est la convention "universelle", il ne s'agit pas que de python (et donc, si on ne précise rien dessus, c'est bien de cette associativité qu'il s'agit).
                                  C'est comme dire que a + b * c n'est pas naturel à calculer quand on lit de gauche à droite : ça vaut toujours a + (b * c), et pas besoin de le préciser dans le sujet. Le fait que naturellement on ait envie de faire l'inverse n'a aucun sens mathématiquement.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    31 mars 2011 à 10:06:35

                                    Citation : Maxibolt

                                    C'est la convention "universelle", il ne s'agit pas que de python (et donc, si on ne précise rien dessus, c'est bien de cette associativité qu'il s'agit).
                                    C'est comme dire que a + b * c n'est pas naturel à calculer quand on lit de gauche à droite : ça vaut toujours a + (b * c), et pas besoin de le préciser dans le sujet. Le fait que naturellement on ait envie de faire l'inverse n'a aucun sens mathématiquement.



                                    Sauf que si c'était si naturel que ça, le PO se serait pas planté et wikipédia se serait pas planté non plus. Les conventions sont des conventions lorsqu'elles sont largement utilisées.


                                    Ta comparaison avec la multiplication n'est pas pertinente car il s'agit d'opérateurs beaucoup usuels que l'exponentiation, très tôt on a besoin de différencier des calculs du genre 2+3*5 vs (2+3)*5. Par contre, on a rarement à faire des puissances de puissances, des choses du genre <math>\(5^{3^2}\)</math>, on manipule pas tous les jours des nombres de Fermat par exemple, donc ta convention est en fait largement ignorée. Elle est tellement universelle que si tu écris à latex
                                    $$5^5^5$$
                                    


                                    tu te prends un :

                                    ! Double superscript.
                                    l.12 $$5^5^
                                               5$$


                                    D'autre part, le problème de l'exponentiation ici est distinct du problème a + b * c. En effet, l'exponentiation ici utilise un seul opérateur. Si par exemple a+b+c (un seul opérateur) ne pose aucune difficulté d'interprétation, c'est que l'associativité de gauche à droite ou de droite à gauche sont identiques. Or si j'écris une quantité du genre <math>\(120/12/4\)</math> énormément de gens vont tiquer alors que c'est une convention "universelle".
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      31 mars 2011 à 12:22:42

                                      Ce sera la même chose que pour l'exponentiation : les gens qui tiquent auront tort. Une règle c'est une règle, qu'elle soit connue partout ou pas. C'est comme ça, point. Même si Latex bugs.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        17 juillet 2011 à 1:58:15

                                        Bonjour.

                                        C'est la première fois que j'apprends un langage de programmation donc excusez si le code que je vous propose paraît un peu simpliste :

                                        Donc je propose :

                                        # -*-coding:Latin-1 -*
                                        import os 
                                        
                                        
                                        #On définit la fonction fac telle qu'elle renvoie la factorielle de n
                                        def fac(n):
                                        	i = 1
                                        	un= 1
                                        	 #Par convention : 0! = 1
                                        	if n == 0:
                                        		un = 1
                                        	#Sinon, n!=1*2*3*...*n
                                        	else:
                                        		while i <= n:
                                        			un *= i
                                        			i += 1
                                        	return un #un est la variable qui contient le total de factorielle n
                                        	
                                        #On demande à l'utilisateur d'entrer un nombre n pour que l'ordi renvoi factorielle de n
                                        print("Factorielle ?") 
                                        n=input()
                                        try:
                                        	n=int(n)
                                        	assert n >= 0 and (n%2 == 0 or n%2 == 1)
                                        except ValueError:
                                        	print("Erreur lors de la conversion")
                                        except AssertionError:
                                        	print("Entrez une valeur entière positive")
                                        print("Valeur :",fac(n))
                                        
                                        #On définit la fonction superfac telle qu'elle renvoie la superfactorielle de n
                                        def superfac(n):
                                        	i=1
                                        	un = fac(n) #Ici le premier facteur n'est pas 1 comme avec la factorielle mais directement fac(n)
                                        	            #D'ailleurs tous les exposants ont la même valeur : fac(n)
                                        				
                                        	while i < fac(n):#L'inégalité est stricte car le premier facteur étant déjà égal à fac(n) "utilise de la place"
                                        	                 #Il vaut mieux laisser ça comme ça, car si on met 1 au premier facteur alors 1^x sera toujours 1
                                        		un = un**fac(n)
                                        		i += 1
                                        	return un #un est la variable qui contient le total de superfactorielle n
                                        	
                                        	
                                        #On test la superfactorielle de n
                                        print("Super Factorielle ?")
                                        n=input()
                                        try:
                                        	n=int(n)
                                        	assert n >= 0 and (n%2 == 0 or n%2 == 1)
                                        except ValueError:
                                        	print("Erreur lors de la conversion")
                                        except AssertionError:
                                        	print("Entrez une valeur entière positive")
                                        print("Valeur :",superfac(n))
                                        	
                                        os.system("pause")
                                        
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          24 juillet 2011 à 23:51:45

                                          Bonsoir, voici mes solutions.
                                          Comme sur wikipédia il y a 2 définitions de la superfactorielle, j'ai essayé de faire les deux.
                                          Pour la superfac_alt par contre au dessus de 3 ça bug, je n'ai pas trouvé l'astuce.
                                          N'hésitez pas à me suggérer des améliorations ou des corrections.

                                          def fac(n=2):
                                          
                                              j, r = 1, 1
                                              for i in range(1, n+1):
                                                  r *= i*j
                                              return r
                                          
                                          def superfac(n=2):
                                          
                                              r = 1
                                              for i in range(n+1):
                                                  r *= fac(i)
                                              return r
                                          
                                          def superfac_alt(n=2): 
                                          
                                              f = fac(n)
                                              for _ in range(f-1):
                                                  f = f**fac(n)
                                              return f
                                          
                                          print(fac())
                                          print(superfac())
                                          print(superfac_alt())
                                          
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          [Exercice] La factorielle et ses analogues

                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                          • Editeur
                                          • Markdown