title: Reverse factorial function

text:
# Question
Title: Reverse factorial function
Given a number n, find x such that x! = n, where both x and n are positive integers. Assume the input n will always be the factorial of a positive integer, so something like n=23 will not be given as input.

Examples: `n=1 -> x=1` (0 is not a positive integer), `n=24 -> x=4`

Shortest code wins.

# Answer
# Python 2, 28 bytes (input \\$\leq2^{64}\\$)

```
lambda n:len(`n**8L`)**.6//1

```

Try it online!

This works on inputs up to \\$20! =2432902008176640000 \\$ that fall within 64-bit integers.

This uses an approximate fit inspired by Stirling's approximation. However, the constants were estimated manually and it breaks down for larger values. With Python not having a built-in `log`, we use the digit-length for \\$n^8\\$ as an approximation for \\$c\cdot\log(n)\\$. Actually, we use the long value `8L` so that the string representations uniformly end in `L` for "long", which adds one to the lengths.

From there, raising the value to the power of \\$0.6\\$ and taking the integer part is apparently sufficient to give the correct output up to \\$20!\\$. It's lucky that the `0.6` is `0.60`, since we'd usually need another digit of precision.
> 14 votes

# Answer
# APL (Dyalog Extended), 2 bytes

```
¯!

```

Try it online!

Exactly the same as non-extended APL answer but just with the shorter syntax.

`!` is factorial function, `¯` prefix gives the inverse function of it.
> 11 votes

# Answer
# Python 2, 32 bytes

```
f=lambda n,k=2:n and-~f(n/k,k+1)

```

Try it online!
> 7 votes

# Answer
# Jelly, 3 bytes

```
!€i

```

Try it online!

```
  i    The first index (from 1) of the input in
!€     the factorials of every integer from 1 to the input.

```
> 7 votes

# Answer
# Ruby, 27 bytes

```
->n,x=0{2>n/=x+=1or redo;x}

```

Try it online!

Increment the divisor `x` (initially 0), divide `n` (initially the input value) by `x` and store the result as `n`, repeat until `n=1`. Then `x` is the desired output.
> 6 votes

# Answer
# Brachylog, 3 bytes

```
ℕ₁ḟ

```

Try it online!

A predicate which takes input reversed (i.e., the input is given through the output variable, and the output is given through the input variable). Brachylog more-or-less has a builtin for exactly this, aside from needing to apply the additional constraint of having to output a positive integer, where I say more or less because it's also just the factorial builtin and it works in both directions.
> 5 votes

# Answer
# C (gcc), <sup>~~33~~ ~~29~~</sup> 28 bytes

Saved a byte thanks to ceilingcat!!!

```
x;f(n){for(x=0;++x-n;n/=x);}

```

Try it online!
> 5 votes

# Answer
# , 4 bytes

```
!inv

```

Try it online!

Inverse of factorial.
> 5 votes

# Answer
# Wolfram Language (Mathematica), 20 bytes

Mathematica has the inverse function of the factorial! It's called `InverseFunction@Factorial`. I used a pure (Mathematica for "anonymous") function that returns the factorial by using the exclamation mark, as it's shorter.

```
InverseFunction[#!&]

```

Try it online!
> 4 votes

# Answer
# 05AB1E, 4 bytes

```
Å!g<

```

Try it online!
> 4 votes

# Answer
# Retina 0.8.2, 39 bytes

```
.+
1 $&$*
+`^(1+) (1\1)+$
1$1 $#2$*
\G1

```

Try it online! Link includes test cases. Actually calculates the largest factorial that divides `n`. Explanation:

```
.+
1 $&$*

```

Set `x` to `1` and convert `n` to unary.

```
^(1+) (1\1)+$
1$1 $#2$*

```

If `x+1` divides `n`, then increment `x` and divide `n` by the incremented `x`.

```
+`

```

Repeat the above until `x+1` does not divide `n` (hopefully because `n=1` at this point).

```
\G1

```

Convert `x` to decimal.
> 4 votes

# Answer
# , ~~29~~ 28 bytes (input ≤170!)

```
match(scan(),cumprod(1:170))

```

Try it online!

Input is limited to 170!, which is the largest factorial that can be handled as a floating-point number by R; in any case, at larger values, there is a risk that truncated digits in the internal floating-point encoding will affect the output. Obviously the second issue will be fixed when run on an imaginary 'unlimited-precision' R implementation, but the input limitation will always be there (or, with slight modification, a limitation to ≤999!). So...

# , ~~38~~ 34 bytes

```
n=scan();while(n>(T=T*(F=F+1)))n;F

```

Try it online!

*Edit: -4 bytes thanks to tip from Giuseppe*

This version is still subject to the precision limitations of the R implementation, but could (in principle) be run with unlimited input.

Edit: Obviously the ~~large~~ increase in program length to achieve the unimplemented ability to run on unlimited input is rather unsatisfying, so...

# , ~~30~~ 29 bytes

```
match(n<-scan(),cumprod(1:n))

```

Try it online!

Only one-byte longer than the input-limited attempt. Unfortunately, on all current R implementations, it is rather slow and is likely to crash with anything but small input values, but - in the words of Osgood Fielding III - 'well, nobody's perfect'
> 4 votes

# Answer
# Pyth, 4 bytes

```
.I*F

```

Try it online!

### Explanation

```
.I*F
.I    : Inverse function of
  *F  : factorial

```

---

# Pyth, ~~6~~ 5 bytes

```
fqQ*F

```

Try it online!

-1 byte thanks to @FryAmTheEggman

### Explanation

```
fqQ*F
f      : First positive integer value where
  Q    : input
 q     : is equal to
   *F  : factorial of value

```
> 4 votes

# Answer
# dc, 22 bytes

```
0?[r1+d_3R/d1<F]dsFx/p

```

Try it online!

Input on stdin, and output on stdout.

Works for arbitrarily large inputs (up to the available memory). The TIO sample run is for `200!`.

**How it works**

The description below presumes that the input is a factorial (so all the divisions have no remainder).

```
0
?     # Stack is now (top of stack on right):
      #    x n
      #    where x = 0 and n is the input number.
[     # Define a macro (to be used as a loop).
      #    If we write the stack as
      #    x n
      #    then we assert the following loop invariant at this point in the cycle:
      #       n = input / x!
  r      # Swap.        Stack: n x
  1+     # Increment.          n x+1
  d      # Duplicate.          n x+1 x+1
  _3R    # Rotate 3 steps clockwise.
         #                     x+1 n x+1
  /      # Divide.             x+1 n/(x+1)
  d1<F   # If n/(x+1) > 1, go back to the beginning of the loop.
         #    Note that the loop invariant is once again true,
         #    as it should be at the beginning of a new loop iteration.
]dsFx # End macro, call it F, and execute it.
      # When we leave the loop, we know the following, where 'x n' is the current stack:
      #   (1) the loop termination condition was false, so n <= 1,
      #       and we must actually have
      #       n = 1
      #       because the input was a factorial;
      #   and
      #   (2) the loop invariant is true, so n = input / x!
      #
      #   It follows that x! = the input, and the stack is now:
      #                              x 1
/     # Divide (to pop the 1).       x
p     # Print top of stack.

```
> 4 votes

# Answer
# \[MATLAB/Octave\], ~~35 34~~ 26 bytes

```
f=@(n)nnz(cumprod(1:n)<=n)

```

Thanks @David for the feedback! I added the f= to have way to call the function for 2 bytes.
> 4 votes

# Answer
# Clojure, 73 bytes

```
(defn f[n](loop[x 1](if(= n(reduce *'(range 2(inc x))))x(recur(+ x 1)))))

```

Ungolfed:

```
(defn find-fact [n]  ; n = x!. Find x
  (loop [x 1]
    (if (= n (reduce *' (range 2 (inc x))))
      x
      (recur (+ x 1)))))

```

Tested out to 1234!, which is the 3281 digit number `51084981466469576881306176261004598750272741624636207875758364885679783886389114119904367398214909451616865959797190085595957216060201081790863562740711392408402606162284424347926444168293770306459877429620549980121621880068812119922825565603750036793657428476498577316887890689284884464423522469162924654419945496940052746066950867784084753581540148194316888303839694860870357008235525028115281402379270279446743097868896180567901452872031734195056432576568754346528258569883526859826727735838654082246721751819658052692396270611348013013786739320229706009940781025586038809493013992111030432473321532228589636150722621360366978607484692870955691740723349227220367512994355146567475980006373400215826077949494335370591623671142026957923937669224771617167959359650439966392673073180139376563073706562200771241291710828132078928672693377605280698340976512622686207175259108984253979970269330591951400265868944014001740606398220709859461709972092316953639707607509036387468655214963966625322700932867195641466506305265122238332824677892386098873045477946570475614470735681011537762930068333229753461311175690053190276217215938122229254011663319535668562288276814566536254139944327446923749675156838399258655227114181067181300031191298489076680172983118121156086627360397334232174932132686080901569496392129263706595509472541921027039947595787992209537069031379517112985804276412719491334730247762876260753560199012424360211862466047511184797159731714330368251192307852167757615200611669009575630075581632200897019110165738489288234845801413542090086926381756642228872729319587724120647133695447658709466047131787467521648967375146176025775545958018149895570817463048968329692812003996105944812538484291689075721849889797647554854834050132592317503861422078077932841396250772305892378304960421024845815047928229669342818218960243579473180986996883486164613586224677782405363675732940386436560159992961462550218529921214223556288943276860000631422449845365510986932611414112386178573447134236164502410346254516421812825350152383907925299199371093902393126317590337340371199288380603694517035662665827287352023563128756402516081749705325705196477769315311164029733067419282135214232605607889159739038923579732630816548135472123812968829466513428484683760888731900685205308016495533252055718190142644320009683032677163609744614629730631454898167462966265387871725580083514565623719270635683662268663333999029883429331462872848995229714115709023973771126468913873648061531223428749576267079084534656923514931496743842559669386638509884709307166187205161445819828263679270112614012378542273837296427044021252077863706963514486218183806491868791174785424506337810550453063897866281127060200866754011181906809870372032953354528699094096145120997842075109057859226120844176454175393781254004382091350994101959406590175402086698874583611581937347003423449521223245166665792257252160462357733000925232292157683100179557359793926298007588370474068230320921987459976042606283566005158202572800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000`
> 4 votes

# Answer
**SWI-Prolog, 50 bytes**

```
:-[library(clpfd)].
c(F,N):-F#=1,N#=1;c(F//N,N-1).

```

Try it online!

`c(F,N)` recursively defines factorials, either F = N = 1, or F/N is (N-1)!. To save bytes we used integer division, so the answer is only valid if F is actually a factorial. Prolog infers the correct value for N if not specified.

Algorithm should work for all inputs, although it isn't particularly fast. Tested up to 128!.
> 4 votes

# Answer
# Rust, ~~41~~ 32 bytes

```
|mut y|(1..).find(|x|{y/=x;y<2})

```

Try it online!

The `.unwrap()` was unnecessary (Meta post), saving 9 bytes
> 4 votes

# Answer
# Factor \+ `math.factorials`, ~~41~~ 32 bytes

Saved 9 bytes thanks to @Bubbler!

```
[ dup [1,b] [ n! = ] with find ]

```

Try it online!

# Factor, ~~50~~ 34 bytes

Saved 16 bytes thanks to @Bubbler!

```
[ 1 over [1,b] [ * 2dup = ] find ]

```

Try it online!

There's probably a better idiom for this, but I can't find it right now.
> 4 votes

# Answer
# Husk, 4 bytes

```
€mΠN

```

Try it online!

```
€     the index of implicit input in ...
 mΠ   ... map factorial over ...
   N  ... the natural numbers

```
> 3 votes

# Answer
# Erlang (escript), 45 bytes

Quite similar with ovs's Python answer.

```
f(1.0,Y)->Y;f(X,Y)->f(X/Y,Y+1).
f(X)->f(X,2).

```

Try it online!
> 3 votes

# Answer
# COW, 108 bytes

```
oomMOoMOOMoOMMMOOOmoOMMMmoOMoOmOoMOOmoOMMMmoOMMMMOOMOomOomOoMOomoOmoOmoomOomOomOoMoOmoOmoomOoMOomoomoOmoOOOM

```

Try it online!

## Explanation

```
moo ]    mOo <    MOo -    OOO *    OOM o
MOO [    moO >    MoO +    MMM =    oom ^

[0]: n/(i!)     [1]: n/((i-1)!)     [2]: i     [3]: i_temp

^-                   ;  Read i in [0] and decrement it
[                    ;  Loop while [0] is non zero ( n/(i!)-1 is checked )
    +=*>=            ;      [0] is incremented and cut/copied in [1]
    >+<              ;      [2] is incremented
    [                ;      Loop while [1] is non zero ( repeated subtraction begins )
        >=>=         ;          Copy [2] in [3]
        [            ;          Loop while [3] is non zero
            -<<->>   ;              [3] and [1] are decremented ( [1] is guaranteed to be divisible by [3] )
        ]            ;
        <<<+>        ;          [0] is incremented
    ]                ;      [0] is now the product of the biggest x-i factor of n
    <-               ;  [0] is decremented so iff [0] = 1 the loop ends
]                    ;
>>o                  ;  Print [2] x

```
> 3 votes

# Answer
# Excel, 29 bytes

```
=MATCH(A1,FACT(ROW(1:170)),0)

```
> 3 votes

# Answer
# APL (Dyalog Unicode), 4 bytes

I was just copying Bubbler's solution. I didn't write it, so it's community wiki.

```
!⍣¯1

```

Try it online!

## Explanation

```
 ⍣¯1 The inverse of this function:
!    Factorial function

```
> 2 votes

# Answer
# Charcoal, 17 bytes

```
Ｎθ⊞υ¹Ｗ‹Πυθ⊞υＬυＩ⌈υ

```

Try it online! Link is to verbose version of code. Actually calculates the lowest factorial not less than `n`. Explanation:

```
Ｎθ

```

Input `n`.

```
⊞υ¹

```

Push `1` to the predefined empty list.

```
Ｗ‹Πυθ

```

Repeat while the product of the list is less than `n`.

```
⊞υＬυ

```

Push the length of the list to the list. (This means that the list has an extra `1` in it, but conveniently that doesn't affect the product.)

```
Ｉ⌈υ

```

Output the largest element of the list (which is also the last element; either operation works.)
> 2 votes

# Answer
# SimpleTemplate, 72 bytes

Not exactly the smallest, but works.

Uses a naive approach to calculate the factorial up to the chosen number, returning the value if found.

```
{@setf 1}{@forfrom 1toargv.0}{@set*f f,_}{@iff is equalargv.0}{@return_}

```

Notice that this is a *REAL* `{@return}`! The compiler method will give you this value.
To be used as a function, simply wrap it in `{@fn invert_factorial} [...] {@/}`.

---

**Ungolfed version**

This should be easy to understand

```
{@set factorial 1}
{@for i from 1 to argv.0}
    {@set* factorial factorial, i}
    {@if factorial is equal to argv.0}
        {@return i}
    {@/}
{@/}

```

The line `{@set* factorial factorial, i}` simply stores ,in `factorial`, the result of multiplying the value `factorial` to `i`.

---

You can test this on:
http://sandbox.onlinephpfunctions.com/code/61cc7101a868a71d0a7a85cdde57f946bcb2586e
> 2 votes

# Answer
# Rust, 57 bytes

```
fn f(mut y:i32)->i32{let mut x=1; while y>1{x+=1;y/=x;}x}

```

Try it online!
> 2 votes

# Answer
# , ~~56~~ 52 bytes

```
function(n){while(n>(T=T*(F=F+gmp::as.bigz(1))))1;F}

```

Try it online!

Thanks to Dominic van Essen for the golfs and bug catch!

Takes input as a string.
> 2 votes

# Answer
# Julia, 36 bytes

# Try it!

```
julia> f=n->findfirst(x->factorial(x)==n,1:n)

julia> @benchmark f(121645100408832000)
BenchmarkTools.Trial:
  memory estimate:  0 bytes
  allocs estimate:  0
  --------------
  minimum time:     32.801 ns (0.00% GC)
  median time:      33.246 ns (0.00% GC)
  mean time:        33.661 ns (0.00% GC)
  maximum time:     56.452 ns (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     993

```
> 2 votes

# Answer
# Burlesque, 17 bytes

```
b01{+.}{?!.>}w!it

```

Try it online!

Explanation:

```
b0                # Parse input as base 10 integer
  1               # Push counter to the stack
   {+.}      w!   # Increment counter while
       {?!.>}     # The input is greater than the factorial of the counter
               it # Return just the counter

```
> 2 votes

# Answer
# PowerShell, 34 bytes

```
param($n)for(;++$x-$n;$n/=$x){};$x

```

Try it online!
> 2 votes

# Answer
# 05AB1E, 5 bytes

```
∞.Δ!Q

```

Try it online!
> 1 votes

# Answer
# Python 2, 73 bytes

```
lambda x:[n for n in range(1,x)if reduce(lambda a,b:a*b,range(1,n+1))==x]

```

Try it online!
> 1 votes

# Answer
# Keg, 10 bytes

```
&1{:¡⑻≠|1+

```

Try it online!
> 1 votes

# Answer
# JavaScript (V8), 29 bytes

```
f=(n,i=1)=>n/i^1?f(n/i,++i):i

```

Try it online!
> 1 votes

# Answer
# Prolog (SWI), ~~62~~ 55 bytes

```
X-N-N:-A is N/D,A==1,X is D;X-N/D-(D+1).
f(X,N):-X-N-1.

```

Try it online!

If `N` equals `D`, sets `X` to `D`, otherwise, it calls itself with `N/D` and `D+1`.
> 1 votes

# Answer
## HP‑41C series, 18 B

The \\$x\\$ in \\$x! = n\\$ can be determined by repeatedly dividing \\$n\\$ by an incrementing divisor (first \\$1\\$, then \\$2\\$, then \\$3\\$ and so forth) until the quotient equals the (next) divisor. The program works correctly up to and including \\$x = 39\\$.

```
01♦LBL "S"         5 Bytes    global label requires 4 + (length of string) Bytes
   NULL            1 Byte     invisible Null byte before numbers
02 1               1 Byte     place 1 on top of stack; X ≔ 1 ; Y ≔

03 LBL 00          2 Bytes    mark head of this loop with (local) label 00 ──┐
                                                                             │
04 X=Y?            1 Byte     if X = Y ──┐                                   │
05 RTN             1 Byte                └── then return                     │
                                                                             │
06 ∕               1 Byte     lastX ≔ X ;  X ≔ Y ∕ X                         │
                                                                             ↑
07 LASTX           1 Byte     put lastX back on top of stack again           │
   NULL            1 Byte     invisible Null byte before numbers             │
08 1               1 Byte     place 1 on top of stack                        │
09 +               1 Byte     sum X and Y, stack drops by one item           │
                                                                             │
10 GTO 00          2 Bytes    go to (local) label 00  ───────────────────────┘

```

Since this is pretty abstract, let’s consider a trace of the stack in the case \\$n = 6 = 3! = x!\\$. The *step* “sees” data from one row above, the *result* of a step follows in the *same* row. Empty cells are not relevant to the program.

| step | `X` | `Y` | `Z` | `T` | `L`astX |
| --- | --- | --- | --- | --- | --- |
|  | `6` |  |  |  |  |
| `1` | `1` | `6` |  |  |  |
| `X=Y?` |  |  |  |  |  |
|  | `6` |  |  |  | `1` |
| `LASTX` | `1` | `6` |  |  |  |
| `1` | `1` | `1` | `6` |  |  |
| `+` | `2` | `6` |  |  | `1` |
| `GTO 00` |  |  |  |  |  |
| `X=Y?` |  |  |  |  |  |
|  | `3` |  |  |  | `2` |
| `LASTX` | `2` | `3` |  |  |  |
| `1` | `1` | `2` | `3` |  |  |
| `+` | `3` | `3` |  |  | `1` |
| `X=Y?` |  |  |  |  |  |
| `RTN` |  |  |  |  |  |

Note that `GTO` searches for a local label downward in program memory and wraps to the beginning of the currently executed program. To inhibit local label search, append an `END` command (3 Bytes). The above program presumes there are *no other* programs (following) in program memory, so the *permanent* (= always there) `END` is sufficient.
> 1 votes

# Answer
# Add++, 23 bytes

```
D,f,@,R¦*BK=
L,dBkRÞ{f}

```

Try it online!

This is what happens when there's no "find index" or "first n where" or auto-vectorisation.

## Explained

```
D,f,@,R¦*BK= # Helper function f
      R      #    range 1...n
       ¦*    #    reduce by multiplication
         BK= #    does that equal the global register?
L,dBkRÞ{f}   # main lambda
  dBk        #    place the input into the global register.
     R       #    range 1...input
      Þ{f}   #    filter by helper function f

```
> 0 votes

# Answer
# Vyxal 3 `G`, 5 bytes

```
K!=Þκ

```

Try it Online!
> 0 votes

---
Tags: code-golf, math, factorial
---