-14
\$\begingroup\$

The goal of this code golf is to create a program that calculates the factorial of a positive number, without using recursion or loops. The rules:

  1. Your program should prompt for input. This input will be a positive integer
  2. Your program should output the factorial of the given positive integer
  3. You are not allowed to use recursion or loops (including goto)
  4. You are not allowed to execute an external program
  5. You are not allowed to use a built-in function to calculate the factorial (including eval functions)
  6. Your program MUST work without network connection

Good luck!

\$\endgroup\$
11
  • 4
    \$\begingroup\$ im pretty sure this is impossible, u need some sort of looping (built-in or otherwise), unless u let trick looping/recursion. so you have to depend on a built-in looping function? its impossible in many languages.... \$\endgroup\$ Oct 23 '13 at 16:30
  • 2
    \$\begingroup\$ Just take a look how numbers are converted to strings, every programming language will loop. (Ok there could be the C equivalent with literal strings) \$\endgroup\$ Oct 23 '13 at 17:46
  • 9
    \$\begingroup\$ And by the way: Restricting eval changes the rules, invalidates most of the answers, and is just like "ohh, they found an other way to solve this, forbid that too"... \$\endgroup\$ Oct 23 '13 at 18:53
  • 18
    \$\begingroup\$ -1 for changing the question radically \$\endgroup\$
    – Doorknob
    Oct 23 '13 at 20:54
  • 3
    \$\begingroup\$ @ProgramFOX This is impossible (wihtout adding abitiary limitations like 32-bit or defer the loop to the language). The problem you describe here is more or less equivalent to "Find a formula that calculates the factorial". Just look at the Γ-Function. While there are formulas that can calculate n!, they are too complex and involve either Π or , which can not be solved without loops/recursion. \$\endgroup\$ Oct 24 '13 at 8:21

19 Answers 19

40
\$\begingroup\$

Tcl, 82

puts [lindex {1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800} [gets stdin]]

No eval, no recursion, no loops. As requested. Only works with 32-Bit integers.

\$\endgroup\$
1
  • 5
    \$\begingroup\$ but isn't 12! = 479001600 < 2^29? \$\endgroup\$
    – Will Ness
    May 25 '15 at 7:54
25
\$\begingroup\$

Mathematica, 32

Integrate[x^Input[]/E^x,{x,0,∞}]

I hope I did everything correctly, otherwise please correct it.
I don't even have Mathematica.

If nothing else works, use the Gamma function.

\$\endgroup\$
2
  • \$\begingroup\$ Nice approach. It works fine. \$\endgroup\$
    – DavidC
    Oct 26 '13 at 16:33
  • \$\begingroup\$ here's a test at WolframAlpha. \$\endgroup\$
    – Will Ness
    May 25 '15 at 8:01
14
\$\begingroup\$

Mathematica 20

This should be easy to beat.

Times@@Range@Input[]
\$\endgroup\$
3
  • \$\begingroup\$ "you are not allowed to use a built-in function to calculate the factorial" \$\endgroup\$ Oct 23 '13 at 16:30
  • 4
    \$\begingroup\$ @tryingToGetProgrammingStraight the built-in one would be Factorial \$\endgroup\$
    – ssch
    Oct 23 '13 at 16:31
  • 15
    \$\begingroup\$ @tryingToGetProgrammingStraight. I used three functions, Times, Apply (@@), and Range. \$\endgroup\$
    – DavidC
    Oct 23 '13 at 16:31
7
\$\begingroup\$

R - 14 characters

prod(1:scan())

\$\endgroup\$
2
  • \$\begingroup\$ +1 but I think it should be scan(n=1) \$\endgroup\$
    – flodel
    Oct 29 '13 at 0:07
  • \$\begingroup\$ @flodel leaving out the n=1 saves space, and still allows the function to work, so long as your first input is the value to target, and the next is empty (press enter twice on the first value). \$\endgroup\$
    – Gaffi
    Oct 29 '13 at 15:02
5
\$\begingroup\$

Bash 43

Using only internal commands:

read n;echo $((`eval "echo 1 '*'{1..$n}"`))

The inside is pretty much seq -s'*' $n

\$\endgroup\$
2
  • \$\begingroup\$ Two small improvements: $[…] instead of $((…)) and \* instead of '*'. \$\endgroup\$
    – manatwork
    Oct 24 '13 at 8:01
  • \$\begingroup\$ @manatwork Nice hadn't seen $[ ] before (probably because it's deprecated) \$\endgroup\$
    – ssch
    Oct 25 '13 at 14:04
4
\$\begingroup\$

Excel Formula, 32

=PRODUCT(ROW(INDIRECT("1:"&A1)))

Enter as an array formula, and the value to be factored should be in A1

it's 34 if you have to count the {} that excel will put around the formula when successfully entered with Ctrl+Shift+Enter

\$\endgroup\$
1
  • \$\begingroup\$ =PRODUCT(ROW(INDIRECT("1:"&ROW()))) to put in any cell, where the row number in which it's placed is the value to be factored. This way, the solution is self-contained and does not require any other references. (Not that your answer needed any improving.) \$\endgroup\$
    – Gaffi
    Oct 28 '13 at 17:45
4
\$\begingroup\$

Ruby, 25 characters

p eval [*1..gets.to_i]*?*
\$\endgroup\$
1
  • \$\begingroup\$ Or 21 characters if you assume the input will have no trailing line separator: pastebin.com/pMRDWn4v \$\endgroup\$
    – manatwork
    Oct 24 '13 at 8:06
3
\$\begingroup\$

APL, 4 characters / GolfScript, 9 characters

APL:

×/⍳⎕

GolfScript:

~),1>{*}*
\$\endgroup\$
2
  • \$\begingroup\$ And how does that GolfScript work? Isn't * applied to a block like eval? \$\endgroup\$ Oct 30 '13 at 7:30
  • 7
    \$\begingroup\$ {*}* does a loop \$\endgroup\$
    – Claudiu
    Oct 16 '14 at 16:36
3
\$\begingroup\$

Perl 6 (14 bytes)

I assume that reduce operator ([*]) is not a loop.

say [*] 2..get
\$\endgroup\$
2
\$\begingroup\$

Haskell - 51 characters

main=getLine >>=(print .(\n->product[1..n]). read)

From Evolution of a Haskell Programmer, the tenured professor.

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

Java, 500 bytes

A couple years late to the party, but I think I've captured the spirit of the question, as it uses no form of looping whatsoever. Takes the first command line argument as an integer (greater than or equal to 1), and prints out its factorial, or terminates with exception in the case of overflow. Since java integers can only hold the factorials of numbers up to 16, it just uses a switch statement with the results hard coded in ;)

public class M{public static void main(String[]args){int n=Integer.parseInt(args[0]);int r;switch(n){case(1):r=1;break;case(2):r=2;break;case(3):r=6;break;case(4):r=24;break;case(5):r=120;break;case(6):r=720;break;case(7):r=5040;break;case(8):r=40320;break;case(9):r=362880;break;case(10):r=3628800;break;case(11):r=39916800;break;case(12):r=479001600;break;case(13):r=1932053504;break;case(14):r=1278945280;break;case(15):r=2004310016;break;case(16):r=2004189184;break;default:r=1/0;}System.out.print(r);}}

EDIT - Saved 7 bytes thanks to NoOneIsHere

class M{public static void main(String[]args){int n=Integer.parseInt(args[0]);int r;switch(n){case(1):r=1;break;case(2):r=2;break;case(3):r=6;break;case(4):r=24;break;case(5):r=120;break;case(6):r=720;break;case(7):r=5040;break;case(8):r=40320;break;case(9):r=362880;break;case(10):r=3628800;break;case(11):r=39916800;break;case(12):r=479001600;break;case(13):r=1932053504;break;case(14):r=1278945280;break;case(15):r=2004310016;break;case(16):r=2004189184;break;default:r=1/0;}System.out.print(r);}}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can change args to a, and remove some publics (I think). \$\endgroup\$ Sep 3 '16 at 17:49
1
\$\begingroup\$

J, 14 characters

*/1+i.".1!:1[1
\$\endgroup\$
3
  • \$\begingroup\$ Wouldn't */@:>:@i. work? \$\endgroup\$
    – Leaky Nun
    May 20 '16 at 17:23
  • \$\begingroup\$ @KennyLau I'm not at my computer right now so I can't check, but my answer includes the input 1!:1[1 which your version doesn't. \$\endgroup\$
    – Gareth
    May 20 '16 at 17:28
  • \$\begingroup\$ I see, thanks for your explanation. \$\endgroup\$
    – Leaky Nun
    May 20 '16 at 17:29
1
\$\begingroup\$

Ruby: 30 26 characters

(“Translation” of David Carraher's answer.)

p [*1..gets.to_i].reduce:*

Sample run:

bash-4.1$ ruby -e 'p [*1..gets.to_i].reduce:*' <<< 5
120

bash-4.1$ ruby -e 'p [*1..gets.to_i].reduce:*' <<< 10
3628800
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Remove parens around :* to save 2 chars \$\endgroup\$
    – Doorknob
    Oct 23 '13 at 17:00
  • \$\begingroup\$ @Doorknob, which version? It doesn't work with 1.9.3. pastebin.com/JVEb0Wzv \$\endgroup\$
    – manatwork
    Oct 24 '13 at 7:49
  • \$\begingroup\$ pastebin.com/mSG6d5ax \$\endgroup\$
    – Doorknob
    Oct 24 '13 at 20:50
  • \$\begingroup\$ Thank you @Doorknob. That $><< was the problem. \$\endgroup\$
    – manatwork
    Oct 25 '13 at 8:14
1
\$\begingroup\$

Python 3 - 77 characters

import functools
print(functools.reduce(int.__mul__,range(1,int(input())+1)))
\$\endgroup\$
1
\$\begingroup\$

Ruby, 21 characters

p eval [*?1..gets]*?*
\$\endgroup\$
1
\$\begingroup\$

TI-Basic, 9 bytes

prod(seq(I,I,1,Ans

Makes a list from 1 to the input and calculates the product.

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

PHP, 116

class a{function __destruct(){global $_,$x,$i,$argv;$x*=$i;if($i++<$argv[1])$_=new a;else echo$x;}}$i=$x=1;$_=new a;

No recursions, loops, range, reduce, implode, repeat, map, etc.

\$\endgroup\$
5
  • \$\begingroup\$ I think recursive self-initialisation is definitely recursion. In fact, this is literally no different than a recursive function and global variables... \$\endgroup\$
    – cat
    Jun 10 '16 at 18:10
  • \$\begingroup\$ @cat You can print a stacktrace using echo new Exception; and it has 2 levels for every time. Internally it is probably a loop on a queue though. \$\endgroup\$
    – jimmy23013
    Jun 10 '16 at 23:24
  • \$\begingroup\$ @cat You might have misunderstood it. It is self-initialization but the function is __destruct. \$\endgroup\$
    – jimmy23013
    Jun 10 '16 at 23:33
  • \$\begingroup\$ It's still recursion, regardless of whether it's only on a GC cycle \$\endgroup\$
    – cat
    Jun 10 '16 at 23:46
  • \$\begingroup\$ @cat Well, you can have opinion. \$\endgroup\$
    – jimmy23013
    Jun 10 '16 at 23:50
0
\$\begingroup\$

Factor, 44 bytes

[ 1 readln string>number 1 <range> product ] 
\$\endgroup\$
0
\$\begingroup\$

Julia

As a function — 12 bytes:

n->prod(1:n)

With an input prompt — 23 bytes:

prod(1:int(readline()))

By integration — 50 bytes:

n=int(readline());int(quadgk(x->x^n/e^x,0,Inf)[1])

(Not sure if the function-only form qualifies, re rule #1.)

\$\endgroup\$

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