# The vanilla factorial challenge

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


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.

# Keg, -hr, 4 bytes

Ï_∑*


Try it online!

• Shouldn't that be 7 bytes, due to the use of -hr? Feb 7, 2022 at 8:01
• @oliver -hr is a command line flag, and it's the site policy that flags don't count towards the byte score. Feb 7, 2022 at 8:19

# Pyth, 2 bytes

*F


Try it online!

Alternate solution:

.!


# 05AB1E, 1 byte

!


Try it online!

# Python 3.8, 23 21 bytes

Saved 2 bytes thanks to Bubbler!!!

import math
math.perm


Try it online!

• I think f= can be excluded from the byte count? Aug 24, 2020 at 23:44
• @Bubbler You get so used to things you forget what their orginal purpose was - thanks for the heads up! :D Aug 24, 2020 at 23:55
• What's the point of the math.perm line? I mean, sure, we use math.perm() in the footer, but you can take out that math.perm line and the code will still work. (Then again, maybe the import math line can just be placed in the header, which would leave... 0 bytes? Hm... maybe we should count math.perm.)
– J-L
Aug 25, 2020 at 17:41
• @J-L In function answers the whole point is to provide enough code to define a function that solves the challenge. Here the function is math.perm so job done. Leaving anything out doesn't provide a full solution. Aug 25, 2020 at 17:52
• Hmm I feel like excluding the f= is somehow wrong, maybe because the interface between the answer and the evaluation code is tightly coupled? Moving f= to the header only makes sense when the first line of code can be used as an expression without assignment, in this case we could wrap math.perm in a lambda and then import math to fit the usual pattern of excluding the assigned variable. If math.perm is allowed to be named in the evaluation code, we could look at the import math statement as a complete solution since it defines math.perm in the current scope. Feb 7, 2022 at 4:56

# Japt, 1 byte

l


Try it online!

# Charcoal, 8 bytes

ＩΠ…·¹∨Ｎ¹


Try it online! Link is to verbose version of code. Explanation:

      Ｎ     n as a number
∨      Logical Or
¹    Literal 1
…·¹       Inclusive range from 1 to n
Π          Take the product
Ｉ           Cast to string
Implicitly print


# Io, 20 bytes

method(\,\factorial)


Try it online!

# Seriously, 2 bytes

,!


Try it online!

# Elixir, 30 bytes

Recursive.

def f(n),do: n>1&&n*(f n-1)||1


Try it online!

# T-SQL, 91 bytes

CREATE FUNCTION dbo.f(@ INT)RETURNS INT AS BEGIN SET @=IIF(@<=1,1,@*dbo.f(@-1))RETURN @ END


Demo

It seems you need to specify a schema (dbo.) in order to make a recursive function :( Perhaps other SQL dialects are shorter.

# ReRegex, 47 bytes

#import math
\b1!/1/(\d+)!/($1-1)!*$1/
#input
!


Defines two regexes;

(\d+)!/($1-1)!*$1/ Looks for a base10 number followed by a !, and replaces it with (n-1)!*n.

\b1!/1/ Replaces any free standing 1!'s with just 1.

The math library then takes care of the subtractions and multiplications. ReRegex will continue attempting its regex operations until it can no-longer modify the text.

The final two lines put the input as n! ready for the operations.

Values greater than 5 work offline, but due to how long they take; do not work on TIO.

Try it online!

# Perl 5-p, 20 bytes

$\*=$_ for++$\..$_}{


Try it online!

• Alternatively, for 20 bytes as well: $;=$_;$_*=$;while--$ ;-) – Dada Aug 25, 2020 at 15:13 • Nice to see you back around @Dada! Aug 25, 2020 at 15:15 • $_*="@F"while--$F too (with -a)... there must be something shorter! Aug 25, 2020 at 15:17 • Oh, those don't work with 0 :( Aug 25, 2020 at 15:29 • Indeed, I didn't noticed that :x – Dada Aug 25, 2020 at 15:32 # Assembly (MIPS, SPIM), 108 bytes, 6*10 = 60 assembled bytes main:li$v0,5
syscall
li $a0,1 beqz$v0,e
f:mul $a0,$a0,$v0 sub$v0,$v0,1 ble$v0,0,e
b f
e:li $v0,1 syscall  Try it online! ## Explanation main: li$v0, 5                  # set syscall code 5
syscall                    # Read an integer into v0
li $a0, 1 # register a0 = 1 beqz$v0, end              # Handle $v0 = 0 case fact: # Main procedure: mul$a0, $a0,$v0      #     a0 = a0 * v0
sub $v0,$v0, 1        #     v0 = v0 - 1
ble $v0, 0, end # If v0 <= 0, jump to end b fact # Jump back to the start of the procedure end: # After-process: li$v0, 1              #     Set sycall code 1
syscall                #     Output the number stored in a0

• @640KB Sorry for the late response, it's fixed now.
– user96495
Aug 26, 2020 at 1:17

# Muriel, 128 bytes

C:"\";@%(B+\");B:\\\"\"+B+\"*\"+$a+\"\\\";a:\"+$(a-1)+\";C:\\\"\"+|C+C),(a>0)*(&B+2),a*999+&B+2";@"B:\".$(1\";a:"+~+";C:\""+|C+C  Try it online! Moving another answer from the previous challenge, this time because the answer uses an eval function... in a language where that's the only way to loop. This is a difficult for a number of reasons. First is Muriel itself, where the only way to do loops is to create a quine and eval it, passing a condition into the code. Next is that large numbers lose precision over time (so the output for $$\125!\$$ is 1.88267717688893e+209), but the program can't handle that format inside the program itself, so you can't pass large numbers to the next iteration of code. The last problem is that numbers will eventually be so large, the program just renders them as Inf, but thankfully that's far beyond $$\125!\$$, so we don't have to worry about that. ### Explanation: The first iteration doesn't have to be a complete quine, but can take shortcuts in constructing the actual loop. C:"\";@%(B+\");B:\\\"\"+B+\"*\"+$a+\"\\\";a:\"+$(a-1)+\";C:\\\"\"+|C+C),(a>0)*(&B+2),a*999+&B+2";  This creates an string version of the loop. This string persists across all iterations of the loop. @ # Evaluate the next strings as a new program "B:\".$(1\";       # Initialise B as the string ".$(1" a:"+~ # Initialise a as the inputted number +"C:\""+|C # Initialise C as the persistent string C +C # And add the executing part of the program  The resulting program with input 125 looks like (newlines added for clarity) B:".$(1";
a:125;
C:"\";@%(B+\");B:\\\"\"+B+\"*\"+$a+\"\\\";a:\"+$(a-1)+\";C:\\\"\"+|C+C),(a>0)*(&B+2),a*999+&B+2";
@%(B+");B:\""+B+"*"+$a+"\";a:"+$(a-1)+";C:\""+|C+C),(a>0)*(&B+2),a*999+&B+2


The eval then executes

@                   # Evaluate
%(     ...     ),(a>0)*(&B+2),a*999+&B+2   # The substring
B+");                                    # If a is 0, evaluate B
# Otherwise
B:\""+B+"*"+$a+"\"; # Concatonate "*a" to the end of B a:"+$(a-1)+";                            # Decrement a
C:\""+|C                                 # Set C to C
+C                                       # And add the executing part of the program


Eventually, a will reach 0, and B will be evaluated. B will look like:

.                         # Print
$( ... ) # The string form of 1*125*124*123*...*1 # The factorial  # COW, 150 bytes oomMOOMOoMMMmoOmoOmoOMMMMMMMoOmOomOomOoMOOmoOMMMmoOmoOMMMOOOmOoMMMmOoMOOmoOMMMMOOmoOMoOmOoMOomooMMMmOoMOomoomOoMOoMMMmoomoOmoOmoOOOMOOOMOomOOmooMoOOOM  Try it online! ### Commented Four memory blocks are used. Block 1 stores a persistent counter. Blocks 2 and 3 store the temporary loop variables used for multiplication (by repeated addition). Block 4 stores the result. oom # read input into Block 1 MOO # if input is not 0 MOoMMM # decrement and copy moOmoOmoOMMMMMMMoOmOomOomOo # paste and increment to initialise Block 4 MOO # Loop 1: from Block 1 value down to 1 moOMMM # set Block 2 to Block 1 value moOmoOMMMOOOmOoMMM # set Block 3 to Block 4 value and zero Block 4 mOoMOO # Loop 2: from Block 2 value down to 1 moOMMMMOO # Loop 3: as many times as Block 3 value moOMoO # increment Block 4 mOoMOomooMMM # end Loop 3 mOoMOomoo # end Loop 2 mOoMOoMMMmoo # end Loop 1 moOmoOmoOOOM # print Block 4 value OOOMOomOO # exit moo # (only get here if input is 0) MoOOOM # print 1  # Scala 2.12, 14 bytes 1 to _ product  This is a function expression, where the underscore is the parameter. 1 to _ creates a range object, and product calculates the product of all numbers. • May I ask why it's Scala 2.12 specifically? It looks like that code should work in other versions too. – user Sep 5, 2020 at 20:26 • @user In Scala 2.13, you get an error mesage: error: postfix operator product needs to be enabled by making the implicit value scala.language.postfixOps visible. It should work in older versions, though. Sep 7, 2020 at 7:54 • You can also add the compiler flag -language:postfixOps, though. That’s not part of the byte count, right? – user Sep 7, 2020 at 11:22 • @user I think the common practice is to count compiler flags codegolf.meta.stackexchange.com/q/19. Sep 8, 2020 at 9:53 • Oh, that’s too bad. – user Sep 9, 2020 at 0:12 # Forth (gforth), 30 bytes : f 1 swap 0 ?do i 1+ * loop ;  Try it online! ### Code Explanation : f \ start a new word definition 1 swap 0 \ create accumulator and set up loop parameters ?do \ start a conditional counted loop from 0 to n i 1+ * \ multiply accumulator by loop index + 1 loop \ end counted loop ; \ end word definition  • 28 bytes using a backward loop. Nov 2, 2020 at 0:50 # F#, 26 bytes, by Laikoni fun x->List.fold(*)1[1..x]  Try it online! # F#, 35 bytes let rec f=function|0->1|x->x*f(x-1)  Try it online! • 26 bytes: fun x->List.fold(*)1[1..x] Aug 28, 2020 at 13:03 • Very nice :) Why don't you post it yourself? Until then, I've updated my answer. Aug 29, 2020 at 17:53 ## Setanta, 4544 43 bytes gniomh F(n){ma n<2 toradh 1toradh n*F(n-1)}  Try it here! # Arn, 2 bytes ↓;  Try it! Unpacked: .fact. Passes STDIN (_) into the factorial function via the . infix ## 3 byte solution: A→.  Unpacked: *\~  \ Fold with * Multiplication ~ 1-range _ Variable initialized to STDIN; implied  • There can't be shorter answer. Jan 16 at 8:16 # Flurry-nii, 14 bytes {}{<({})[]>}{}  Try it online! Takes single number from the stack and prints its factorial from the return value. The online interpreter implements certain arithmetic shortcuts, so it computes and prints 125! in an instant. ### How it works Iterate through 1 to n using the stack height and multiply all of them to the starting value of 1. // n is the only content of the stack at program start // 1 is popped from empty stack main = pop push-mul pop = n push-mul 1 // height yields 1 to n, since it is called after a push // <a b> = a * b (where a, b are Church numerals) push-mul = \x. <(push x) height>  # Labyrinth, 16 bytes ?+1#* (: (; @!;  Try it online! Utilizes two loops, one to duplicate and decrement the input until zero, then one to multiply all the items on the stack. # Husk, 1 byte Π  Try it online! • OMG only one byte... Jan 16 at 8:17 • it's nothing special. The answers which have more bytes are better by a large margin. Jan 17 at 14:16 # ARM Thumb-2, 12 bytes 2101 b110 4341 3801 d1fc 4770  Commented assembly:  .syntax unified .arch armv6t2 .thumb .globl factorial .thumb_func // input: r0 // output: r1 factorial: // accumulator starts at 1 movs r1, #1 // skip to end if r0 is zero cbz r0, .Lend .Lloop: // r1 *= r0 muls r1, r0 // while (--r0) subs r0, #1 bne .Lloop .Lend: // return bx lr  Standard iterative approach. Takes a 32-bit integer in r0, returns a 32-bit integer in r1. # ARM Thumb-2, 20 bytes 2201 2300 b128 fba2 2100 fb03 1300 3801 d1f9 4770  Commented assembly:  .globl factorial64 .thumb_func // input: r0 // output: {r2, r3} factorial64: // accumulator starts at 1 movs r2, #1 movs r3, #0 // skip to end if r0 is zero cbz r0, .Lend64 .Lloop64: // {r2, r3} *= r0 // tmp = (u64)r2 * r0 umull r2, r1, r0, r2 // {r2, r3} = tmp + (r3 * r0 << 32) mla r3, r3, r0, r1 // while (--r0) subs r0, #1 bne .Lloop64 .Lend64: // return bx lr  This version uses 64-bit arithmetic, at the cost of 8 bytes. It is only 2 more instructions, but two of those instructions are now wide instructions. 😭 Takes a 32-bit integer in r0 and returns a 64-bit integer in {r2, r3} (easy to forward to printf) • OMG, you beat x86-16?! – user99151 Feb 11, 2021 at 7:07 # Assembly (MIPS, SPIM), 78 bytes, 6*9 = 54 assembled bytes main:li$2,5
syscall
li$4,1 f:beqz$2,g
mul$4,$4,$2 sub$2,1
b f
g:li$2,1 syscall  Try it online! This is a significant optimization of this answer, but the account was deleted. Specifically, this makes the following changes: • It compares once at the top of the loop, using an unconditional branch at the bottom • It uses the numerical register names which are shorter • It removes spaces between mnemonics, as SPIM accepts this • It removes the second operand from sub Otherwise, the logic is identical. # Phooey, 15 bytes =>&.[@<*>-1]<$i


Try it online!

=>&.[@<*>-1]<$i # stack tape = # (0) >a 0 acc = 1 > # (0) a >0 move left &. # (0) a >n read int [ ] # (0) a >n loop while n != 0 @ # n a >n push n <*> # (0) a*n >n multiply acc by n (popping from stack) -1 # (0) a*n >n-1 subtract 1 from n < # (0) >res 0 go right to the result$i #   (0)  >res 0      print as integer


Since Phooey uses int64_t, this supports up to 20.

# Factor + math.factorials, 6 bytes

[ n! ]


Try it online!

Thanks to @Bubbler for -9 bytes

# Factor + math.factorials, 15 bytes

[ factorial . ]


Try it online!

• There's n! which is a synonym of factorial, and you don't need to print the result, so simply n! is a valid built-in submission. (You don't need to wrap it in a quotation, as a built-in submission is scored by its name.) Mar 31, 2021 at 3:34

# jq, 10 bytes

.+1|tgamma


Uses the gamma function Γ(n) = (n - 1)!

Try it online!

• I think |ceil is not necessary since floating point imprecision is allowed. Sep 2, 2021 at 23:50

#1]*
\aa?
(\&;
a ?


Try it online!

Golfed version by Jo King.

A program without @ starts at the top-left corner. The main difference with my version is that a is decremented under the second branch, not first:

  ?
]
a ?
&;(
a


? @
]*#1
)(|a
a?\
&;a\


Try it online!

Solved as part of LYAL 2021-09-29.

### How it works

Cascade programs start the execution at the entry point @.

? @   The main program prints (#) the result of the huge loop
#   starting at ?
|
\
\

?    (grid rotated once for clarity)
]    On entry, the if-clause is run:
a (   Push to the stack "a" the decrement of...
?   If EOF, the top value of "a", otherwise the input from stdin
&;a

?    If the above is not positive, return 1;
1 *   Otherwise return (increment of a) times
) |  the next invocation of the main loop
a \
\


# Python 3, 25 bytes

f=lambda n:n<1or n*f(n-1)


Try it online!

• This does not work. This outputs True for 0 when it should output 1. You can fix this by replacing n<1 with +(n<1) to cast it to an integer. You can also remove f= to save 2 bytes. Aug 24 at 9:42
• @TheEmptyStringPhotographer thanks for your feedback! In Python, True == 1, so it is generally accepted to leave it at that. Also, the f= is required because the lambda is recursive. Aug 31 at 13:25