Trouvez le Factorial!


74

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

n!:={1n=0n(n1)!n>0

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.


10
Combien de réponses données peuvent calculer jusqu'à 125! sans débordement entier? N'était-ce pas l'une des exigences? Les résultats sous forme d'approximations exponentielles sont-ils acceptables (c'est-à-dire 125! = 1,88267718 × 10 ^ 209)?
Ami

6
@SHiNKiROU, même golfscript peut en gérer 125! moins de 1 / 10ème de seconde et c'est un langage interprété interprété!
Gnibbler

5
@ugoren la solution à deux caractères à l'autre question utilise une fonction factorielle intégrée. Ce n'est pas permis dans cette version du challenge.
Michael Stern

4
Compléter en moins d’une minute semble une exigence très dépendante du matériel. Se termine en moins d’une minute sur quel matériel?
sergiol

4
@sergiol Incroyablement, cela n'a pas été un problème au cours des 2 dernières années, je suppose que la plupart des langues peuvent le faire en moins d'une minute.
Kevin Brown

Réponses:


66

Golfscript - 12 caractères

{,1\{)*}/}:f

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:

# pseudocode: f(n){c=1;while(n>1){c*=n;n--};return c}
{:n;1:c;{n 1>}{n c*:c;n 1-:n;}while c}:f

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 comme nné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 la 1place d’ |ici si nous le voulions, ce qui laisserait tomber l’initialisation).

{:n;1:|;{n}{n|*:|;n(:n;}while|}:f

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.

{:n;1{n}{n*n(:n;}while}:f

Voici quelque chose d'autre à penser. Nous retirons la variable nde 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.

{1\:n{}{n*n(:n}while}:f

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 0sur la pile à la fin de la boucle, mais cela est facile à corriger.

Cela nous conduit à notre whilesolution de boucle optimale !

{1\{.}{.@*\(}while;}:f

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 à 5 whilepar 4 /. En ce qui concerne do, nous coupons whilepar 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 doboucle. Puisque la vérification de la condition est effectuée après que le corps ait été exécuté une fois, la valeur de 0sera fausse, nous aurons peut-être besoin d'une instruction if. Je vais vous dire maintenant que le déroulement est plus court (quelques solutions dosont fournies à la fin). Allez-y et essayez, le code que nous avons déjà nécessite des modifications minimes.

{1\{}{.@*\(}/;}:f

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.

# pseudocode: f(n){return n==0?n*f(n-1):1}
{:n{n.(f*}1if}:f # taking advantage of the tokeniser

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 whileboucle! 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:

  1. {block}/: pousser, bloquer, pousser, bloquer, ...
  2. {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)
  3. {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.

{,{*}*}:f

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.

{,{)}%{*}*}:f

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.

{).,{)}%{*}*\/}:f

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.

Pas si bien est le tri, à 7 caractères: [1\]$1=. Notez que cette technique de tri a des objectifs utiles, tels qu'imposer des limites à un nombre (par exemple `[0 \ 100] $ 1 =).
Voici le gagnant, avec seulement 3 caractères:.! +

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!

{,1\{)*}/}:f


Solutions bonus

Commençant par une ifsolution simple pour une doboucle:

{.{1\{.@*\(.}do;}{)}if}:f

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.

{1\.!!{{.@*\(.}do}*+}:f
{.!{1\{.@*\(.}do}or+}:f
{.{1\{.@*\(.}do}1if+}:f

Une meilleure alternative consiste à calculer (n + 1)! / (N + 1), ce qui élimine le besoin d'une ifstructure.

{).1\{.@*\(.}do;\/}:f

Mais la dosolution 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.

{.!+1\{.@*\(.}do;}:f

Pour ceux qui sont intéressés, quelques solutions alternatives récursives avec la même longueur que ci-dessus sont fournies ici:

{.!{.)f*0}or+}:f
{.{.)f*0}1if+}:f
{.{.(f*}{)}if}:f

* 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.


8
Intéressant, cela semble être un bogue dans le démarquage du spoiler lorsque vous utilisez du code dans un spoiler ... Quelqu'un veut-il le mentionner sur Meta?
Ivo Flipse

5
Je trouve intéressant comment golfscript - une langue de golf - permet des noms de variable multi-lettres et vous "punit" pour avoir utilisé une lettre avec les espaces nécessaires
Cyoce

44

Haskell, 17 ans

f n=product[1..n]

2
Je ne connais pas Haskell ... Mais cela calculera-t-il une factorielle pour 0
The King

11
@ Le roi: oui ce sera. [1..0] ==> []etproduct [] ==> 1
JB

5
Je dirais que cela utilise la "bibliothèque intégrée" que le problème interdit. Cependant, l’autre méthode f 0=1;f n=n*f$n-1comporte également 17 caractères.
eternalmatt

5
@eternalmatt: cette partie des restrictions est sous-spécifiée pour moi. Les deux productet, 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?
JB

2
@YoYoYonnY: Je compte également 17 caractères, pour une lisibilité moins (subjective). IMHO c'est bien dans les commentaires.
JB

41

Python - 27

Tout simplement:

f=lambda x:0**x or x*f(x-1)

22
Bonne astuce: 0**x.
Alexandru

Qu'en est- il math.factorial? Ce n'est pas intégré, n'est-ce pas?

1
@JackBates est considéré comme intégré, car vous n'avez pas écrit le code pour calculer la factorielle.
FlipTack

1
Quelqu'un peut-il me dire quel est le truc derrière 0**x?
Pavitra

1
@Pavitra: 0 0 = 1, et c'est la première chose qui est évaluée pour qu'elle soit renvoyée. Pour tout autre n, 0 n = 0, ainsi le premier opérande de ou est falsey, de sorte que le deuxième opérande soit évalué.
Mega Man

29

APL (4)

×/∘⍳

Fonctionne comme une fonction anonyme:

    ×/∘⍳ 5
120

Si vous voulez lui donner un nom, 6 caractères:

f←×/∘⍳

Je ne parle pas APL, que se passe-t-il ici?
Michael Stern

@MichaelStern: crée un vecteur d'index, c'est ⍳5-à- dire 1 2 3 4 5. ×est (évidemment) multiplier, /est réduire et est la composition de la fonction. Donc, ×/∘⍳est une fonction qui prend un argument xet donne le produit des nombres [1..x].
marinus

Ah, la même approche que dans la solution Mathematica de @Yves Klett. Très agréable.
Michael Stern

@ NBZ: Cela n'existait pas encore en 2011 lorsque cette question a été écrite, ni en 2012 lorsque j'ai écrit cette réponse. Les trains n’ont été ajoutés qu’au Dyalog 14.0, sorti en 2014.
marinus le

19

J (12)

Une définition standard en J:

f=:*/@:>:@i.

Moins de 1sec pour 125!

Par exemple:

 f 0
 1
 f 5
 120
  f 125x
 1882677176888926099743767702491600857595403
 6487149242588759823150835315633161359886688
 2932889495923133646405445930057740630161919
 3413805978188834575585470555243263755650071
 31770880000000000000000000000000000000

pourquoi pas juste * />: i. ?
Andbdrew

Parce que OP demande une fonction et que le mieux que nous puissions faire en J est de définir un verbe.
Eelvex

2
Il n'y a aucune raison pour que ce ne soit pas une fonction anonyme, non? Comme ([:*/1+i.)pour 10 points, voire 8, les parenthèses ne sont nécessaires que pour appeler la fonction, pas pour la définition.
Jpjacobs

dans le dernier, f 125xque fait le x? Est-ce un type spécial de numéro?
Cyoce

@ Cyoce, oui, c'est un entier de précision étendue .
Eelvex

17

Golfscript - 13 caractères (SYM)

définit la fonction !

{),()\{*}/}:!             # happy robot version \{*}/ 

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:

0!

sortie

1

contribution

125!

sortie

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000

1
+1 pour une entrée de golf symbolique! J'aimerais pouvoir voter plus d'une fois. :-D
Chris Jester-Young

@ ChrisJester-Young Je vais le faire pour vous.
Cyoce

13

Perl 6: 13 caractères

$f={[*]1..$_}

[*]est identique à Haskell productet 1..$_compte de 1 à $_l'argument.


2
Il est interdit de ne plus utiliser d'espace après [*](message d'erreur "Deux termes d'affilée").
Konrad Borowski

Vous n'avez pas besoin de définir une variable, un bloc de code nu est une réponse acceptable car il forme implicitement une fonction. Est-ce que ça marche aussi pour 0?
Phil H

10

Matlab, 15 ans

f=@(x)prod(1:x)

Cas de test

>> f(0)
ans =
     1
>> f(4)
ans =
    24
>> tic,f(125),toc
ans =
  1.8827e+209
Elapsed time is 0.000380 seconds.

10

Python, 28 octets

f=lambda x:x/~x+1or x*f(x-1)

(basé sur la solution d'Alexandru)


9

MATL , 2 octets

:p

A expliqué:

:    % generate list 1,2,3,...,i, where i is an implicit input
p    % calculate the product of of all the list entries (works on an empty list too)

Essayez-le en ligne!


10
: O
Andras Deak

J'allais poster exactement ceci :-) Vous voudrez peut-être modifier le lien pour inclure le code et un exemple d'entrée
Luis Mendo le

Comme vous le commandez, mon seigneur.
mardi

4
@AndrasDeak, Non, cela afficherait tous les nombres de 1 à i ...
YoYoYonnY

8

Ruby - 21 caractères

f=->n{n>1?n*f[n-1]:1}

Tester

irb(main):009:0> f=->n{n>1?n*f[n-1]:1}
=> #<Proc:0x25a6d48@(irb):9 (lambda)>
irb(main):010:0> f[125]
=> 18826771768889260997437677024916008575954036487149242588759823150835315633161
35988668829328894959231336464054459300577406301619193413805978188834575585470555
24326375565007131770880000000000000000000000000000000

8

Java, 85 caractères

BigInteger f(int n){return n<2?BigInteger.ONE:new BigInteger(""+n).multiply(f(n-1));}

1
Cela manque les importations: import java.math.*;(donc, +19 octets).
Olivier Grégoire

Bon point. ............
st0le

7

PostScript, 26 caractères

/f{1 exch -1 1{mul}for}def

Exemple:

GS> 0 f =
1
GS> 1 f =
1
GS> 8 f =
40320

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:

GS> 0{1 exch -1 1{mul}for}def
GS> 8 0 load exec =
40320

1
Ghostscript ne peut pas gérer 125 !; tout ce qui dépasse 34! sort comme 1.#INF. (J'ai utilisé GNU Ghostscript 9.0.7 stock compilé pour Windows x64.)
Ross Presser

7

JavaScript, 25

function f(n)!n||n*f(n-1)

CoffeeScript, 19

f=(n)->!n||n*f(n-1)

Renvoie truedans le cas de n = 0, mais JavaScript va quand même taper que 1.


Vous n'avez pas besoin d'une returndéclaration dans la fonction JavaScript?
Justin Morgan

Mise à jour: Sainte fumée, vous n'en avez pas besoin return! Mais pourquoi pas?
Justin Morgan

C'est JavaScript 1.8 ( developer.mozilla.org/en/new_in_javascript_1.8 ). Divulgation complète, cela ne fonctionne que sur Firefox!
Casey Chu

1
Bien, je ne savais pas que je devais laisser de côté la déclaration de retour pour JavaScript 1.8. En outre, vous pouvez garantir 1 au lieu de true pour le cas n = 0 avec le même code de longueur: function f(n)n?n*f(--n):1
Briguy37

10
ES6, 17: f=n=>!n||n*f(n-1)Prenez ça, CoffeeScript!
Ry-

6

Ruby - 30 29 caractères

def f(n)(1..n).inject 1,:*end

Tester

f(0) -> 1
f(5) -> 120

1
Vous pouvez mettre le enddirectement après :*sans une nouvelle ligne ou un point-virgule.
sepp2k

1
Il n'est pas nécessaire de passer 1 à l'appel #inject. (1..10).inject :*# => 3628800
Dogbert

1
@Dogbert, pourquoi pas f(0)?
Nemo157

@ Nemo157, ah! oublié à ce sujet.
Dogbert

4
Shorter d'utiliser la syntaxe 1.9 lambda: f=->n{(1..n).inject 1,:*}. Appelez ça avec f[n].
Michael Kohl

6

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

let f n=Seq.fold(*)1{1..n}

6

C #, 20 ou 39 caractères selon votre point de vue

En tant que méthode d'instance traditionnelle (39 caractères; testé ici ):

double f(int x){return 2>x?1:x*f(x-1);}

En tant qu'expression lambda (20 caractères, mais voir disclaimer; testé ici ):

f=x=>2>x?1:x*f(x-1);

Nous devons utiliser doubleparce que 125! == 1,88 * 10 209 , ce qui est beaucoup plus élevé que ulong.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 :

Func<int,double> f=x=>2>x?1:x*f(x-1); //Error: Use of unassigned local variable 'f'

Mais cela fait :

Func<int,double> f=null;            
f=x=>2>x?1:x*f(x-1);  

Il n'y a aucune bonne raison pour cette restriction, car elle fne peut jamais être annulée au moment de son exécution. La nécessité de la Func<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éels

f=(x)->+!x||x*f x-1

Testé ici: http://jsfiddle.net/0xjdm971/


6

Brachylog , 7 à 6 octets

En faisant une gamme et en la multipliant

-1 octets de réservoirs à ovs ayant l'idée d'utiliser la fonction max ()

;1⌉⟦₁×

Explication

;1          --  If n<1, use n=1 instead (zero case)
  ⟦₁        --      Construct the range [1,n]
    ×       --      return the product of said range

Essayez-le en ligne!


Brachylog , 10 à 9 octets

récursion

≤1|-₁↰;?×

Explication

            --f(n):
≤1          --  if n ≤ 1: return 1
|           --  else:
 -₁↰        --      f(n-1)
    ;?×     --            *n

Essayez-le en ligne!


1
Cela fonctionne pour 6 octets. Prendre une entrée en tant que singleton est autorisé par défaut.
ovs

@ovs merci. Mais utiliser ;au lieu de ,permet uniquement une entrée numérique régulière. -1byte quand même
Kroppeb

5

C (39 caractères)

double f(int n){return n<2?1:n*f(n-1);}

3
Agréable. Mais peut sauver quelques caractères: double f(n){return!n?1:n*f(n-1);}- 33 caractères.
Ugoren

2
f(125)débordera
jkabrg

4

D: 45 caractères

T f(T)(T n){return n < 2 ? 1 : n * f(n - 1);}

Plus lisiblement:

T f(T)(T n)
{
    return n < 2 ? 1 : n * f(n - 1);
}

Un refroidisseur (bien qu'une version plus longue) est celui modélisé qui fait tout à la compilation ( 64 caractères ):

template F(int n){static if(n<2)enum F=1;else enum F=n*F!(n-1);}

Plus lisiblement:

template F(int n)
{
    static if(n < 2)
        enum F = 1;
    else
        enum F = n * F!(n - 1);
}

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.


3
sortez les espaces et vous pouvez les réduire à 36 caractères
Ratchet Freak

@ Cyoce Pouvez-vous expliquer?
2016

Bienvenue sur le site, @ user272735. Notez que nous ne modifions pas les solutions des personnes afin d'apporter des améliorations ici. Au lieu de cela, nous laissons des commentaires suggérant ces améliorations, comme l’a fait plus haut le cas.
Shaggy

4

PowerShell - 36

Naïve:

filter f{if($_){$_*(--$_|f}else{1}}

Tester:

> 0,5,125|f
1
120
1,88267717688893E+209

4

Scala, 39 caractères

def f(x:BigInt)=(BigInt(1)to x).product

La plupart des caractères garantissent que BigInts est utilisé, de sorte que les valeurs maximales de 125 sont remplies.


Quelques options plus courtes:(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
LRLucena

4

Javascript, ES6 17

f=n=>n?n*f(n-1):1

ES6:

  • Fonction de flèche

ES6 est plus jeune que ce défi si je me souviens bien et n'est donc pas éligible.
lirtosiast

Il est étrange avec opérateur conditionnel. Pourquoi il y a deux colons?
Qwertiy

@ Qwertiy Vous avez raison, c'était une faute de frappe, merci.
Afonso Matos

4

PowerShell, 42 octets

(sauvegardé 2 caractères en utilisant le filtre au lieu de la fonction )

filter f($x){if(!$x){1}else{$x*(f($x-1))}}

Sortie:

PS C:\> f 0
1
PS C:\> f 5
120
PS C:\> f 1
1
PS C:\> f 125
1.88267717688893E+209

1
Ceci est bon vieux maintenant, mais ... peut -il sauver 1 caractère en inversant le if / else: 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 exemple 125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Andrew,

4

Raquette (schéma) 40 35 29 octets

Calcule 0! être 1, et calcule 125! dans 0 secondes selon le minuteur. Approche récursive régulière

(define(f n)(if(= n 0)1(* n(f(- n 1)))))

Nouvelle version à battre common lisp: multiplie tous les éléments d'une liste (identique à cette solution Haskell)

(λ(n)(apply *(build-list n add1)))

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

(λ(n)(foldl * n(range 1 n)))

4

Croissant Mornington , 1827 1698 caractères

J'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!

Take Northern Line to Bank
Take Central Line to Holborn
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Bank
Take District Line to Parsons Green
Take District Line to Acton Town
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Bank
Take District Line to Upney
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

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!


3

Befunge - 2x20 = 40 caractères

0\:#v_# 1#<\$v *\<
    >:1-:#^_$>\:#^_$

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

555**   0\:#v_# 1#<\$v *\<
            >:1-:#^_$>\:#^_$    .@

Test 0

0   0\:#v_# 1#<\$v *\<
        >:1-:#^_$>\:#^_$    .@

Je sais que c'est assez vieux, mais je pense que c'est un peu plus court et plus rapide: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(où & devrait être remplacé par l'entrée). Il est de 32 caractères / octets
Date limite

3

J - 6 personnages

*/>:i.

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!


3

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é.

f(a){a=a>0?f(a-1)*a:1;}

En bon C, 28 caractères

f(a){return a>0?f(a-1)*a:1;}

+1 pour la "fonctionnalité" de GCC. Je pense que GCC autorise même une valeur de retour de bloc (je peux me souvenir d'avoir fait quelque chose comme ça)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY

3

Kona ( 11 6)

*/1.+!

K fonctionne de droite à gauche (pour la plupart), nous énumérons x(faisons une liste / un tableau de nombres de 0à x-1), nous lui ajoutons 1(des plages de liste 0à x), puis multiplions tous les nombres ensemble. Si ce n’était pas une obligation de calcul 125!, je pourrais économiser un octet de plus en éliminant à .côté du 1. En tout état de cause, 125! est calculé en quelques millisecondes:

  */1.+!125.
1.882677e+209

Vous n'avez pas besoin de beaucoup de cela. K a currying, donc la réponse entière devient */1.+!: 6 octets.
Kirbyfan64sos

@ kirbyfan64sos: Vrai & je l'éditerai. Je pense que lorsque j'ai écrit ceci il y a environ 18 mois, j'étais toujours bloqué sur tout ce qui devait être appelable (c'est-à-dire, la fonction).
Kyle Kanos
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.