38
\$\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\$
  • 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
  • 11
    \$\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\$ – CalculatorFeline May 22 '17 at 23:15

76 Answers 76

2
\$\begingroup\$

Haskell, 42 41 bytes

f 0=1
f a=a*f(a-1)
i x=elem x f<$>[1..x]

sample ghci output:

λ> i 0
False
*Main
λ> i 1
True
*Main
λ> i 2
True
*Main
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG and golfing in Haskell in particular! You can save a byte with f<$>[1..x] instead of map f[1..x]. \$\endgroup\$ – Laikoni May 21 '17 at 8:22
2
\$\begingroup\$

T-SQL 143 Bytes

create function a(@ int)
returns int begin
declare @a int=1,@b int=1
while @b<@
select @b*=@a,@a+=1
return case @b when @ then 1 else 0 end
end

Playing code golf with SQL gives me results like when I really golf!

Analysis:

create function a(@ int)
returns int begin

Ugh why do I have so many required characters to create a SQL function

declare @a int=1,@b int=1

We need a variable for our current factorial value, and a variable for the iteration to multiply by.

while @b<@

While our current factorial value is less than our input value, keep iterating through the loop.

select @b*=@a,@a+=1

Multiply our factorial value by the iteration value, and add one to the iteration value for the next loop.

return case @b when @ then 1 else 0 end

If our factorial value equals our input value, then it's going to return 1 for true, and if it's not, then that means it's not a factorial value and it's false.

end
\$\endgroup\$
2
\$\begingroup\$

Pyt, 5 bytes

←Đř!∈


Explanation:

←           Get input and put on stack
 Đ          Duplicate top of stack
  ř         Push [1,...,top of stack] to stack
   !        Calculate element-wise factorial of the array
    ∈       Is input in factorial array?
\$\endgroup\$
2
\$\begingroup\$

C++, 87 77 bytes

(I'm aware this is a bit old, but I figured I'd try my luck since the current C++ answer is at 92 bytes)

int f(int a){a=a?a*f(a-1):1;}int c(int a,int b=0){a=f(b)-a?a-b?c(a,b+1):0:1;}

The function for the check is c, the f function is purely to calculate the factorial

Ungolfed with comments:

int f(int a)
{
    // In some systems the last expression evaluated will be
    // the return value, this is utilizing that, as it assigns
    // a to a, and if that is 0, then the last espression will
    // have been 1, else it will be a * f(a-1)
    a=a ? a*f(a-1) : 1;
}

int c(int a,int b=0)
{
    // This works in the same way but over 2 levels
    // If f(b)==a then a=f(b)-a is 0, which means it'll
    // evalute 1, truthy, but if it's not zero, then it
    // Checks if a==b, if yes then it's 0, falsy because
    // we've checked all numbers, and if it's not 0, then
    // it calls c again with b+1
    a = f(b) - a ? a - b ? c(a,b+1) : 0 : 1;
}

Try it online (Thanks to @Jonathan Frech for the 77 bytes and link)

I found this recursive method much more shorter than a loop, especially with the default argument that stores the counter.

\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to PPCG! You might want to add a Try it online! link. \$\endgroup\$ – Deadcode Jan 27 at 9:19
  • \$\begingroup\$ 77 bytes. \$\endgroup\$ – Jonathan Frech Jan 27 at 13:13
  • \$\begingroup\$ @JonathanFrech Thank you for the improvement, but I'm unsure of how it works exactly, I put some comments to explain what I think it is, could you check if this is it? Also there is one specific thing I don't understand if my rational is correct, which is that you assign a=f(b)-a on the beginning, so how can you call c(a,b+1) without any problems? I would have thought the value of a would be lost after the first iteration \$\endgroup\$ – Filipe Rodrigues Jan 27 at 14:10
  • \$\begingroup\$ @FilipeRodrigues To my knowledge, it is simply an undefined behaviour exploitation with regards to gcc on some processors. The registers for the last assigned integer and the integer return value just happen to be the same in some (!) cases. Regarding your question, a= is the very last thing that will happen, so it cannot override c's argument. I actually do not think that there is a sequencing issue of any kind. If you simply add an return a; the a= should simply be an obfuscation. \$\endgroup\$ – Jonathan Frech Jan 27 at 15:01
  • \$\begingroup\$ For the sake of fairness, I also want to say that @Deadcode provided the TIO link and the test wrapper. \$\endgroup\$ – Jonathan Frech Jan 27 at 15:03
1
\$\begingroup\$

JavaScript (ES6), 60 58 bytes

a=>[...Array(a).keys()].some(b=>(f=c=>c?c*f(c-1):1)(b)==a)
\$\endgroup\$
1
\$\begingroup\$

CJam, 9 bytes

q~_,:m!e=

Try it online!

This outputs 1 if the input is a factorial, 0 otherwise.

Explanation:

q~           Read the input
  _,         Create array [0,...,Input-1]
    :m!      Factorial of each element of the array
       e=    Check if any element is equal to input
\$\endgroup\$
  • \$\begingroup\$ this outputs 0 for 2, try adding ) to increase values. This solution used the exact same logic (was basically identical to yours so I won't post it). \$\endgroup\$ – maxb May 18 '18 at 18:32
1
\$\begingroup\$

Clojure, 39 bytes

#(=((set(reductions *'(range 1 %)))%)%)

Calculating factorials up-to n seems to be the best way to go. *' supports arbitrary precision, but the runtime and memory usage of this implementation are quite bad for larger inputs. Returns true or false.

If truthy value was allowed to vary (returns the input number or nil) this would be 35 bytes:

#((set(reductions *'(range 1 %)))%)

For small input arguments you could use * instead of *'.

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

PHP, 32 Bytes

prints -2 for true and -1 for false

for(;1<$argn/=++$x;);echo~$argn;

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ echo$a&1 would work in PHP too (see my JS answer). \$\endgroup\$ – Arnauld May 20 '17 at 10:26
  • \$\begingroup\$ @Arnauld the other both bitwise operations should work in JS too \$\endgroup\$ – Jörg Hülsermann May 20 '17 at 10:36
  • 1
    \$\begingroup\$ Yup. Or even ~$a if -1 / -2 are acceptable outputs. \$\endgroup\$ – Arnauld May 20 '17 at 10:38
  • 1
    \$\begingroup\$ -3 bytes: for(;1<$argn/=++$x;);echo~$argn;. \$\endgroup\$ – user63956 May 20 '17 at 10:53
  • \$\begingroup\$ Is -1 really falsy in PHP? (I have never used this language) \$\endgroup\$ – Luis Mendo May 20 '17 at 12:56
1
\$\begingroup\$

J, 9 bytes

e.!@i.@>:

Try it online!

\$\endgroup\$
  • 2
    \$\begingroup\$ 0=1|!^:_1 should be much faster, and can handle huge numbers. \$\endgroup\$ – Adám May 22 '17 at 6:35
  • \$\begingroup\$ @Adám wow, I didn't think in terms of inverse per se. \$\endgroup\$ – Leaky Nun May 22 '17 at 7:14
  • \$\begingroup\$ And 0=1|!inv even saves you a byte... \$\endgroup\$ – Jonah Jan 26 at 2:40
1
\$\begingroup\$

Pyth, 5 bytes

/.!MS

online interpreter link

\$\endgroup\$
  • \$\begingroup\$ I was about to post... \$\endgroup\$ – Leaky Nun May 20 '17 at 12:37
  • 1
    \$\begingroup\$ @LeakyNun Yeah I felt it. But you posted the Jelly answer I had made... \$\endgroup\$ – Erik the Outgolfer May 20 '17 at 12:39
1
\$\begingroup\$

Charcoal, 24 bytes

NβA⟦⟧γW¬﹪βL⊞OγβA÷βLγβ⁼β¹

Try it online! Prints - for true and nothing for false. Note: Link is to verbose form for ease of explanation.

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

C#, 99 bytes

a=>{for(int i=0;i<22;i++){var b=1;for(int j=2;j<i;j++){b*=j;}if(a==b){return true;}}return false;};

It checks, if the input is one of the first 22 factorials, if yes it returns true, otherwise false.

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

Python 2 - 48 44 bytes

Thanks, @JonathanAllan, saved 4 bytes

Of course, not as short as the other answer, but doing stuff the old-fashion way:

n,x=input(),1.
while n>1:x+=1;n/=x
print n<1

Try It Online!

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

C, 57 bytes

More of a novelty solution more than anything else, just to have some fun with recursion. An iterative solution will most likely be shorter.

g(d,n){n<2?putchar(n+47):g(d+1,n/d*!(n%d));}f(n){g(1,n);}
\$\endgroup\$
1
\$\begingroup\$

C, 42 41 38 bytes

-3 bytes by @KritixiLithos!

m;f(float n){for(;n>1;n/=++m);m=n==1;}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Looks like 41 bytes to me ... \$\endgroup\$ – Hagen von Eitzen May 20 '17 at 22:24
  • \$\begingroup\$ your TIO link shows a different program than the one in your post, and that one is 39 bytes \$\endgroup\$ – Conor O'Brien May 21 '17 at 1:25
  • \$\begingroup\$ @HagenvonEitzen fixed \$\endgroup\$ – betseg May 21 '17 at 8:13
  • \$\begingroup\$ @ConorO'Brien fixed \$\endgroup\$ – betseg May 21 '17 at 8:13
1
\$\begingroup\$

Pari/GP, 23 bytes

n->#[x|x<-[1..n],x!==n]

Try it online!

\$\endgroup\$
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\$
  • \$\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\$

Templates Considered Harmful, 99 bytes

Fun<Ap<Fun<If<Eq<A<1>,T>,T,Eq<Rem<A<1>,A<2>>,F>,Ap<A<0>,Div<A<1>,A<2>>,Add<A<2>,T>>,F>>,A<1>,I<2>>>

Try it online!

Ungolfed:

Fun<Ap<Fun<If<Eq<A<1>, T>,
              T,
              Eq<Rem<A<1>, A<2>>, F>,
              Ap<A<0>, Div<A<1>, A<2>>, Add<A<2>, T>>,
              F>>,
       A<1>, I<2>>>

Divides by 2, 3, 4… until hits 1 or non-zero remainder.

\$\endgroup\$
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, 34 bytes

->a{x=1;(1..a).any?{|y|(x*=y)==a}}

Try it online!

\$\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
    \$\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\$

Japt, 4 bytes

õÊøU

Try it online!

\$\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\$

SmileBASIC, 37 bytes

INPUT N
WHILE N>1A=A+1N=N/A
WEND?N==1

Divides N by increasing numbers until N is less than or equal to 1. If N was a factorial, it will be 1 at the end.

Examples:

8 (÷1)-> 8 (÷2)-> 4 (÷3)-> 4/3 (÷4)-> 1/3 (end)
6 (÷1)-> 6 (÷2)-> 3 (÷3)-> 1 (end)
\$\endgroup\$
1
\$\begingroup\$

Befunge-98, 39 38 bytes

&1s #;:30g%;@.;#0_30g:1+30p/:1-#;!#1_;

Try it online!

Funge storage is only byte-sized, so the input number has to be kept on stack.

&1s #;:30g%;@.;#0_30g:1+30p/:1-#;!#1_;
&1s                                     n = read(), k = 1
     ;:30g%;     _                      S: if n % k != 0 goto Z
                  30g      /            n /= k
                     :1+30p             k += 1
                            :1-  !  _   if n != 1 goto S
                                ;  1    push(1), goto P
                0                       Z: push(0)
            @.;                         P: print()
\$\endgroup\$
  • \$\begingroup\$ you can use 1sX instead of 100p at the beginning as long as you swutch all the other get and put coordinates to 30 instead of 00 to save a byte. \$\endgroup\$ – MildlyMilquetoast May 18 '18 at 21:45
  • \$\begingroup\$ @MistahFiggins thanks! \$\endgroup\$ – eush77 May 19 '18 at 10:12
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\$
  • \$\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 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\$

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.