46
\$\begingroup\$

The Task

Given a natural number as input, your task is to output a truthy or falsey value based on whether the input is a factorial of any natural number. You can assume that the input number will always be in the range of numbers supported by your language, but you must not abuse native number types to trivialize the problem.

Standard Loopholes apply.


Input

You'll be given a natural number (of type Integer or similar).

You can take input in any way you want except assuming it to be in a predefined variable. Reading from file, console, dialog box (prompt), input box etc. is allowed. Input as function argument is allowed as well!


Output

Your program should output a truthy or falsey value based on whether the input number is a factorial of any natural number.

Make sure that your truthy/falsey values are consistent for all inputs, i.e, if you are using pair of 1 and 0 to denote truthy and falsey values respectively, then your program must output 1 for all inputs that should have truthy values and 0 for all inputs that should have falsey values.

You can take output in any way you want except writing it to a variable. Writing to file, console, screen etc. is allowed. Function return is allowed as well!

Your program must not produce errors for any input!


Test Cases

Input     Output

1         Truthy (0! or 1!)
2         Truthy (2!)
3         Falsey
4         Falsey
5         Falsey
6         Truthy (3!)
7         Falsey
8         Falsey
24        Truthy (4!)
120       Truthy (5!)

Winning Criterion

This is , so the shortest code in bytes wins!

\$\endgroup\$
5
  • 2
    \$\begingroup\$ If the language supports only numbers in the range {0,1}, can I expect the input to always be 1? \$\endgroup\$
    – eush77
    May 20 '17 at 9:45
  • 12
    \$\begingroup\$ @eush77 Abusing native number types to trivialize a problem is forbidden by default. \$\endgroup\$
    – Dennis
    May 20 '17 at 17:56
  • 1
    \$\begingroup\$ is 4! a truthy? \$\endgroup\$
    – tuskiomi
    May 20 '17 at 22:04
  • \$\begingroup\$ Question: Why aren't you using the I/O defaults? \$\endgroup\$ May 22 '17 at 23:15
  • \$\begingroup\$ @CalculatorFeline Didn't know they existed, if you still want to know the answer :-P Sorry \$\endgroup\$
    – Arjun
    Mar 18 '21 at 11:14

88 Answers 88

1 2
3
1
\$\begingroup\$

C#, 69 62 60 Bytes

n=>{int l=1,i=1,r=0;for(;i<13;i++)r=(l*=i)==n?1:r;return r;}

With line breaks:

n=> {
        int l = 1, i = 1, r = 0;
        for (; i < 13; i++) 
            r = (l *= i) == n 
                ? 1 
                : r;
        return r;
    }

Or as a whole method (79 71 69 Bytes):

int F(int n){int l=1,i=1,r=0;for(;i<13;i++)r=(l*=i)==n?1:r;return r;}

With line breaks:

int F(int n)
{
    int l = 1, i = 1, r = 0;
    for (; i < 13; i++)
        r = (l *= i) == n 
            ? 1 
            : r;
    return r;
}

Saved 2 Bytes thanks to Arjun

\$\endgroup\$
8
  • \$\begingroup\$ Can save three bytes: true -> 1>0, false -> 1<0. \$\endgroup\$
    – ProgramFOX
    May 20 '17 at 15:17
  • \$\begingroup\$ @ProgramFOX I got an even better idea - but thank you. \$\endgroup\$
    – MetaColon
    May 20 '17 at 16:52
  • \$\begingroup\$ Ah, yeah, that's better :) \$\endgroup\$
    – ProgramFOX
    May 20 '17 at 17:15
  • 1
    \$\begingroup\$ How about n=>int l=1,i=1,r=0;for(;i<13;i++)if((l*=i)==n)r=1;return r;} \$\endgroup\$
    – Arjun
    May 21 '17 at 15:35
  • 1
    \$\begingroup\$ r=(l*=i)==n?1:r \$\endgroup\$
    – Arjun
    May 21 '17 at 15:41
1
\$\begingroup\$

TI-Basic, 12 bytes

sum(Ans=seq(X!,X,1,Ans

This creates a list of all factorials up to the input's factorial, compares each one to the input, and returns the sum of all of the comparisons, which will be 1 if one of the factorials is equal to the input, or 0 if none are. This sum is implicitly returned as it is on the last line of the program.

Call with 53:prgmNAME. Overflows on inputs over 69; to avoid this, use sum(Ans=seq(X!,X,1,1+sqrt(Ans for 15 bytes

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

Ruby, 39 bytes

->a{(1..a).any?{|e|Math.gamma(e+1)==a}}
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 17 bytes

{$_∈[\*] 1..$_}

Checks whether $_, the argument, is a member of the triangular multiplication reduction (1, 1*2, ..., 1*2*...*$_).

This does a LOT of unnecessary math for larger inputs, but hey, it's short!

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

Japt, 9 bytes

This is my first Japt answer (and first Esolang answer)!

Uõl d_==U

An optimal solution already exists but that's not a reason for not posting this answer!

Try it online!

Thanks to @ETHproductions and @Shaggy for helping me out in the Japt Chatroom when I was stuck! And special thanks to @ETHproductions for making this language! It feels so good to code in Japt!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome​ to Japt :) You can save a couple of bytes on this by dropping the first U (it's implicit in this instance) and by using the ¥ shortcut for == (or the shortcut for ===). \$\endgroup\$
    – Shaggy
    May 23 '17 at 17:49
1
\$\begingroup\$

Actually, 5 bytes

;R♂!c

Try it online!

-2 bytes from Erik the Outgolfer's suggestion on a different answer

Explanation:

;R♂!c
;        duplicate input
 R       range(1, input+1)
  ♂!     factorial of each number in range
    c    does the list contain the input?
\$\endgroup\$
1
\$\begingroup\$

Tcl, 69 bytes

proc F n {incr p
while \$p<$n {set p [expr $p*[incr i]]}
expr $p==$n}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Now as a function it renders 2 bytes less! \$\endgroup\$
    – sergiol
    Sep 23 '17 at 1:57
1
\$\begingroup\$

Japt, 4 bytes

õÊøU

Try it online!

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

Zephyr, 86 bytes

input n as Integer
set i to 1
set f to 1
while f<n
inc i
set f to f*i
repeat
print f=n

Try it online!

f successively takes the value of every factorial from 1 on up, until it is no longer less than the input number n. If f is now equal to n, then n is a factorial and we output true; otherwise, n is not a factorial and we output false.

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

Retina, 31 bytes

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

Try it online!


Takes as input a unary number with _ as tally mark

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

Forth (gforth), 58 bytes

Surprisingly, the shortest method I could find to do this was iterating the factorial numbers and comparing them to the input.

: f >r 1 1 begin 1+ tuck 1- * tuck r@ >= until r> nip = ; 

Try it online!

Explanation

>r              \ place the input on the return stack (saves a lot of stack operations)
1 1             \ place the current factorial-value and the index on the stack
begin           \ start an indefinite loop
   1+ tuck 1-   \ increment the index, save a copy, and then decrement again
   * tuck       \ multiply the factorial and the index and save a copy
   r@           \ copy the input from the return stack
   0>=          \ check if it's greater than or equal to the factorial-value
until           \ end the indefinite loop
r> nip          \ move the input back to the normal stack and delete the index
=               \ compare the input and the final factorial value
\$\endgroup\$
1
\$\begingroup\$

CJam, 10 bytes

q~_),:m!&,

Try it online!

Uses similar logic as @FrodCube, but instead calculates set intersection and gets the length of the input. If the last , is dropped, you still get truthy/falsy values, but they are not consistent.

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

F#, 79 bytes

let rec f x=if x<2 then 1 else f(x-1)*x
let i n=Seq.map f{0..n}|>Seq.contains n

Try it online!

Maps each number from 0 to n inclusive to its factorial value (through the recursive function f), and checks to see if any of the mapped numbers are n.

\$\endgroup\$
1
  • \$\begingroup\$ Can be refactored with a fold and a lambda to save 16 bytes: fun a->Seq.map(fun b->Seq.fold(*)1[2..b]){0..a}|>Seq.contains a \$\endgroup\$
    – LSM07
    Jan 22 '19 at 4:56
1
\$\begingroup\$

CJam, 15 bytes

q~_,{)m!}%#-1=!

probably not the shortest answer but it's my first attempt with CJam

Explanation:

    q~_        Get the input and make a copy on the stack
    ,{)m!}%    Factorial all numbers from 1 to input
    #          see if input is in array
    -1=!       if input isn't in array return false otherwise return true
\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 56 bytes

(lambda(i)(do((c 0)(j 1(*(incf c)j)))((<= i j)(= j i))))

Try it online

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

Brain-Flak, 154 bytes

(<>((()))<>){{}(({}))<>({}<>)(({<({}[()])><>({})<>}{})<><({}())>)<>([([{}]{}[(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}}({}{}<>[{}]<>)((){[()](<{}>)}{})

Try it online!

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

Tidy, 18 bytes

{x:x in(!)on[1,x]}

Try it online!

Simply tests if x is in the list generated by taking the factorial of each element in [1, x].

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

GolfScript, 17 bytes

~.),{,1\{)*}/}%?)

Try it online!

Explanation

~                  # Evaluate the input
 .                 # Duplicate the value
  )                # Increment the value
   ,               # Generate range from 1 to input
    {        }%    # Map every item
     ,             # Generate a to-0 range
      1\           # Make the initial product 1
        {  }/      # Foreach over the product:
         )*        # Multiply by the value incremented by 1
               ?)  # Index, and then logicize it
\$\endgroup\$
1
\$\begingroup\$

Burlesque, 13 bytes

riJro?!jFi0>=

Try it online!

If you accept -1 as falsey (technically isn't in burlesque) and >0 as truthy can save 3 bytes.

riJ # Read as int and duplicate on stack
ro  # Range from [1,N]
?!  # Factorial each
jFi # Find the index of the element == N
0>= # Found index
\$\endgroup\$
1
\$\begingroup\$

Add++, 10 bytes

L,R€R€b*Ae

Try it online!

How it works

L,		; Define the main function that takes one argument, x
		; Example: x = 24		STACK = [24]
	R	; Range				STACK = [[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]]
	€R	; Range for each		STACK = [[[1] [1 2] [1 2 3] ... [1 2 3 ... 22 23 24]]
	€b*Bh	; Product for each		STACK = [[1 2 6 ... 620448401733239439360000]]
	Ae	; Is x in the array?		Returns 1
\$\endgroup\$
1
\$\begingroup\$

ink, 52 bytes

=t(n)
~temp f=1
-(l){n<f:{n==1}->->}
~n=n/f
~f++
->l

Try it online!

Assumes the input is a floating point number. If the number is integer-type, the division on line 4 truncates the quotient, which can cause false positives.
Prints its output (1 or 0) directly to stdout. Because ink.

Ungolfed

== check_if_factorial(input) ==
~ temp iterator = 1
- (loop)
{
    - iterator < input:
        {n == 1 : 1 | 0}
        ->->
}
~ input = input / iterator
~ iterator++
-> loop
\$\endgroup\$
1
\$\begingroup\$

Vyxal, r, 3 bytes

ʀ‼c

Try it Online!

Explained

ʀ‼c
ʀ   # range(0, input + 1)
 ‼  # factorial(^) // vectorises
  c # input in ^ // r flag makes operators take arguments in reverse
\$\endgroup\$
0
\$\begingroup\$

Axiom, 67 bytes

f(x:NNI):Boolean==(i:=2;r:=1;repeat(r>=x=>break;r:=r*i;i:=i+1);r=x)

some test

(12) -> [[i,f(i)] for i in [0,1,2,3,6,24,25,120,720]]
   (12)
   [[0,false], [1,true], [2,true], [3,false], [6,true], [24,true], [25,false],
    [120,true], [720,true]]
                                                      Type: List List Any
\$\endgroup\$
0
\$\begingroup\$

2Col, 5 bytes [non-competing]

F!
$^

Try it in 2CollIDE

Basically the same as the Jelly answers. Link leads to the current 2Col interpreter in TIO, with the above code already inserted. 3rd argument is input.

2Col is a language where each line is a 2 character expression of some form. It's what I like to call an "Accumulator-based" language. It works like Stack-based languages, except the "stack" can only contain a single item.

Explanation:

      Implicit input to Cell
F!    Return [1!, 2!, ... n!]
$^    Return whether above return value contains Cell value
      Implicit: Print final line's return value
\$\endgroup\$
0
\$\begingroup\$

Tcl, 71 bytes

incr p
while \$p<$argv {set p [expr $p*[incr i]]}
puts [expr $p==$argv]

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Note: $argv is the variable that carries the argument from console; I had just overridden it to test all test cases at once! \$\endgroup\$
    – sergiol
    Sep 23 '17 at 1:45
0
\$\begingroup\$

JavaScript, 124 bytes

I am nub so here it is:

a=(i)=>{r=1;n=0;while(n>=0){n++;r=r*n;if(i==r){console.log(i,"truthy:",n+"!");break;}else{console.log(i,"falsey:",n+"!");}}}

This link may or may not work. If it does, click run and then type "a(24)" or "a(120)" etc. If you pass-in a non-factorial int, it will run infinitely... so don't do that.

\$\endgroup\$
1
  • \$\begingroup\$ Output is allowed as return values, which could save you a lot of bytes. \$\endgroup\$
    – Nissa
    May 18 '18 at 16:26
0
\$\begingroup\$

Python 3, 92 bytes

f=lambda n,i='1':n<2or(eval(i)==n if eval(i)>=n else f(n,i+'*%d'%(int(i.split('*')[-1])+1)))

Try it online!

This is the first thing I thought of seeing this challenge, but it didn't turn out as well as I had it in my head, easily beaten by other solutions.

Thanks to lambda for noticing a bug in my submission.

\$\endgroup\$
1
  • \$\begingroup\$ Is there a point to using strings and then evaling it instead of just using a separate variable to keep track of the number? e.g. 46 bytes \$\endgroup\$
    – Jo King
    Jan 22 '19 at 5:30
0
\$\begingroup\$

Excel, 24 bytes

=OR(A1=FACT(ROW(1:170)))
\$\endgroup\$
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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