57
\$\begingroup\$

Task

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.

\$\endgroup\$

154 Answers 154

1
\$\begingroup\$

Wren, 36 bytes

var F=Fn.new{|n|n<1?1:n*F.call(n-1)}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Cubix, 24 bytes

I:;.^!^u.>($.sr*u..;uO;@

Try it online!

And here's a link to the Cubix online interpreter you can run in "debug" mode if you want to see the IP as it moves around the cube the code on.

http://ethproductions.github.io/cubix/?code=STo7Ll4hXnUuPigkLnNyKnUuLjt1TztA&input=NgoK&speed=6

I find it hard to explain code in this language, since the directions the code takes a confusing (since it's running through code wrapped around a cube). The size of the cube used varies based on the length of the code. In this case each side has 4 characters.

Here goes...

I:;.^!^u.>($.sr*u..;uO;@
    ^                    - code starts here, change IP to "up"
I:                       - read a number from STDIN, duplicate it on stack
         >               - change IP to "right" (start of loop)
          (              - decrement top of stack
           $             - skip the next instruction
    ^                    - SKIPPED
     !                   - if top of stack not 0, skip next instruction
      ^                  - TRUE, change IP to "up" (exit path 0)
       u                 - FALSE, IP does a "u turn"
               *         - multiple top two entries on the stack
              r          - rotate top three stack entries twice
             s           - flip the top two entries on the stack
                   ;     - delete the top of stack
                u        - IP does a "u turn", (end of loop)
  ;                      - exit path 1, delete top of stack
I                        - exit path 2, read STDIN as number onto stack
           $             - exit path 3, skip next instruction
                   ;     - exit path 4, SKIPPED
                      ;  - exit path 5, delete top of stack
                    u    - exit path 6, IP makes a "u turn"
                     O   - exit path 7, output top of stack as a number
                       @ - exit path 8, halt program
\$\endgroup\$
1
\$\begingroup\$

Python 3, 31 bytes

f=lambda n:n>1 and n*f(n-1)or 1

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$
    – rydwolf
    Commented Nov 15, 2021 at 15:54
  • 1
    \$\begingroup\$ Make sure to check out our tips for golfing in Python to see if there are any ways to golf your program. I don't have much experience golfing Python myself, but I did notice that you can remove a space for 30 bytes. \$\endgroup\$ Commented Nov 15, 2021 at 16:01
1
\$\begingroup\$

Knight, 28 bytes

;;;=xP=y 1W<0=x-x 1=y*y+1xOy

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Knight, 26 bytes

;=yT;=x+0P;W=x-xT=y*+xTyOy

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 24 bytes: ;=x+=y 1P;W=x-xT=y*x yOy \$\endgroup\$
    – Aiden Chow
    Commented Aug 14, 2022 at 23:21
1
\$\begingroup\$

StackCell, 14 bytes

Uses this input format and this output format

The below code uses the Unicode control character glyphs [U+24XX] to represent ASCII unprintable control characters embedded in the source code

[the input is implicitly pushed to the stack before the program begins]

{'␁}[}*'␁}-{}]

[the output is left as the sole value on the stack after the program ends]

For standard I/O (i.e. stdin and stdout), the following snippet can be used to place the input on the stack (for 21 bytes):

'0'␁['0x-x'
*+@:'
-]`

and for output (26 bytes):

:[:'
x%'0+{X}X'
x/:]X:[:;]

For the complete program using stdin/stdout only, that means a total of 61 bytes:

'0'␁['0x-x'
*+@:'
-]`{'␁}[}*'␁}-{}]:[:'
x%'0+{X}X'
x/:]X:[;:]
\$\endgroup\$
1
\$\begingroup\$

Carbon, 53 bytes

fn f(x:i32)->i32{return if(x==0)then 1else x*f(x-1);}

Try it Online!

Here is a full program for testing at the above site:

package c api;

fn f(x:i32)->i32{return if(x==0)then 1else x*f(x-1);}

fn Main() -> i32 {
  return f(5);
}
\$\endgroup\$
1
\$\begingroup\$

Haskell, 17 characters

f n=product[1..n]

Bonus reference: "The Evolution of a Haskell Programmer" by Fritz Ruehr

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Clojure, 38 bytes

(defn f[n](apply *' (range 2(inc n))))

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 36 \$\endgroup\$
    – ASCII-only
    Commented May 7, 2023 at 4:18
1
\$\begingroup\$

Rattle, 14 bytes

|F0:s[1F]-F0*~

Try it Online!

There's already a Rattle answer here by me but this approach is completely different. Not only does this answer use the shiny new interpreter, but it takes advantage of the fact that recursion was recently implemented in Rattle!

Explanation

|                parses the user's input
 F0              calls local function 0
   :             (separator between the main method and local function 0)
    s            save the current value to local memory slot 0 (local to only this instance of F0)
     [1 ]        if the value is equal to 1, then:
       F         return (returns 1)
         -       subtract 1 from the current value
          F0     recursively call function 0 with the current value as a parameter
            *~   multiply the result of function 0 by the value stored in local memory
                 (the result of the multiplication is returned)

Rattle is able to process factorials up to 170! with no loss in precision.

\$\endgroup\$
1
\$\begingroup\$

Thunno, \$ 1 \log_{256}(96) \approx \$ 0.82 bytes

F

Attempt This Online! or verify \$0!\$ to \$10!\$.

Builtins FTW.

\$\endgroup\$
1
\$\begingroup\$

Pyt, 1 byte

!

Try it online!

Builtins FTW.

\$\endgroup\$
1
\$\begingroup\$

Arturo, 9 bytes

factorial

Try it

Builtin

Arturo, 18 12 bytes

$=>[∏1..&]

Try it

Non-builtin

\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 9 bytes

factorial

Try it online!

12 bytes

~x=*(1:x...)

Try it online!

~x=prod(1:x)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

vemf, 1 byte

!

Falls back to \$\Gamma\left(\alpha+1\right)\$ if \$\alpha\notin\mathbb Z\$

In the online interpreter this works (returns values other than /0/-0/inf) for \$-178.9999999999999\le\alpha\le170.6243769563\$ and \$\alpha\notin\mathbb Z^-\$ (set of negative integers)

\$\endgroup\$
1
\$\begingroup\$

minigolf, 6 bytes

1i,n*_

Attempt This Online!

Explanation

1      Push 1
i      Push input
,      Repeat input times ([1..n]):
  n*     Muliply tos by curr. item
_      end repeat

implicit output
\$\endgroup\$
1
\$\begingroup\$

All answers works correctly for 0 only in Firefox

JavaScript, 29 bytes

  • Without recursion
  • Expects Number type
  • Max value is 170. If above outputs Infinity
n=>eval('p=1;while(n)p*=n--')

f=n=>eval('p=1;while(n)p*=n--')

;[
  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
  170, // 7.257415615308004e+306
  171, // Infinity
].forEach(n=>document.write(n + ' - ' + f(n), '<br>'))

JavaScript, 30 bytes

  • Without recursion
  • Expects BigInt type
  • In theory there is no max value. In practice it depends on implementation
n=>eval('p=1n;while(n)p*=n--')

f=n=>eval('p=1n;while(n)p*=n--')

;[
  0n, // 1
  1n, // 1
  2n, // 2
  3n, // 6
  4n, // 24
  5n, // 120
  6n, // 720
  7n, // 5040
  8n, // 40320
  9n, // 362880
  10n, // 3628800
  11n, // 39916800
  12n, // 479001600
  170n, // 7257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000
  171n, // 1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000
].forEach(n=>document.write(n + ' - ' + f(n), '<br>'))

JavaScript, 33 bytes

  • Without recursion
  • Expects Number or BigInt type
  • Max value for type Number is 170. In theory there is no max value for type BigInt
n=>eval('p=++n/n;while(--n)p*=n')

f=n=>eval('p=++n/n;while(--n)p*=n')

;[
  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
  170, // 7.257415615308004e+306
  171, // Infinity
  0n, // 1
  1n, // 1
  2n, // 2
  3n, // 6
  4n, // 24
  5n, // 120
  6n, // 720
  7n, // 5040
  8n, // 40320
  9n, // 362880
  10n, // 3628800
  11n, // 39916800
  12n, // 479001600
  170n, // 7257415615307998967396728211129263114716991681296451376543577798900561843401706157852350749242617459511490991237838520776666022565442753025328900773207510902400430280058295603966612599658257104398558294257568966313439612262571094946806711205568880457193340212661452800000000000000000000000000000000000000000
  171n, // 1241018070217667823424840524103103992616605577501693185388951803611996075221691752992751978120487585576464959501670387052809889858690710767331242032218484364310473577889968548278290754541561964852153468318044293239598173696899657235903947616152278558180061176365108428800000000000000000000000000000000000000000
].forEach(n=>document.write(n + ' (' + typeof n + ') - ' + f(n), '<br>'))

\$\endgroup\$
6
  • \$\begingroup\$ Fails for input 0 \$\endgroup\$
    – Shaggy
    Commented Mar 7, 2023 at 23:26
  • \$\begingroup\$ @Shaggy I already added 0 as test cases and output is 1 everywhere \$\endgroup\$
    – EzioMercer
    Commented Mar 7, 2023 at 23:29
  • \$\begingroup\$ @EzioMercer What browser did you test this on? I'm on a chromium-based browser and f(0) is returning undefined for all three versions \$\endgroup\$ Commented Jul 14, 2023 at 18:47
  • \$\begingroup\$ @noodleman Firefox 115.0.2 (64-bit) \$\endgroup\$
    – EzioMercer
    Commented Jul 15, 2023 at 18:15
  • 1
    \$\begingroup\$ I get the same f(0) === undefined on Safari on my iPhone. Can you double check that you are getting the expected 1? If you are then you might want to add that it only works on Firefox to your answer. I see why it might return 1 if the result of p=1 is returned, since the result of the while loop would never happen, but it’s probably implementation dependent or a bug \$\endgroup\$ Commented Jul 15, 2023 at 19:52
1
\$\begingroup\$

Itr, 2 bytes:

#P

online interpreter

The product over the range from 1 to the input number

\$\endgroup\$
1
\$\begingroup\$

Gema, 41 characters

f:*=@cmpi{*;0;;1;@mul{@f{@sub{$0;1}};$0}}

Assuming a domain can be considered equivalent of a function.

(Being pure text processing utility, no way to calculate up to 125! to qualify for the old challenge.)

Sample run:

bash-5.2$ gema '*=@f{*};f:*=@cmpn{*;0;;1;@mul{@f{@sub{$0;1}};$0}}' <<< 12
479001600

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Swift, 37 36 bytes

var f={$0<1 ?1:(1...$0).reduce(1,*)}

Self-explanatory. Call it as f(n).

\$\endgroup\$
1
\$\begingroup\$

[Assembly (nasm, x64, Linux)], 103 bytes

4c89c0e84a0000006683f800770366ffc048be0000000000000000b90a00
00004831d2f7f180c23066ffce88166683f80075ed66ffc066bf010048ba
00000000000000004829f20f0549ffc04983f80d7cae5083f801740c66ff
c8e8f2ffffff48f724244159c3

Try it online!

How it works

fact.asm

c:mov rax,r8
call f          ; <---- Call factorial f()
cmp ax,0
ja x
inc ax
x:mov rsi,n     ; <---+
mov ecx,10      ;     |
l:xor rdx,rdx   ;     |
div ecx         ;     | Convert factorial to ASCII
add dl,48       ;     |
dec si          ;     |
mov[rsi],dl     ;     |
cmp ax,0        ; <---+
jnz l
inc ax          ; <---+
mov di,1        ;     |
mov rdx,n+1     ;     | Write factorial to stdout
sub rdx,rsi     ;     |
syscall         ; <---+
inc r8
cmp r8,13       ; <---- Loop [0,12]
jl c
f:push rax      ; <---+ 
cmp eax,1       ;     |
jz e            ;     |
dec ax          ;     | Compute factorial EAX (in/out)
call f          ;     |
mul qword[rsp]  ;     |
e:pop r9        ;     |
ret             ; <---+
section .data
resb 9
n: db 10

Build Commands

nasm -f elf64 fact.asm -o fact.o
ld fact.o -o fact
objcopy --dump-section .text=text.bin fact.o
xxd -p text.bin > text.hex
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Assembly contributions are usually scored in bytes the translated opcodes require, not the source code. nasm ‑felf64 factorial.asm, objdump ‑d a.o ⇒ 6A₁₆ Bytes + 1 Byte = 107₁₀ Bytes. This allows you to extensively comment and explain the source code, too. \$\endgroup\$ Commented Mar 16 at 2:18
1
\$\begingroup\$

Gray Snail, 130 bytes

INPUT n
POP f  1
F
POP  p 
POP  i [n]
M
POP  p _[p][f]
GOTO   [i]
POP  i [i]
GOTO M

POP  f _[p]
POP  n [n]
GOTO F 1 []
OUTPUT [f]

Takes input and produces output in unary (using 1s).

Try it here! (Paste the code, then click Compile Code, then click Execute Program, then enter your input and click Set Input.)

Ungolfed, with comments

INPUT num
"Set factorial = 1"
POP factorial _ 1

fact_loop:

"Multiply factorial by num using loop counter i, storing result in product"
"Set product = empty"
POP _ product _
"Set i = one less than num"
POP _ i [num]

mult_loop:
"Concatenate factorial to product"
POP _ product _[product][factorial]
"If i is empty, exit loop"
GOTO mult_done: "" [i]
"Decrement i"
POP _ i [i]
GOTO mult_loop:

mult_done:
"Set factorial = product"
POP _ factorial _[product]
"Decrement num, storing 1 in x if there was anything there to decrement"
POP x num [num]
"If there was, loop"
GOTO fact_loop: 1 [x]

OUTPUT [factorial]

Astute readers may notice that the outer loop runs one more time than you might expect. Despite the fact that num is zero on this last loop, it's not a problem because my multiplication algorithm doesn't work for multiplying by zero and leaves factorial unchanged.

\$\endgroup\$
1
\$\begingroup\$

sed 4.2.2, 54 bytes

h                                      # copy number to hold space
:                                      # define label ''
x;s/&//;x                              # decrement hold space
G                                      # append hold space to pattern space after newline
s/(&+)\n(&+)/sed 's%\1%\2%'<<<'\1'/e   # multiply two numbers seperated by a newline
t                                      # if a swap happened, branch to ''

Try it online!

honestly surprised no one's done a sed answer here yet. takes input in unary &s. TIO link comes with decimal conversion header and footer for easy verification.

the multiplication is done by using the fact that an & in the regex half of a s/// command matches an & but an & in the replace half means 'the whole match'. so s/&&&/&&/ actually means 'replace &&& with itself twice'; e.g. multiplication by two.

\$\endgroup\$
0
\$\begingroup\$

PPL, 60 bytes

fnf(n){
declarea=1
declares=1
loopn{
a=a*s
s=s+1
}
returna
}

Anybody remember PPL? ;)

Declares a new function f with variables a and s. Loops n times and multiplies a by s each time.

Sadly recursion is not supported with PPL.

\$\endgroup\$
0
\$\begingroup\$

APOL, 24 bytes

⊕(ƒ(-(⧣ 1) *(⋒ -(⋒ ∈))))

Explanation:

⊕(         Sum of list
  ƒ(        List-builder for
    -(      Subtract
      ⧣     Integer input
      1
    )
    *(      Multiply
      ⋒     For iterator (what's being iterated through)
      -(    Subtract
         ⋒  For iterator
         ∈  Loop counter
      )
    )
  )
)
\$\endgroup\$
0
\$\begingroup\$

Python, 34 29 Bytes

x=lambda a:a and a*x(a-1)or 1

lambda is good at shortening code!
-5 from TheThonnu

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Your function us recursive so you need to name it by putting x= in front \$\endgroup\$
    – The Thonnu
    Commented Apr 5, 2023 at 16:23
  • \$\begingroup\$ 29 bytes \$\endgroup\$
    – The Thonnu
    Commented Apr 5, 2023 at 16:24
0
\$\begingroup\$

Fortran (GFortran), 51 42 bytes

We abuse that variables (and functions) beginning with i,j,k,l,m or n are assumed to be (or return) integers, and that all other objects are assumed to be (or return) reals to create this function that generates a list of integers and multiplies them together into a another integer. It breaks at i=13.

function k(i)
k=product((/(j,j=1,i)/))
end

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python, 26 Bytes

import math
math.factorial

Uses the built-in function from the built-in module math.

\$\endgroup\$
0
\$\begingroup\$

Thunno 2, 1 byte

w

Attempt This Online! Built-in.

Thunno 2, 2 bytes

Rp

Attempt This Online! Product of range.

\$\endgroup\$
0
\$\begingroup\$

Desmoslang Assembly, 3 Bytes

I!OT

Explanation: Takes input to Command, adds an exclamation mark for factorial, outputs it, and loops infinitely at the end.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.