Créez le programme ou la fonction la plus courte qui trouve la factorielle d'un entier non négatif.
La factorielle, représentée par !
est définie comme telle
En clair, la factorielle de 0 est 1 et la factorielle de n, où n est supérieur à 0 est n fois la factorielle de un inférieur à n.
Votre code doit effectuer une entrée et une sortie en utilisant une méthode standard.
Exigences:
- N'utilise aucune bibliothèque intégrée capable de calculer la factorielle (y compris toute forme de
eval
) - Peut calculer des factorielles pour des nombres allant jusqu'à 125
- Peut calculer la factorielle pour le nombre 0 (égal à 1)
- Complète en moins d'une minute pour les numéros allant jusqu'à 125
La soumission la plus courte gagne, en cas d'égalité, la réponse avec le plus de votes à l'époque l'emporte.
code-golf
arithmetic
factorial
Kevin Brown
la source
la source
Réponses:
Golfscript - 12 caractères
Démarrer avec Golfscript - Factorial étape par étape
Voici quelque chose pour les personnes qui essaient d'apprendre golfscript. La condition préalable est une compréhension de base de golfscript et la capacité de lire la documentation de ce dernier.
Nous voulons donc essayer notre nouvel outil golfscript . Il est toujours bon de commencer par quelque chose de simple, alors nous commençons par factorielle. Voici une première tentative, basée sur un simple pseudocode impératif:
Les blancs sont très rarement utilisés dans golfscript. L'astuce la plus simple pour se débarrasser des espaces est d'utiliser différents noms de variables. Chaque jeton peut être utilisé comme une variable (voir la page de syntaxe ). Jetons utiles à utiliser en tant que variables sont des caractères spéciaux comme
|
,&
,?
- en général rien non utilisé ailleurs dans le code. Ceux-ci sont toujours analysés comme des jetons à caractère unique. En revanche, des variables commen
nécessiteront un espace pour insérer un nombre dans la pile après. Les nombres sont essentiellement des variables pré-initialisées.Comme toujours, il y aura des déclarations que nous pourrons changer, sans affecter le résultat final. En golfscript, tout évalue à vrai sauf
0
,[]
,""
et{}
(voir ce ). Ici, nous pouvons changer simplement la condition de sortie de la boucle{n}
(on boucle une fois supplémentaire et on termine quand n = 0).Comme pour le golf, peu importe la langue, il est utile de connaître les fonctions disponibles. Heureusement, la liste est très courte pour golfscript. Nous pouvons changer
1-
pour(
sauver un autre personnage. Actuellement, le code ressemble à ceci: (nous pourrions utiliser la1
place d’|
ici si nous le voulions, ce qui laisserait tomber l’initialisation).Il est important de bien utiliser la pile pour obtenir les solutions les plus courtes (pratique, pratique, pratique). En règle générale, si les valeurs ne sont utilisées que dans un petit segment de code, il peut ne pas être nécessaire de les stocker dans des variables. En supprimant la variable de produit en cours et en utilisant simplement la pile, nous pouvons économiser beaucoup de caractères.
Voici quelque chose d'autre à penser. Nous retirons la variable
n
de la pile à la fin du corps de la boucle, mais nous la repoussons immédiatement après. En fait, avant que la boucle ne commence, nous la retirons également de la pile. Nous devrions plutôt le laisser sur la pile et garder la condition de boucle vide.Peut-être pouvons-nous même éliminer complètement la variable. Pour ce faire, nous devrons garder la variable sur la pile à tout moment. Cela signifie que nous avons besoin de deux copies de la variable sur la pile à la fin du contrôle de condition pour ne pas le perdre après le contrôle. Ce qui signifie que nous aurons un redondant
0
sur la pile à la fin de la boucle, mais cela est facile à corriger.Cela nous conduit à notre
while
solution de boucle optimale !Maintenant, nous voulons toujours rendre cela plus court. La cible évidente devrait être le mot
while
. En regardant la documentation, il y a deux alternatives viables: déplier et faire . Lorsque vous avez le choix entre différents itinéraires, essayez de peser les avantages des deux. Unfold est "une boucle de while", donc, en tant qu'évaluation, nous allons réduire le caractère à 5while
par 4/
. En ce qui concernedo
, nous couponswhile
par 3 caractères et arrivons à fusionner les deux blocs, ce qui pourrait sauver un ou deux autres personnages.Il y a en fait un gros inconvénient à utiliser une
do
boucle. Puisque la vérification de la condition est effectuée après que le corps ait été exécuté une fois, la valeur de0
sera fausse, nous aurons peut-être besoin d'une instruction if. Je vais vous dire maintenant que le déroulement est plus court (quelques solutionsdo
sont fournies à la fin). Allez-y et essayez, le code que nous avons déjà nécessite des modifications minimes.Génial! Notre solution est maintenant très courte et nous avons terminé ici, non? Nan. Ceci est 17 caractères, et J a 12 caractères. Ne jamais admettre la défaite!
Maintenant, vous pensez avec ... la récursivité
Utiliser la récursivité signifie que nous devons utiliser une structure de branchement. Malheureusement, mais comme factoriel peut être exprimé de manière si succincte et récurrente, cela semble être une alternative viable à l'itération.
Eh bien, c'était facile - si nous avions essayé la récursivité plus tôt, nous n'aurions peut-être même pas envisagé d'utiliser une
while
boucle! Pourtant, nous sommes seulement à 16 caractères.Tableaux
Les tableaux sont généralement créées de deux manières - en utilisant les
[
et]
caractères, ou avec la,
fonction. S'il est exécuté avec un entier en haut de la pile,,
retourne un tableau de cette longueur avec arr [i] = i.Pour itérer sur des tableaux, nous avons trois options:
{block}/
: pousser, bloquer, pousser, bloquer, ...{block}%
: [pousser, bloquer, pousser, bloquer, ...] (cela a quelques nuances, par exemple les valeurs intermédiaires sont retirées de la pile avant chaque poussée){block}*
: pousser, pousser, bloquer, pousser, bloquer, ...La documentation de golfscript contient un exemple d'utilisation
{+}*
de la somme du contenu d'un tableau. Cela suggère que nous pouvons utiliser{*}*
pour obtenir le produit d'un tableau.Malheureusement, ce n'est pas si simple. Tous les éléments sont désactivés par un (
[0 1 2]
au lieu de[1 2 3]
). Nous pouvons utiliser{)}%
pour rectifier ce problème.Eh bien pas tout à fait. Cela ne gère pas le zéro correctement. Nous pouvons calculer (n + 1)! / (N + 1) pour remédier à cela, bien que cela coûte beaucoup trop cher.
Nous pouvons également essayer de traiter n = 0 dans le même compartiment que n = 1. C’est vraiment très court, essayez de travailler le plus rapidement possible.
Si nous voulons avoir l'incrément et la multiplication dans le même bloc, nous devrions itérer sur chaque élément du tableau. Puisque nous ne construisons pas de tableau, cela signifie que nous devrions utiliser
{)*}/
, ce qui nous amène à la plus courte implémentation de factorial de golfscript! À 12 caractères de long, c'est à égalité avec J!Solutions bonus
Commençant par une
if
solution simple pour unedo
boucle:Nous pouvons en extraire un couple supplémentaire. Un peu compliqué, alors vous devrez vous convaincre que ceux-ci fonctionnent. Assurez-vous de comprendre tout cela.
Une meilleure alternative consiste à calculer (n + 1)! / (N + 1), ce qui élimine le besoin d'une
if
structure.Mais la
do
solution la plus courte ici prend quelques caractères pour mapper 0 à 1, et tout le reste à elle-même - nous n’avons donc besoin d’aucune branche. Ce type d’optimisation est extrêmement facile à manquer.Pour ceux qui sont intéressés, quelques solutions alternatives récursives avec la même longueur que ci-dessus sont fournies ici:
* remarque: je n'ai pas encore testé la plupart des éléments de code de ce message, alors n'hésitez pas à nous informer en cas d'erreur.
la source
Haskell, 17 ans
la source
[1..0] ==> []
etproduct [] ==> 1
f 0=1;f n=n*f$n-1
comporte également 17 caractères.product
et, disons,(*)
ou(-)
"peuvent calculer la factorielle", et ils sont tous définis par le prélude. Pourquoi l'un serait-il cool et pas l'autre?Python - 27
Tout simplement:
la source
0**x
.math.factorial
? Ce n'est pas intégré, n'est-ce pas?0**x
?APL (4)
Fonctionne comme une fonction anonyme:
Si vous voulez lui donner un nom, 6 caractères:
la source
⍳
crée un vecteur d'index, c'est⍳5
-à- dire1 2 3 4 5
.×
est (évidemment) multiplier,/
est réduire et∘
est la composition de la fonction. Donc,×/∘⍳
est une fonction qui prend un argumentx
et donne le produit des nombres[1..x]
.J (12)
Une définition standard en J:
Moins de 1sec pour 125!
Par exemple:
la source
([:*/1+i.)
pour 10 points, voire 8, les parenthèses ne sont nécessaires que pour appeler la fonction, pas pour la définition.f 125x
que fait lex
? Est-ce un type spécial de numéro?Golfscript - 13 caractères (SYM)
définit la fonction
!
version alternative 13 caractères
la version complète du programme est de 10 caractères
Les tests prennent moins de 1/10 de seconde:
contribution:
sortie
contribution
sortie
la source
Perl 6: 13 caractères
[*]
est identique à Haskellproduct
et1..$_
compte de 1 à$_
l'argument.la source
[*]
(message d'erreur "Deux termes d'affilée").Matlab, 15 ans
Cas de test
la source
Python, 28 octets
(basé sur la solution d'Alexandru)
la source
MATL , 2 octets
A expliqué:
Essayez-le en ligne!
la source
Ruby - 21 caractères
Tester
la source
Java, 85 caractères
la source
import java.math.*;
(donc, +19 octets).PostScript, 26 caractères
Exemple:
La fonction elle-même prend seulement 21 caractères. le reste consiste à le lier à une variable. Pour sauvegarder un octet, on peut aussi le lier à un chiffre, comme ceci:
la source
1.#INF
. (J'ai utilisé GNU Ghostscript 9.0.7 stock compilé pour Windows x64.)JavaScript, 25
CoffeeScript, 19
Renvoie
true
dans le cas de n = 0, mais JavaScript va quand même taper que 1.la source
return
déclaration dans la fonction JavaScript?return
! Mais pourquoi pas?function f(n)n?n*f(--n):1
f=n=>!n||n*f(n-1)
Prenez ça, CoffeeScript!Ruby -
3029 caractèresTester
la source
end
directement après:*
sans une nouvelle ligne ou un point-virgule.(1..10).inject :*
# => 3628800f(0)
?f=->n{(1..n).inject 1,:*}
. Appelez ça avecf[n]
.F #: 26 caractères
Il n'y a pas de fonction de produit intégrée dans F #, mais vous pouvez en créer une avec un pli
la source
C #, 20 ou 39 caractères selon votre point de vue
En tant que méthode d'instance traditionnelle (39 caractères; testé ici ):
En tant qu'expression lambda (20 caractères, mais voir disclaimer; testé ici ):
Nous devons utiliser
double
parce que 125! == 1,88 * 10 209 , ce qui est beaucoup plus élevé queulong.MaxValue
.Clause de non responsabilité concernant le nombre de caractères de la version lambda:
Si vous récurez dans un lambda C #, vous devez évidemment stocker le lambda dans une variable nommée pour qu'il puisse s'appeler lui-même. Mais contrairement à (par exemple) JavaScript, un lambda à auto-référencement doit avoir été déclaré et initialisé sur une ligne précédente. Vous ne pouvez pas appeler la fonction dans la même instruction dans laquelle vous déclarez et / ou initialisez la variable.
En d'autres termes, cela ne fonctionne pas :
Mais cela fait :
Il n'y a aucune bonne raison pour cette restriction, car elle
f
ne peut jamais être annulée au moment de son exécution. La nécessité de laFunc<int,double> f=null;
ligne est un caprice de C #. Le lecteur peut décider s'il est juste de l'ignorer dans le nombre de caractères.CoffeeScript,
21 à19 caractères réelsTesté ici: http://jsfiddle.net/0xjdm971/
la source
Brachylog ,
7 à6 octetsEn faisant une gamme et en la multipliant
-1 octets de réservoirs à ovs ayant l'idée d'utiliser la fonction max ()
Explication
Essayez-le en ligne!
Brachylog ,
10 à9 octetsrécursion
Explication
Essayez-le en ligne!
la source
;
au lieu de,
permet uniquement une entrée numérique régulière. -1byte quand mêmeC (39 caractères)
la source
double f(n){return!n?1:n*f(n-1);}
- 33 caractères.f(125)
déborderaD: 45 caractères
Plus lisiblement:
Un refroidisseur (bien qu'une version plus longue) est celui modélisé qui fait tout à la compilation ( 64 caractères ):
Plus lisiblement:
Les modèles éponymes sont assez verbeux, vous ne pouvez donc pas vraiment les utiliser dans le code de golf. Le nombre de personnages de D est déjà assez verbeux pour être assez médiocre pour le code de golf (bien que cela réduise réellement la taille globale du programme pour les programmes plus volumineux). C’est pourtant mon langage préféré, alors je pense que je pourrais aussi bien essayer de voir comment je peux le faire en code-golf, même si les goûts de GolfScript ne manqueront pas de l’écraser.
la source
PowerShell - 36
Naïve:
Tester:
la source
Scala, 39 caractères
La plupart des caractères garantissent que
BigInt
s est utilisé, de sorte que les valeurs maximales de 125 sont remplies.la source
(x:Int)=>(BigInt(1)to x).product
def f(x:Int)=(BigInt(1)to x).product
def f(x:BigInt)=(x.to(1,-1)).product
def f(x:BigInt)=(-x to-1).product.abs
Javascript, ES6 17
ES6:
la source
PowerShell, 42 octets
(sauvegardé 2 caractères en utilisant le filtre au lieu de la fonction )
Sortie:
la source
filter f($x){if($x){$x*(f($x-1))}else{1}}
. Et il peut être réduit davantage à 36 caractères s'il est appelé via pipeline puisqu'il s'agit d'un filtre (par exemple125|f
):filter f{if($_){$_*($_-1|f)}else{1}}
Raquette (schéma)
403529 octetsCalcule 0! être 1, et calcule 125! dans 0 secondes selon le minuteur. Approche récursive régulière
Nouvelle version à battre common lisp: multiplie tous les éléments d'une liste (identique à cette solution Haskell)
Version plus récente pour battre l’autre solution de schémas et calculer l’autre solution de raquette en utilisant foldl au lieu d’appliquer et en utilisant range au lieu de buildlist
la source
Croissant Mornington ,
18271698 caractèresJ'avais envie d'apprendre une nouvelle langue aujourd'hui, et c'est ce sur quoi j'ai atterri ... (Pourquoi je me fais ça moi-même?) Cet article ne gagnera pas de prix, mais il bat tous les 0 autres réponses jusqu'ici en utilisant le Même langue!
Essayez-le en ligne!
Tous ceux qui ont parcouru Londres comprendront cela instantanément, bien sûr, alors je ne suis pas obligé de donner une explication complète.
Au début, la majeure partie du travail consiste à traiter le cas 0. Après avoir initialisé le produit à 1, je peux l'utiliser pour calculer max (entrée, 1) afin d'obtenir la nouvelle entrée, en tirant parti du fait que 0! = 1! Ensuite, la boucle principale peut commencer.
(EDIT: Tout un tas de voyages ont été sauvés en enlevant le 1 de "Heathrow Terminals 1, 2, 3" au lieu de le générer en divisant 7 (Sisters) par lui-même. J'utilise également une méthode moins coûteuse pour générer le -1 en la prochaine étape.)
La décrémentation coûte cher à Mornington Crescent (bien que moins chère que le Tube lui-même). Pour rendre les choses plus efficaces, je génère un -1 en prenant le NON d'un 0 analysé et le stocke dans Hammersmith pendant une grande partie de la boucle.
J'y ai consacré beaucoup de travail, mais puisqu'il s'agit de ma première tentative de golf à Mornington Crescent (en fait, ma première tentative dans n'importe quelle langue), je m'attends à manquer quelques optimisations ici et là. Si vous souhaitez programmer vous-même dans ce langage (et pourquoi ne le seriez-vous pas?), Esoteric IDE - avec son mode de débogage et sa fenêtre de visualisation - est un must!
la source
Befunge - 2x20 = 40 caractères
Il s’agit d’une fonction en ce sens qu’il s’agit d’un bloc de code autonome n’utilisant pas le wraparound. Vous devez placer l'argument au sommet de la pile, puis entrer en partant de la gauche, en haut à gauche. La fonction sortira de la droite en bas à droite avec le résultat en haut de la pile.
Par exemple pour calculer la factorielle de 125
Test 0
la source
&:!#@_>:# 1# -# :# _$>\# :#* _$.@
(où & devrait être remplacé par l'entrée). Il est de 32 caractères / octetsJ - 6 personnages
Est-ce que ça compte? Je sais que cela ressemble beaucoup à l'exemple précédent, mais il est un peu plus court :)
Je suis un débutant avec J, mais c'est très amusant jusqu'à présent!
la source
En C (23 Caractères)
Cela abuse de la "fonctionnalité" de GCC qui fait que la dernière affectation compte comme un retour si aucun retour n'est spécifié.
En bon C, 28 caractères
la source
0 == ({printf("Hello, world!"); 0;});
Kona (
116)K fonctionne de droite à gauche (pour la plupart), nous énumérons
x
(faisons une liste / un tableau de nombres de0
àx-1
), nous lui ajoutons1
(des plages de liste0
àx
), puis multiplions tous les nombres ensemble. Si ce n’était pas une obligation de calcul125!
, je pourrais économiser un octet de plus en éliminant à.
côté du1
. En tout état de cause, 125! est calculé en quelques millisecondes:la source
*/1.+!
: 6 octets.