# The vanilla factorial challenge

Note: We already have the old factorial challenge, but it has some restrictions on the domain, performance, and banning built-ins. As the consensus here was to create a separate challenge without those restrictions so that more esolangs can participate, here it goes.

Also, we discussed whether we should close the old one as a duplicate of this, and we decided to leave it open.

Given a non-negative integer $$\n\$$, evaluate the factorial $$\n!\$$.

The factorial is defined as follows:

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

## Rules

• All default I/O methods are allowed.
• Standard loopholes are forbidden.
• Built-ins are allowed.
• There is no time or memory limit.
• Giving imprecise or incorrect results for large inputs due to the limit of the native number format is fine, as long as the underlying algorithm is correct. Specifically, it is not allowed to abuse the native number type to trivialize the challenge, which is one of the standard loopholes.
• This is . Shortest code in bytes wins, but feel free to participate in various esolangs (especially the ones hindered by the restrictions of the former challenge).

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

# Shakespeare Programming Language, 106 bytes

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

Try it online!

Uses the built-in the factorial of, which isn't described at all in the official docs.

### Commented

,!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

# x86-16 / x87 machine code, 13 bytes

Binary:

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

Listing:

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:

Callable function. Input $$\n\$$ in CX, output $$\{n!}\$$ in ST(0). Works for values of $$\n\$$ up to 21 (before loss of precision).

Or recursive...

## x86-16 / x87 machine code, 15 bytes

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

Or x64 just for grins...

## x86_64 machine code, 12 11 bytes

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

Try it online!

Input $$\n\$$ in rcx, output $$\{n!}\$$ in rax for values of $$\n\$$ up to 20.

• -1 bytes thx to @PeterCordes on x86_64!
• Foiled once again by the limitations of x86-16's memory addressing modes! Would have been nice to elide that mov si, sp by just doing a fimul WORD PTR [sp] to load directly from the stack pointer. Oh well. – Cody Gray Aug 26 at 0:37
• @CodyGray: You can do that in 32-bit code with the same machine code for everything else, except the ModRM byte for fimul dword ptr [esp]. Net savings of 1 byte because encoding that [esp] addressing mode requires a SIB; the unfortunate price x86 pays for more flexible addressing modes. They could have chosen ECX or something to be the special-case register that needs a longer encoding, instead of pessimizing -fomit-frame-pointer code :/. Also, obviously pure integer with mul cx or ecx would be more compact but less interesting. – Peter Cordes Aug 27 at 5:53
• If not for longer [esp] addressing modes, there might have been something to gain by taking a stack arg so you don't have to manually push/pop. Or perhaps taking a value by non-const reference, e.g. pointed-to by di. Start with a jmp to the loop condition at the bottom instead of jecxz, and you can maybe use dec word ptr [di] / jg : 2+2 = 4 bytes instead of 6 total for mov si,sp / push/pop/loop. Or saves 1 byte in 32-bit mode (the [edi] instead of [esp] addressing mode). But hard to justify the destroying the by-reference arg. – Peter Cordes Aug 27 at 6:00
• Would be 9 bytes (fld1, fimul [di], dec [di], jnz, ret) if we didn't have to worry about that "pesky" 0 case! – 640KB Aug 27 at 14:17
• Your x86-64 version can start with push 1 / pop rax. It's always possible to create a small value in a register in 3 bytes, sometimes with lea reg, [reg+disp8], or worst case push imm8. tips (xor/inc is not break-even with those in 64-bit mode because the 1-byte inc/dec encodings were repurposed as REX prefixes. That trick is only good in 16 / 32-bit mode. Also, I wish AMD64 had used one of the other removed opcode bytes for a mov r/m32, sign_extended_imm8 opcode to make stores and register-init with constants efficient in 3 bytes.) – Peter Cordes Aug 27 at 20:50

# MATL, 2 bytes

:p

Try it online!

The : generate range from 1 to input inclusive and the p reduces on product

• I like the emoticon :p – user96495 Aug 25 at 2:15
• PERFECT. love that emoticon. – matt Sep 9 at 17:55

# C (gcc), 21 bytes

Uses the assignment trick, works consistently in GCC without optimizations.

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

Try it online!

• What's the assignment trick? – Quelklef Aug 25 at 21:51
• @Quelklef see here stackoverflow.com/questions/4644860/… – AZTECCO Aug 25 at 23:13
• Undefined behavior? – Dúthomhas Aug 26 at 1:45
• Why ~-o and not o-1? – retnikt Aug 27 at 11:33
• Guess what? I read this program in ghost voice. – user96495 Sep 5 at 13:32

# Retina, 29 bytes

.+
*
.
$.<'$*
~.+
.+¶$$.(&_ Try it online! Explanation: .+ * Convert n to unary. . .<'* Count down from n in decimal, with trailing *s. ~.+ .+¶$$.($&_ Wrap the result in a Retina replacement stage and evaluate it. Example: For n=10, the resulting stage is as follows: .+$.(10*9*8*7*6*5*4*3*2*1*_

This calculates the length of the string obtained by repeating the _ by each of the numbers from 1 to 10.

Explanation for n=0:

.+
*

Delete the input.

.
$.<'$*

Do nothing.

~`.+

Try it online!

# ArnoldC, 409 bytes

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

Try it online!

Iterative approach, it just loops starting from the input number and decreasing it until it reaches 0.

# Jelly, 1 byte

!

Try it online!

• For once a Jelly program that I understand! :) – 640KB Aug 28 at 14:17

# Brain-Flak, 52 bytes

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

Try it online!

Posting my own Brain-Flak solution, which differs from the same size one from the older challenge.

• You might want to move your Brainfuck answer too, as BF can't meet the performance requirement of the old challenge (which makes all BF answers there invalid). – Bubbler Aug 25 at 1:20

# J, 1 byte

!

Try it online!

Works for APL too

• Also works in most, if not all, flavors of APL (which is the parent of J), and Jelly (which is a child of J). – Bubbler Aug 24 at 23:29
• Why not? After you made that explanation, I thought ! was for logical negation... – user96495 Aug 25 at 2:21
• Ha. That would be -. – Jonah Aug 25 at 2:22

# Befunge-93, 20 19 bytes

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

Try it online!

Reposting more of my answers from the old challenge that didn't fit the requirements. This one didn't get up to 125!, at least with this interpreter.

## Explanation:

&           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

I believe this was actually my first answer on this site, with the below being the 20 byte version of the above.

# Befunge-93, 20 bytes

1&0>-#1:__\#0:#*_$.@ Try it online! # Funky 2, 22 18 bytes Saved 4 bytes through ovs's optimization. f=x=>x<1orx*f(x-1) When x<1, returns 1 (Due to x<1 being truthy), Otherwise returns x*f(x-1), recursively getting the factorial/ Try it online! • f=x=>x<1orx*f(x-1) seems to work just fine. – ovs Aug 25 at 8:39 • This seems like an interesting language. Is there more documentation than the GitHub Wiki? – ovs Aug 25 at 8:45 • @ovs Unfortunately I've not documented very well. And Worse, the TIO version is quite out-dated and lacks functionality. Good spot on the golf though – ATaco Aug 25 at 11:13 # tinylisp, 34 bytes (load library (q((n)(product(1to n Try it online! (Code has +4 bytes for assigning the lambda function to a name.) ### Explanation Using the library functions product and 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 # Ruby, 23 19 bytes ->n{Math.gamma n+1} -4 bytes using gamma function (Dingus). Try it online! # Bash, 13 bytes seq -s*$1|bc

Try it online!

• Hopefully you don't have a filename beginning with -s in the current directory. – user253751 Aug 25 at 9:58

# Python 2, 38 bytes

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

Try it online!

• Nice attempt. Note that the old challenge has a ton of non-builtin Python answers, the best being a 25-bytes function. – Bubbler Aug 25 at 8:18
• @Bubbler I just wanted to see what I could get without looking at the old ones – pxeger Aug 25 at 8:19
• Nice, your exec this beats the while loop: TIO – xnor Aug 25 at 9:57

# K (ngn/k), 6 bytes

Solution:

*/1+!:

Try it online!

Explanation:

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

Extra:

• Also */-!-: for the same byte count.

# Pepe, 57 bytes

3 bytes have been decreased from my Pepe factorial program.

rrEEReREEEEErEeREeEreEREErEEEEErEEEeeReererRrEEEEEEeEreEE

Try it online!