Le défi:
Écrivez un programme ou une fonction qui entre un nombre positif et renvoie sa factorielle .
Remarque: Il s'agit d'une question de contrôle de code . Veuillez ne pas prendre la question et / ou les réponses au sérieux. Plus d'informations ici . Chaque question de code-trolling est également une question de concours de popularité , donc la réponse la plus votée gagne.
popularity-contest
code-trolling
alephalpha
la source
la source
Réponses:
Il s'agit d'un problème de calcul numérique très simple que nous pouvons résoudre avec l'approximation de Stirling :
Comme vous pouvez le voir, cette formule comporte une racine carrée, dont nous aurons également besoin d'un moyen d'approximation. Nous choisirons la soi-disant "méthode babylonienne" pour cela car c'est sans doute la plus simple:
Notez que le calcul de la racine carrée de cette façon est un bon exemple de récursivité.
Tout rassembler dans un programme Python nous donne la solution suivante à votre problème:
Avec une simple modification, le programme ci-dessus peut produire une table soignée de factorielles:
Cette méthode doit être suffisamment précise pour la plupart des applications.
la source
C #
Désolé, mais je déteste la fonction récursive.
la source
Java
la source
Python
Bien sûr, la meilleure façon de résoudre tout problème est d'utiliser des expressions régulières:
la source
Haskell
Le code court est un code efficace, alors essayez ceci.
Pourquoi c'est à la traîne:
Je ris de tout codeur qui a écrit ça ... L'inefficacité est magnifique. Également probablement incompréhensible pour tout programmeur Haskell qui ne peut pas réellement écrire une fonction factorielle.
Edit: J'ai posté cela il y a un moment maintenant, mais je pensais clarifier pour les futures personnes et les personnes qui ne peuvent pas lire Haskell.
Le code ici prend la liste des nombres 1 à n, crée la liste de toutes les permutations de cette liste et renvoie la longueur de cette liste. Sur ma machine, cela prend environ 20 minutes pour 13!. Et puis cela devrait prendre quatre heures pour 14! puis deux jours et demi pour 15!. Sauf qu'à un moment donné, vous manquez de mémoire.
Edit 2: En fait, vous ne manquerez probablement pas de mémoire car il s'agit de Haskell (voir le commentaire ci-dessous). Vous pourriez être en mesure de le forcer à évaluer la liste et à la garder en mémoire d'une manière ou d'une autre, mais je ne connais pas suffisamment l'optimisation (et l'optimisation) de Haskell pour savoir exactement comment faire cela.
la source
[1..n]
. - Une permutation particulière de[1..n]
, consignée à un thunk pour le reste des permutations (polynôme enn
). - Un accumulateur pour lalength
fonction.C #
Comme il s'agit d'un problème mathématique, il est logique d'utiliser une application spécialement conçue pour résoudre les problèmes mathématiques pour effectuer ce calcul ...
Étape 1:
Installez MATLAB. Un essai fonctionnera, je pense, mais ce problème super compliqué est probablement suffisamment important pour mériter l'achat de la version complète de l'application.
Étape 2:
Incluez le composant MATLAB COM dans votre application.
Étape 3:
la source
C #
Les factorielles sont une opération mathématique de niveau supérieur qui peut être difficile à digérer d'un seul coup. La meilleure solution dans des problèmes de programmation comme celui-ci est de décomposer une tâche importante en tâches plus petites.
Maintenant, n! est défini comme 1 * 2 * ... * n, donc, essentiellement une multiplication répétée, et la multiplication n'est rien d'autre que l'addition répétée. Donc, avec cela à l'esprit, ce qui suit résout ce problème:
la source
Trolls:
z = n - 1 + 1
) sous-optimal le plus évident ( ) est en fait auto-documenté si vous savez ce qui se passe.p[]
utilisant un calcul récursif des coefficients de série!(C'est l' approximation de Lanczos de la fonction gamma )
la source
- 1 + 1
ici? Mon compilateur l'optimise (ce n'est pas un nombre à virgule flottante où l'optimisation de code comme celui-ci pourrait être dangereux), il semble donc inutile.double z = n - 1
fait partie de l'approximation de la fonction gamma. Le+ 1
est de la relation quegamma(n + 1) = n!
pour l'entier n.Nous savons tous de l'université que la façon la plus efficace de calculer une multiplication est d'utiliser des logarithmes. Après tout, pourquoi les gens utiliseraient-ils des tables de logarithmes pendant des centaines d'années?
Donc, à partir de l'identité,
a*b=e^(log(a)+log(b))
nous formons le code Python suivant:Il crée une liste de nombres de
1
àx
, (le+1
est nécessaire parce que Python aspire) calcule le logarithme de chacun, additionne les nombres, élève le e à la puissance de la somme et arrondit finalement la valeur à l'entier le plus proche (parce que Python aspire) . Python a une fonction intégrée pour calculer les factorielles, mais il ne fonctionne que pour les entiers, donc il ne peut pas produire de grands nombres (parce que Python craint). C'est pourquoi la fonction ci-dessus est nécessaire.Btw, un conseil général pour les étudiants est que si quelque chose ne fonctionne pas comme prévu, c'est probablement parce que la langue est nulle.
la source
Malheureusement, Javascript n'a pas de méthode intégrée pour calculer la factorielle. Mais, vous pouvez utiliser sa signification en combinatoire pour déterminer la valeur néanmoins:
La factorielle d'un nombre n est le nombre de permutations d'une liste de cette taille.
Ainsi, nous pouvons générer chaque liste de nombres à n chiffres, vérifier s'il s'agit d'une permutation, et si oui, incrémenter un compteur:
Trolls:
O(n)
, nonO(n!)
, maisO(n^n)
. Cela seul aurait suffi pour se qualifier ici.number.toString(base)
, mais cela ne fonctionne pas pour les bases supérieures à 36. Oui, je sais 36! c'est beaucoup , mais quand même ...Math.pow
? Non? Tant pis.++
dehors de for-loops le rend encore plus mystérieux. Aussi,==
c'est mauvais.$i
.new Array
,document.write
(avec des amis) etalert
(au lieu d'une invite ou d'une étiquette d'entrée) forment un trifecta complet de péchés de choix de fonction. Pourquoi l'entrée est-elle ajoutée dynamiquement après tout?=
rendent encore plus difficiles à lire.la source
Ruby et WolframAlpha
Cette solution utilise l'API REST WolframAlpha pour calculer la factorielle, avec RestClient pour récupérer la solution et Nokogiri pour l'analyser. Il ne réinvente aucune roue et utilise des technologies bien testées et populaires pour obtenir le résultat de la manière la plus moderne possible.
la source
Javascript
Javascript est un langage de programmation fonctionnel, cela signifie que vous devez utiliser des fonctions pour tout car c'est plus rapide.
la source
r = -~(function(){})
résoudra sûrement cela.Utilisation de Bogo-Sort en Java
Cela fonctionne en fait, très lentement, et ce n'est pas exact pour des nombres plus élevés.
la source
PERL
Le factoriel peut être un problème difficile. Une technique de type carte / réduction - tout comme Google utilise - peut diviser les calculs en interrompant un tas de processus et en collectant les résultats. Cela fera bon usage de tous ces cœurs ou processeurs dans votre système par une froide nuit d'hiver.
Enregistrez sous f.perl et chmod 755 pour vous assurer que vous pouvez l'exécuter. Vous avez installé la liste des déchets pathologiquement éclectiques, n'est-ce pas?
Trolls:
la source
ARGV[0]
est en fait le premier argument et non le script!$ARGV[0]
parce que la plupart des langues que je connais un peu l'ontPython
Juste un algorithme O (n! * N ^ 2) pour trouver la factorielle. Cas de base traité. Pas de débordements.
la source
Eh bien, il existe une solution simple dans Golfscript. Vous pouvez utiliser un interpréteur Golfscript et exécuter ce code:
Facile hein :) Bonne chance!
la source
!
Mathematica
Cela ne semble pas fonctionner pour des nombres supérieurs à 11, et le factoriel [11] a gelé mon ordinateur.
la source
Rubis
Le one-liner le plus lent que je puisse imaginer. Il faut 2 minutes sur un processeur i7 pour calculer
6!
.la source
L'approche correcte pour ces problèmes mathématiques difficiles est une DSL. Je vais donc modéliser cela en termes de langage simple
Pour bien écrire notre DSL, il est utile de le voir comme une monade gratuite générée par le foncteur algébrique
Nous pourrions écrire ceci dans Haskell comme
Je laisse au lecteur le soin de tirer la mise en œuvre triviale de
Maintenant, nous pouvons décrire une opération pour modéliser une factorielle dans cette DSL
Maintenant que nous avons modélisé cela, nous avons juste besoin de fournir une fonction d'interprétation réelle pour notre monade libre.
Et je laisse le reste de la dénotation au lecteur.
Pour améliorer la lisibilité, il est parfois utile de présenter un AST concret du formulaire
puis à droite une réflexion triviale
puis il est simple d'évaluer récursivement l'AST.
la source
Python
Vous trouverez ci-dessous une version Python de la solution, qui n'est pas limitée à la limite 32 bits (ou 64 bits sur un système très récent) pour les nombres entiers en Python. Pour contourner cette limitation, nous allons utiliser une chaîne comme entrée et sortie pour lafactorial
routine et diviser en interne la chaîne en ses chiffres pour pouvoir effectuer la multiplication.Voici donc le code: la
getDigits
fonction divise une chaîne représentant un nombre en ses chiffres, donc "1234" devient[ 4, 3, 2, 1 ]
(l'ordre inverse rend simplement les fonctionsincrease
etmultiply
plus simples). Laincrease
fonction prend une telle liste et l'augmente d'une unité. Comme son nom l'indique, lamultiply
fonction se multiplie, par exemplemultiply([2, 1], [3])
retourne[ 6, 3 ]
parce que 12 fois 3 est 36. Cela fonctionne de la même manière que vous multiplieriez quelque chose avec un stylo et du papier.Enfin, la
factorial
fonction utilise ces fonctions d'aide pour calculer la factorielle réelle, par exemplefactorial("9")
donne"362880"
comme sortie.Remarques
En python, un entier n'a pas de limite, donc si vous souhaitez le faire manuellement, vous pouvez simplement le faire
Il y a aussi le très pratique
math.factorial(n)
fonction .Cette solution est évidemment beaucoup plus complexe qu'elle ne devrait l'être, mais elle fonctionne et en fait, elle illustre comment vous pouvez calculer la factorielle au cas où vous seriez limité à 32 ou 64 bits. Donc, même si personne ne croira que c'est la solution que vous avez trouvée pour ce problème simple (au moins en Python), vous pouvez réellement apprendre quelque chose.
la source
Python
La solution la plus raisonnable est clairement de vérifier tous les nombres jusqu'à ce que vous trouviez celui qui est la factorielle du nombre donné.
la source
Une solution récursive la plus élégante en C
Chacun sait que les solutions les plus élégantes aux factorielles sont récursives.
Factorielle:
Mais la multiplication peut également être définie récursivement comme des ajouts successifs.
Multiplication:
Et il en va de même pour les incrémentations successives.
Une addition:
Dans
C
, nous pouvons utiliser++x
et--x
gérer les primitives(x + 1)
et(x - 1)
respectivement, nous avons donc tout défini.Essayons-le:
Parfait, bien que 8! a pris beaucoup de temps pour une raison quelconque. Eh bien, les solutions les plus élégantes ne sont pas toujours les plus rapides. Nous allons continuer:
Hmm, je vous préviendrai quand il reviendra ...
la source
Python
Comme l'indique la réponse de @ Matt_Sieker, les factorielles peuvent être divisées en plus - pourquoi, la répartition des tâches est l'essence de la programmation. Mais, nous pouvons décomposer cela en addition par 1!
Je pense que ce code garantit une erreur SO, car
Récursion - réchauffe
Chaque couche génère des appels à se multiplier
qui génère des appels vers des numéros supplémentaires
qui génère des appels à addby1!
Trop de fonctions, non?
la source
Accédez simplement à Google et saisissez votre factorielle:
http://lmgtfy.com/?q=5!
la source
TI-Basic 84
Ça marche vraiment :)
la source
Javascript
De toute évidence, le travail d'un programmeur est de faire le moins de travail possible et d'utiliser autant de bibliothèques que possible. Nous voulons donc importer jQuery et math.js . Maintenant, la tâche est simple comme ceci:
la source
Python
Avec juste une légère modification de l'implémentation factorielle récursive standard, elle devient intolérablement lente pour n> 10.
la source
Frapper
la source
Essayons de le faire par la méthode Monte Carlo . Nous savons tous que la probabilité que deux n- permutations aléatoires soient égales est exactement de 1 / n! . Par conséquent, nous pouvons simplement vérifier combien de tests sont nécessaires (appelons ce numéro b ) jusqu'à ce que nous obtenions c hits. Alors, n! ~ b / c .
Sage, devrait aussi fonctionner en Python
la source
frapper
Les factorielles sont facilement déterminées avec des outils de ligne de commande bien connus de bash.
Comme @Aaron Davies l'a mentionné dans les commentaires, cela semble beaucoup plus ordonné et nous voulons tous un programme agréable et bien rangé, n'est-ce pas?
la source
paste
commande très sous-estimée :seq 1 $n | paste -sd\* | bc
paste
ressemble à un mot anglais ordinaire et facile à retenir. Voulez-vous vraiment ça? ; o)