Le défi factoriel vanille

Aug 25 2020

Remarque: nous avons déjà l' ancien défi factoriel , mais il comporte certaines restrictions sur le domaine, les performances et l'interdiction des fonctions intégrées. Comme le consensus ici était de créer un défi séparé sans ces restrictions afin que plus d'esolangs puissent participer, c'est parti.

Nous avons également discuté de l' opportunité de fermer l'ancien en tant que duplicata , et nous avons décidé de le laisser ouvert .


Tâche

Étant donné un entier non négatif \$n\$, évaluez la factorielle \$n!\$.

La factorielle est définie comme suit:

$$ n!=\begin{cases}1 & n=0\\n\times(n-1)!&n>0\end{cases} $$

Règles

  • Toutes les méthodes d'E / S par défaut sont autorisées.
  • Les échappatoires standard sont interdites.
  • Les éléments intégrés sont autorisés.
  • Il n'y a pas de limite de temps ou de mémoire.
  • Donner des résultats imprécis ou incorrects pour des entrées volumineuses en raison de la limite du format numérique natif est acceptable, tant que l'algorithme sous-jacent est correct. Plus précisément, il n'est pas permis d'abuser du type de numéro natif pour banaliser le défi , qui est l'une des failles standard.
  • C'est du code-golf . Le code le plus court en octets l'emporte, mais n'hésitez pas à participer à divers esolangs (en particulier ceux entravés par les restrictions du premier défi).

Cas de test

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

Réponses

26 Dingus Aug 25 2020 at 10:05

Langage de programmation Shakespeare , 106 octets

,!Ajax,!Puck,!Act I:!Scene I:![Enter Ajax and Puck]Ajax:Listen tothy!You is the factorial ofyou!Open heart

Essayez-le en ligne!

Utilise le intégré the factorial of, qui n'est pas du tout décrit dans la documentation officielle .

Commenté

,!Ajax,!Puck,!Act I:!Scene I:![Enter Ajax and Puck] # header
Ajax:Listen tothy!                                  # read (numeric) input
You is the factorial ofyou!                         # take factorial
Open heart                                          # numeric output
15 640KB Aug 25 2020 at 08:31

code machine x86-16 / x87, 13 octets

Binaire:

00000000: d9e8 e308 518b f4de 0c59 e2f8 c3         ....Q....Y...

Référencement:

D9 E8       FLD1                ; start with 1 
E3 08       JCXZ DONE           ; if N = 0, return 1 
        FACT_LOOP: 
51          PUSH CX             ; push current N onto stack
8B F4       MOV  SI, SP         ; SI to top of stack for N 
DE 0C       FIMUL WORD PTR[SI]  ; ST = ST * N 
59          POP  CX             ; remove N from stack 
E2 F8       LOOP FACT_LOOP      ; decrement N, loop until N = 0
        DONE: 
C3          RET                 ; return to caller

Fonction appelable. Entrée \$n\$dans CX, sortie \${n!}\$dans ST(0). Fonctionne pour les valeurs de \$n\$jusqu'à 21(avant perte de précision).

Ou récursif ...

code machine x86-16 / x87, 15 octets

D9 E8       FLD1                ; start with 1
        FACT_CALL:
E8 0A       JCXZ DONE           ; if N = 0, end recursion
51          PUSH CX             ; push current N onto stack
49          DEC  CX             ; decrement N
E8 F9FF     CALL FACT_CALL      ; recurse N-1
8B F4       MOV  SI, SP         ; SI to top of stack for N
DE 0C       FIMUL WORD PTR[SI]  ; ST = ST * N
59          POP  CX             ; remove N from stack
        DONE:
C3          RET                 ; return from recursive call

Ou x64 juste pour les sourires ...

code machine x86_64, 12 11 octets

  31:   6a 01            push   0x1             # start with 1
  33:   58               pop    rax
  35:   e3 05            jrcxz  3c <done>       # if 0, return 1
0037 <f_loop>:
  37:   48 f7 e1         mul    rcx             # rax = rax * N
  3a:   e2 fb            loop   37 <f_loop>     # loop until N = 0
003c <done>:
  3c:   c3               ret                    # return to caller

Essayez-le en ligne!

Entrée \$n\$dans rcx, sortie \${n!}\$dans raxpour les valeurs de \$n\$jusqu'à 20.

  • -1 octets thx à @PeterCordes sur x86_64!
13 Mukundan314 Aug 25 2020 at 09:12

MATL , 2 octets

:p

Essayez-le en ligne!

La :plage de génération de 1 à l'entrée incluse et la préduction du produit

12 Sisyphus Aug 25 2020 at 07:22

C (gcc), 21 octets

Utilise l'astuce d'affectation, fonctionne de manière cohérente dans GCC sans optimisations.

O(o){o=o?o*O(~-o):1;}

Essayez-le en ligne!

10 Neil Aug 25 2020 at 07:16

Rétine , 29 octets

.+
*
.
$.<'$*
~`.+
.+¶$$.($&_

Essayez-le en ligne! Explication:

.+
*

Convertir nen unaire.

.
$.<'$*

Compte à rebours nen décimal, avec *s à la fin .

~`.+
.+¶$$.($&_

Enveloppez le résultat dans une étape de remplacement de la rétine et évaluez-le.

Exemple: Pour n=10, l'étape résultante est la suivante:

.+
$.(10*9*8*7*6*5*4*3*2*1*_

Cela calcule la longueur de la chaîne obtenue en répétant le _par chacun des nombres de 1à 10.

Explication pour n=0:

.+
*

Supprimez l'entrée.

.
$.<'$*

Ne fais rien.

~`.+
.+¶$$.($&_

Ne faites rien et évaluez l'étape vide résultante sur la chaîne vide.

L'étape vide renvoie 1plus que le nombre de caractères. Comme la chaîne est vide, c'est juste 1. C'est le résultat que nous voulions depuis le début.

Il est bien sûr possible de calculer correctement la factorielle même pour n=0, mais ma meilleure tentative a pris 30 octets.

10 JoKing Aug 25 2020 at 09:01

brainfuck , 56 octets

+>,[[>+>+<<-]>[-<<[->+<<+>]<[->+<]>>>]<<[-]>[->+<]>>-]<.

Essayez-le en ligne!

Prend les entrées et les sorties sous forme de valeurs d'octet. Étant donné que cet interpréteur a des cellules de taille 8 bits, il ne peut vraiment rien faire de plus grand que 5!. Vous pouvez utiliser cet interpréteur pour essayer des valeurs plus importantes.

8 Lyxal Aug 25 2020 at 06:12

MAWP , 19 octets

@[!1A]%_1A[%W_1A]~:

Essayez-le!

8 water_ghosts Aug 25 2020 at 07:21

Google Sheets / Excel / Numbers, 8 octets

=FACT(A1

Les trois programmes de feuilles de calcul ferment automatiquement les parenthèses.

8 DanielH. Aug 25 2020 at 09:47

Hochet , 23 20 octets

|s>s[0+q][g-s<*~s>]~

Essayez-le en ligne!

C'est la réponse que je n'ai pas pu poster sur l'autre challenge! (voir ça )

Notez que je n'ai pas encore d'interpréteur en ligne pour Rattle, donc l'interpréteur est écrasé dans l'en-tête sur TIO (c'est pourquoi TIO pense que c'est du code Python 3 mais ce qui est dans la codesection n'est que du code Rattle - ignorez l'en-tête et le pied de page).

Cela fonctionne en fait jusqu'à 170!(mais entraînera une perte de précision, bien sûr). Dans la prochaine mise à jour de Rattle, cela deviendra en fait un programme intégré - rendant la solution possible à seulement deux octets - mais pour sa version actuelle, il s'agit probablement du programme factoriel le plus court et le plus intéressant.

Explication

|           takes user's input
s>s         saves the input to memory slots 0 and 1
[0+q]       if the top of the stack is equal to zero: increments, and quits (implicitly prints the top of the stack)
[    ]~     loop n times, where n is the value in storage at the pointer
 g-s         gets the value at the pointer, decrements, and saves
 <           moves pointer left
 *~          pushes product of old top of stack and value at pointer to new top of stack
 s           saves to memory slot at pointer
 >           moves pointer right
             (implicitly outputs the value at the top of the stack after the program executes)

En substance, ce programme enregistre la valeur donnée (à partir de l'entrée) dans deux emplacements de mémoire. Ensuite, il décrémente un emplacement mémoire et multiplie l'autre par la valeur décrémentée, jusqu'à ce que la valeur se décrémente à 1, puis il sort la valeur finale.

8 J42161217 Aug 25 2020 at 13:52

Wolfram Language (Mathematica) , 11 octets

Gamma[#+1]&

Essayez-le en ligne!

Wolfram Language (Mathematica) , 15 octets

1~Pochhammer~#&

Essayez-le en ligne!

Wolfram Language (Mathematica) , 19 octets

If[#>0,#0[#-1]#,1]&

Essayez-le en ligne!

Wolfram Language (Mathematica) , 24 octets

Le déterminant de la matrice n * n des réciproques des fonctions bêta est n!

Det[1/Beta~Array~{#,#}]&

Essayez-le en ligne!

Wolfram Language (Mathematica) , 26 octets

GroupOrder@*SymmetricGroup

Essayez-le en ligne!

8 PizgenalFilegav Aug 26 2020 at 08:47

Miniflak , 90 80 octets

-10 octets grâce à @Nitrodon!

{(({})[()])}{}((())){({(()[{}]({}))([{}]({}))}({}{})[{}])(({}({}))[({}[{}])])}{}

Essayez-le en ligne!

Nous avons déjà une autre réponse Brain-Flak ici, mais elle utilise les deux piles et ne fonctionne donc pas dans Miniflak (un sous-ensemble restreint de Brain-Flak où <, >et []n'est pas autorisé). Pour éviter la deuxième pile, ce programme utilise un algorithme de multiplication différent.

Explication

{(({})[()])}
{          }    # While the top of the stack is nonzero:
   {}           # Pop the stack
  (  )          # Push a copy on the stack
      [()]      # Subtract 1
 (        )     # Push the result

Cette partie compte à rebours de la valeur d'entrée à 0, laissant une copie de chaque nombre dans l'ordre.


{}((()))
{}              # Pop the zero on the top
  ((()))        # Push 1 twice

Ces éléments supplémentaires sont là pour que lorsque l'entrée est 0 ou 1, nous les multiplions ensemble pour obtenir 1 au lieu de multiplier accidentellement quelque chose par 0.


{({(()[{}]({}))([{}]({}))}({}{})[{}])(({}({}))[({}[{}])])}{}
{                                                        }    # While the top of the stack is nonzero:
 ({(()[{}]({}))([{}]({}))}({}{})[{}])                         # Multiply the top two values
                                     (({}({}))[({}[{}])])     # Swap the top two values
                                                          {}  # Remove the zero on top

Cette boucle est le cœur du programme: à chaque étape, elle multiplie les deux premiers nombres ensemble puis ramène le nombre en dessous d'eux vers le haut. Lorsque nous manquons de nombres, un zéro est échangé vers le haut et la boucle se termine. Nous supprimons ensuite ce zéro, et le résultat de la multiplication de tous les nombres ensemble (qui est la factorielle de l'entrée, comme les nombres décomptés à partir de celui-ci jusqu'à 1) est laissé.


Comment fonctionne cet algorithme de multiplication?
(Supposons que les deux premiers nombres de la pile soient aet b.)

({(()[{}]({}))([{}]({}))}({}{})[{}])
      {}                               # Pop a
     [  ]                              # Subtract it ... 
   ()                                  # ... from 1
         ({})                          # Add b
  (          )                         # Push the result
               [{}]                    # Subtract that ... 
                   ({})                # ... from b ...
              (        )               # and push the result
 {                      }              # Repeat until a reaches 0, keeping a running total of the sum of both results
                          {}{}         # Pop a and b, add them together, ... 
                         (    )[{}]    # ... and ignore the result
(                                  )   # Push the running total

Lors de chaque passage, a(le haut de la pile) est remplacé par b-(b+(1-a)), qui est égal à a-1. Cela se répète jusqu'à ce qu'il aatteigne 0, de sorte que le nombre d'itérations est égal à la première entrée. Le total cumulé garde la trace de la somme des deux résultats à chaque itération. Le premier résultat est b+(1-a)et le second est a-1, donc leur somme est toujours b, la deuxième entrée. Cela signifie que le suivi du total en cours donne le produit des deux entrées. Enfin, avant de pousser le produit, on pop aet bparce qu'on n'en a plus besoin.

Le dernier élément est l'algorithme d'échange:

(({}({}))[({}[{}])])
  {}                  # Pop the top number
    ({})              # Add the second number
 (      )             # Push the result
           {}         # Pop the sum
              {}      # Pop the second number ... 
             [  ]     # ... and subtract it from the sum
          (      )    # Push the result (the first number) ...
         [        ]   # ... and subtract that from the previous result (the sum)
(                  )  # Push the final result (the second number)

Puisque le premier numéro est repoussé avant le second, leur ordre est inversé par rapport à avant.

7 jmizv Aug 25 2020 at 19:17

Java , 37 36 octets

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

Je voulais simplement essayer de participer bien que Java ne soit pas le meilleur langage pour avoir le moins d'octets possible.

Il s'agit simplement de la définition inventée en Java, avec un appel récursif.

edit: un octet de moins, merci @Jo King

6 Scott Aug 25 2020 at 06:39

JavaScript (Node.js) , 17 octets

y=x=>x?x*y(x-1):1

Essayez-le en ligne!

6 DLosc Aug 25 2020 at 07:33

QBasic , 37 octets

INPUT n
f=1
FOR i=1TO n
f=f*i
NEXT
?f

Si nest égal à zéro, la boucle for ne fait rien et 1 est émis. Sinon, la boucle for court ide 1 jusqu'à et y compris le nombre d'entrée, en multipliant le résultat par chacun i.

Les valeurs ici sont en simple précision par défaut, ce qui signifie qu'après 10! nous commençons à obtenir des résultats en notation scientifique. Les valeurs sont toujours exactes pour 11! et 12 !, cependant (par exemple 12! donne 4.790016E+08). A 13 ans! nous commençons à voir une erreur d'arrondi ( 6.227021E+09pour 6227020800). Si nous utilisons une variable double précision f#à la place de f(+4 octets), nous obtenons des résultats précis jusqu'à 21 !.

6 EthanChapman Aug 25 2020 at 12:19

CJam , 4 octets

rim!

Essayez-le en ligne

Je suis sûr qu'il y a d'autres solutions sur 4 octets, mais j'aime bien la façon dont cela crée un mot anglais avec ponctuation, même s'il s'exclame "rim!" sans contexte semble absurde.

6 K3v1n Aug 25 2020 at 17:47

Rouille , 27 octets

Fermeture qui prend npour entrée. Merci à madlaina

|n|(1..=n).fold(1,|f,x|f*x)

Exemple de programme wrapper pour appeler la fermeture (111 octets).

fn main(){let f=|n|(1..=n).fold(1,|f,x|f*x);print!("{}",f(std::env::args().nth(1).unwrap().parse().unwrap()));}

Essayez-le en ligne!

Rouille , 104 octets

fn main(){print!("{}",(1..=std::env::args().skip(1).next().unwrap().parse().unwrap()).fold(1,|f,x|f*x))}

Essayez-le en ligne!

La rouille n'est certes pas faite pour le golf, mais c'était intéressant de le faire! Prend nvia les arguments du programme. Échoue commodément à13!

Je suis certain qu'un bon nombre d'octets unwrap()peuvent être supprimés , peut-être si les appels peuvent être éliminés en utilisant ?et a Result.

5 JDL Aug 25 2020 at 16:00

R, 15 octets

gamma(scan()+1)

Il y a aussi factorialce qui semble être autorisé en tant que solution 9 octets.

5 Razetime Aug 25 2020 at 19:12

Pip , 5 octets

$*\,q

Essayez-le en ligne!

5 Charlie Aug 26 2020 at 22:05

ArnoldC , 409 octets

IT'S SHOWTIME
HEY CHRISTMAS TREE f
YOU SET US UP 1
HEY CHRISTMAS TREE x
YOU SET US UP 0
GET YOUR ASS TO MARS x
DO IT NOW
I WANT TO ASK YOU A BUNCH OF QUESTIONS AND I WANT TO HAVE THEM ANSWERED IMMEDIATELY
STICK AROUND x
GET TO THE CHOPPER f
HERE IS MY INVITATION f
YOU'RE FIRED x
ENOUGH TALK
GET TO THE CHOPPER x
HERE IS MY INVITATION x
GET DOWN 1
ENOUGH TALK
CHILL
TALK TO THE HAND f
YOU HAVE BEEN TERMINATED

Essayez-le en ligne!

Approche itérative, il boucle juste à partir du nombre d'entrée et le diminue jusqu'à ce qu'il atteigne 0.

4 Lyxal Aug 25 2020 at 06:11

Gelée , 1 octet

!

Essayez-le en ligne!

4 JoKing Aug 25 2020 at 08:14

Brain-Flak , 52 octets

<>(())<>{(({}[()]))({<>({})<><({}[()])>}{}<>{})<>}<>

Essayez-le en ligne!

Publier ma propre solution Brain-Flak, qui diffère de la même taille que celle de l'ancien défi .

4 Jonah Aug 25 2020 at 05:58

J , 1 octet

!

Essayez-le en ligne!

Fonctionne aussi pour APL

4 JoKing Aug 25 2020 at 09:40

Befunge-93 , 20 19 octets

&+#v:!_:
\@#<*_\:.#

Essayez-le en ligne!

Republier plus de mes réponses à l'ancien défi qui ne correspondait pas aux exigences. Celui-ci ne s'est pas levé 125!, du moins avec cet interprète.

Explication:

&           Get the input
 +          Add it to the current counter (initially 0)
    :!_     Duplicate and check if it is zero
&+     :    If not, duplicate and repeat, but add the -1 from EOF to the input
  #v:!      If it is, not the 0 into a 1, duplicate and go to the second line
            This initialises the stack as n,n-1,n-2...,1,1,1
   <        Start going left
\    _ :    Check if the second element on the stack is zero
    *       If not, then multiply the top two elements
 @#   \ .#  If it is, then print the factorial value and terminate

Je crois que c'était en fait ma première réponse sur ce site , la version ci-dessous étant la version 20 octets de ce qui précède.

Befunge-93 , 20 octets

1&0>-#1:__\#0:#*_$.@

Essayez-le en ligne!

4 ATaco Aug 25 2020 at 10:28

Funky 2 , 22 18 octets

Sauvegardé 4 octets grâce à l'optimisation d'ovs.

f=x=>x<1orx*f(x-1)

Quand x<1, retourne 1(en raison de la x<1vérité), sinon retourne x*f(x-1), obtenant récursivement le factoriel /

Essayez-le en ligne!

3 DLosc Aug 25 2020 at 06:55

tinylisp , 34 octets

(load library
(q((n)(product(1to n

Essayez-le en ligne! (Le code a +4 octets pour attribuer la fonction lambda à un nom.)

Explication

Utilisation des fonctions de la bibliothèque productet 1to:

(q             Quote the following list, which can then be treated as a lambda function
 ((n)          that takes a single argument n:
  (product      Multiply together (if the list is empty, returns 1)
   (1to n))))   all numbers from 1 up to and including n
     
3 Razetime Aug 25 2020 at 09:23

Rubis , 23 19 octets

->n{Math.gamma n+1}

-4 octets en utilisant la fonction gamma (Dingus).

Essayez-le en ligne!

3 Dingus Aug 25 2020 at 10:29

TI-BASIC (TI-83), 2 octets

Ans!

Prend une entrée via Ans. Le nombre de caractères diffère du nombre d'octets car TI-BASIC est tokenisé ; Anset !sont tous deux des jetons de 1 octet.

Exemple de sortie

Utilise cet émulateur .

3 Mukundan314 Aug 25 2020 at 09:52

Bash , 13 octets

seq -s* $1|bc

Essayez-le en ligne!

3 pxeger Aug 25 2020 at 15:03

Python 2 , 38 octets

i=n=1;exec"n*=i;i+=1;"*input();print n

Essayez-le en ligne!

3 streetster Aug 25 2020 at 20:13

K (ngn / k) , 6 octets

Solution:

*/1+!:

Essayez-le en ligne!

Explication:

*/1+!: / the solution
    !: / range 0..N
  1+   / add 1 (vectorised)
*/     / product

Supplémentaire:

  • Aussi */-!-:pour le même nombre d'octets.