# 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).

## Test cases

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


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 – hi. 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. – hi. 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.

~.+
.+¶.($&_  Do nothing, and evaluate the resulting empty stage on the empty string. The empty stage returns 1 more than the character count. As the string is empty, this is just 1. Conveniently, this is the result we wanted all along. It is of course possible to calculate the factorial properly even for n=0, but my best attempt took 30 bytes. # brainfuck, 56 bytes +>,[[>+>+<<-]>[-<<[->+<<+>]<[->+<]>>>]<<[-]>[->+<]>>-]<.  Try it online! Takes input and outputs as byte values. Since this interpreter has 8 bit size cells, it can't really do anything larger than 5!. You can use this interpreter to try larger values. # MAWP, 19 bytes @[!1A]%_1A[%W_1A]~:  Try it! • F*** MAWP (Upvote) – null Aug 25 at 2:25 • TooFast4Meeeeeee – Razetime Aug 25 at 2:27 • @Razetime Haha! – Lyxal Aug 25 at 2:28 ## Google Sheets / Excel / Numbers, 8 bytes =FACT(A1  All three spreadsheet programs close parentheses automatically. • my IDE also closes parentheses, but that doesn't make it a correct program in the language before closing right? – Jens Renders Aug 28 at 12:54 # Rattle, 23 20 bytes |s>s[0+q][g-s<*~s>]~  Try it online! This is the answer that I could not post on the other challenge! (see this) Note that I do not have an online interpreter for Rattle yet so the interpreter is mashed together into the header on TIO (which is why TIO thinks it's Python 3 code but what's in the code section is only Rattle code - ignore the header and footer). This actually works for up to 170! (but will a loss of precision, of course). In the next Rattle update this will actually become a builtin - making the possible solution just two bytes - but for its current version this is likely the shortest and most interesting factorial program. # Explanation | 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)  In essence, this program saves the given value (from input) to two memory slots. Then, it decrements one memory slot and multiplies the other by the decremented value, until the value decrements to 1, then it outputs the final value. # Wolfram Language (Mathematica), 11 bytes Gamma[#+1]&  Try it online! # Wolfram Language (Mathematica), 15 bytes 1~Pochhammer~#&  Try it online! # Wolfram Language (Mathematica), 19 bytes If[#>0,#0[#-1]#,1]&  Try it online! # Wolfram Language (Mathematica), 24 bytes The determinant of the n*n matrix of reciprocals of beta functions is n! Det[1/Beta~Array~{#,#}]&  Try it online! # Wolfram Language (Mathematica), 26 bytes GroupOrder@*SymmetricGroup  Try it online! • Hah very original answers :-D. But why not the obvious #!&? – freddieknets Aug 27 at 13:03 • @freddieknets The obvious one had been already posted by another user – J42161217 Aug 27 at 14:04 # Miniflak, 90 80 bytes -10 bytes thanks to @Nitrodon! {(({})[()])}{}((())){({(()[{}]({}))([{}]({}))}({}{})[{}])(({}({}))[({}[{}])])}{}  Try it online! We already have another Brain-Flak answer here, but it uses both stacks and so doesn't work in Miniflak (a restricted subset of Brain-Flak where <, > and [] are disallowed). To avoid the second stack, this program uses a different multiplication algorithm. ### Explanation {(({})[()])} { } # While the top of the stack is nonzero: {} # Pop the stack ( ) # Push a copy on the stack [()] # Subtract 1 ( ) # Push the result  This part counts down from the input value to 0, leaving a copy of each number in order. {}((())) {} # Pop the zero on the top ((())) # Push 1 twice  These extra ones are there so that when the input is 0 or 1, we multiply them together to get 1 instead of accidentally multiplying something by 0. {({(()[{}]({}))([{}]({}))}({}{})[{}])(({}({}))[({}[{}])])}{} { } # While the top of the stack is nonzero: ({(()[{}]({}))([{}]({}))}({}{})[{}]) # Multiply the top two values (({}({}))[({}[{}])]) # Swap the top two values {} # Remove the zero on top  This loop is the core of the program: at each step, it multiplies the top two numbers together and then brings the number below them to the top. When we run out of numbers, a zero gets swapped to the top, and the loop ends. We then remove that zero, and the result of multiplying all the numbers together (which is the factorial of the input, as the numbers counted down from it to 1) is left. How does this multiplication algorithm work? (Suppose the top two numbers on the stack are a and 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  During each run-through, a (the top of the stack) is replaced by b-(b+(1-a)), which equals a-1. This repeats until a reaches 0, so the number of iterations is equal to the first input. The running total keeps track of the sum of the two results at each iteration. The first result is b+(1-a) and the second is a-1, so their sum is always b, the second input. This means that keeping track of the running total yields the product of the two inputs. Finally, before pushing the product, we pop a and b because we don't need them anymore. The last piece is the swapping algorithm: (({}({}))[({}[{}])]) {} # 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)  Since the first number is pushed back before the second one, their order is swapped from before. # JavaScript (Node.js), 17 bytes y=x=>x?x*y(x-1):1  Try it online! • Would y=x=>x*y(x-1)||1 work? – Redwolf Programs Aug 25 at 0:12 • That's what I originally tried, but it attempts to evaluate y(x-1) to see if it is true, leading to infinite recursion. – Scott Aug 25 at 0:48 # QBasic, 37 bytes INPUT n f=1 FOR i=1TO n f=f*i NEXT ?f  If n is zero, the for loop does nothing and 1 is output. Otherwise, the for loop runs over i from 1 up to and including the input number, multiplying the result by each i. The values here are single-precision by default, which means that after 10! we start getting output in scientific notation. The values are still accurate for 11! and 12!, though (e.g. 12! gives 4.790016E+08). At 13! we start to see rounding error (6.227021E+09 for 6227020800). If we use a double-precision variable f# in place of f (+4 bytes), we get accurate results up to 21!. # CJam, 4 bytes rim!  Try it online I'm sure there's other 4-bytes solutions, but I quite like how this makes an English word with punctuation, even if exclaiming "rim!" without context seems absurd. # Java, 37 36 bytes int f(int n){return n<2?1:n*f(n-1);}  I simply wanted to try to participate although Java is not the best language to have as little bytes as possible. This is simply the definition coined to Java, with a recursive call. edit: one byte less, thx @Jo King • You can also use a lambda expression to save more bytes. – corvus_192 Aug 27 at 9:55 # Rust, 27 bytes Closure that takes n as its input. Thanks to madlaina |n|(1..=n).fold(1,|f,x|f*x)  Sample wrapper program to call closure (111 bytes). fn main(){let f=|n|(1..=n).fold(1,|f,x|f*x);print!("{}",f(std::env::args().nth(1).unwrap().parse().unwrap()));}  Try it online! # Rust, 104 bytes fn main(){print!("{}",(1..=std::env::args().skip(1).next().unwrap().parse().unwrap()).fold(1,|f,x|f*x))}  Try it online! Rust sure isn't built for golfing, but 'twas interesting to do so! Takes n via program arguments. Conveniently fails at 13! I'm certain a fair number of bytes can be shaved from this, possibly if the unwrap() calls can be eliminated using ? and a Result. • codegolf.stackexchange.com/questions/74096/… – Razetime Aug 25 at 11:12 • Sorry, I didn't see your answer before posting my own. You don't have to write a full program, a closure is fine for these sorts of challenges. You can use .nth(1) instead of .skip(1).next(). It is possible to return a Result from main, but unfortunately there's no standard type unifying NoneError from the Option and ParseIntError (Box<dyn std::error::Error> doesn't work because it's not implemented by NoneError (and probably shouldn't be)). In any case, the signature overhead is larger than the few bytes saved in most cases. – madlaina Aug 25 at 19:10 • @madlaina Thank you! So that means I can use the function argument as input without taking it from program arguments I presume? Also I can't remember why I didn't use nth(), I guess I had issues with stdin, I'll change that too :) – K3v1n Aug 26 at 3:39 • Yes, you can just take the inputs as closure arguments, and you don't have to print the result, returning it is fine in most cases. – madlaina Aug 26 at 6:39 # R, 15 bytes gamma(scan()+1)  There is also factorial which appears to be allowable as a 9-byte solution. • or 15 bytes using scan() instead of function(x) – Dominic van Essen Aug 25 at 9:11 • factorial is the obvious shortest answer, but if you insist on a full program then prod(1:scan()) is 14 bytes. – Robin Ryder Aug 25 at 9:22 • @Robin, that doesn't work for input 0. – JDL Aug 25 at 9:27 • Indeed, sorry about that. – Robin Ryder Aug 25 at 9:27 # Pip, 5 bytes $*\,q


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... – hi. 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
*/     / 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!