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

# Piet + ascii-piet, 24 bytes (4×10=40 codels)

rmttlddqbDlbaltdmu?_ V??


Try Piet online!

Similar to below, but realized that I can remove 1 >. Also, using B2->B1 = I (which is a no-op) gave A2->B2 = D (which safely removes a 0) and a color sharing for 3. Luck based golfing?

# Piet + ascii-piet, 27 bytes (5×11=55 codels)

rmttldqbdTl?dckmvfnnN TuDuu


Try Piet online!

The logic is the same as Parcly Taxel's.

Main loop (A1 -> A10 -> B9 -> B1 -> A1):

D * 2 1 r       Mostly no-op, just pushes [2 1]
I               Take input [2 1 n]; becomes a no-op afterwards
Invariant: [2 prod i]
d 1 -           [2 prod i i-1]
3 1 r d 1 > !   [2 i-1 prod i i<=1]
D               [2 i-1 prod i]; turn right at A2 if n <= 1
* 2 1 r         [2 i-1 prod*i]


After turn right at A2 (A2 -> E2):

x O <halt>      Discard i and print prod


The main trick here is to move the DP+ to the cell A2, and rotate the main loop accordingly. This works because most commands are no-op when there are not enough items on the stack yet.

# TypeScript Type System, 82 bytes

type X<A,B=A>=A extends1${infer R}?B extends1${infer O}?${X<R>}${X<A,O>}:B:1


Try it online!

Quite similar to, but independently derived from noodle man's answer. I also stole their test harness.

This is basically the same as the JavaScript code f = (a, b = a) => a ? b ? f(a, b - 1) + f(a-1) : 0 : 1. The idea here is that we have two accumulators, a and b, where b starts at the value of a. We repeatedly decrement b and add f(a-1) to the total, which results in the factorial of a.

# Uiua, 5 bytes

/×+1⇡


Try it!

    ⇡  # create range [0..input)
+1   # amend it to [1..input]
/×     # reduce by multiplication


# Keg, -hr, 4 bytes

Ï_∑*


Try it online!

• Shouldn't that be 7 bytes, due to the use of -hr? Commented 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. Commented 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? Commented 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 Commented 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
Commented 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. Commented 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. Commented 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


# 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 Commented Aug 25, 2020 at 15:13 • Nice to see you back around @Dada! Commented Aug 25, 2020 at 15:15 • $_*="@F"while--$F[0] too (with -a)... there must be something shorter! Commented Aug 25, 2020 at 15:17 • Oh, those don't work with 0 :( Commented Aug 25, 2020 at 15:29 • Indeed, I didn't noticed that :x – Dada Commented Aug 25, 2020 at 15:32 # 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
Commented 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. Commented 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
Commented Sep 7, 2020 at 11:22
• @user I think the common practice is to count compiler flags codegolf.meta.stackexchange.com/q/19. Commented Sep 8, 2020 at 9:53
– user
Commented 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. Commented 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] Commented Aug 28, 2020 at 13:03
• Very nice :) Why don't you post it yourself? Until then, I've updated my answer. Commented 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. Commented Jan 16, 2023 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... Commented Jan 16, 2023 at 8:17
• it's nothing special. The answers which have more bytes are better by a large margin. Commented Jan 17, 2023 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
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
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
Commented 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.) Commented 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. Commented 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 \
\