# 如何找到正数的阶乘？

18

4
-1，对不起，因为我们收到了大量这些代码拖曳问题，而这并没有真正为他们增加任何新内容
Doorknob

Paul

46

``````def sqrt(x, n): # not the same n as below
return .5 * (sqrt(x, n - 1) + x / sqrt(x, n - 1)) if n > 0 else x

n = float(raw_input())
print (n / 2.718) ** n * sqrt(2 * 3.141 * n, 10)
``````

``````1! =    0.92215
2! =    1.91922
3! =    5.83747
4! =   23.51371
5! =  118.06923
6! =  710.45304
7! = 4983.54173
8! = 39931.74015
9! = 359838.58817
``````

16
+1该方法的简单性和准确性使其成为了明显的赢家
Joe the Person

44

## C＃

``````public string Factorial(uint n) {
return n + "!";
}
``````

1

WallyWest

36

``````public int factorial ( int n ) {
switch(n){
case 0: return 1;
case 1: return 1;
case 2: return 2;
case 3: return 6;
case 4: return 24;
case 5: return 120;
case 6: return 720;
case 7: return 5040;
case 8: return 40320;
case 9: return 362880;
case 10: return 3628800;
case 11: return 39916800;
case 12: return 479001600;
default : throw new IllegalArgumentException();
}
}
``````

16

Fabinout 2014年

6
@Fabinout，即使对于n> = 13，实现也是正确的。13！> Integer.MAX_VALUE。
emory

21

# 蟒蛇

``````import re

def multiple_replace(dict, text):
# Create a regular expression  from the dictionary keys
regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
# Repeat while any replacements are made.
count = -1
while count != 0:
# For each match, look-up corresponding value in dictionary.
(text, count) = regex.subn(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
return text

fdict = {
'A': '@',
'B': 'AA',
'C': 'BBB',
'D': 'CCCC',
'E': 'DDDDD',
'F': 'EEEEEE',
'G': 'FFFFFFF',
'H': 'GGGGGGGG',
'I': 'HHHHHHHHH',
'J': 'IIIIIIIIII',
'K': 'JJJJJJJJJJJ',
'L': 'KKKKKKKKKKKK',
'M': 'LLLLLLLLLLLLL',
'N': 'MMMMMMMMMMMMMM',
'O': 'NNNNNNNNNNNNNNN',
'P': 'OOOOOOOOOOOOOOOO',
'Q': 'PPPPPPPPPPPPPPPPP',
'R': 'QQQQQQQQQQQQQQQQQQ',
'S': 'RRRRRRRRRRRRRRRRRRR',
'T': 'SSSSSSSSSSSSSSSSSSSS',
'U': 'TTTTTTTTTTTTTTTTTTTTT',
'V': 'UUUUUUUUUUUUUUUUUUUUUU',
'W': 'VVVVVVVVVVVVVVVVVVVVVVV',
'X': 'WWWWWWWWWWWWWWWWWWWWWWWW',
'Y': 'XXXXXXXXXXXXXXXXXXXXXXXXX',
'Z': 'YYYYYYYYYYYYYYYYYYYYYYYYYY'}

def fact(n):
return len(multiple_replace(fdict, chr(64 + n)))

if __name__ == "__main__":
print fact(7)
``````

1

15

``````fac = length . permutations . flip take [1..]
``````

PLL

1

jgon

10

## C＃

### 第三步：

``````public string Factorial(uint n) {
MLApp.MLApp matlab = new MLApp.MLApp();
return matlab.Execute(String.Format("factorial({0})", n);
}
``````

Moshe Katz 2013年

4
Moshe Katz-有理由的理由。
Mike H.

9

## C＃

``````long Factorial(int n)
{
if(n==0)
{
return 1;
}

Stack<long> s = new Stack<long>();
for(var i=1;i<=n;i++)
{
s.Push(i);
}
var items = new List<long>();
var n2 = s.Pop();
while(s.Count >0)
{
var n3 = s.Pop();
n2 = items.Sum();
}
return items.Sum()/(n-1);
}

IEnumerable<long> FactorialPart(long n1, long n2)
{
for(var i=0;i<n2;i++){
yield return n1;
}
}
``````

Paul

9
``````#include <math.h>

int factorial(int n)
{
const double g = 7;
static const double p[] = { 0.99999999999980993, 676.5203681218851,
-1259.1392167224028, 771.32342877765313,
-176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6,
1.5056327351493116e-7 };
double z = n - 1 + 1;
double x = p[0];
int i;
for ( i = 1; i < sizeof(p)/sizeof(p[0]); ++i )
x += p[i] / (z + i);
return sqrt(2 * M_PI) * pow(z + g + 0.5, z + 0.5)  * exp(-z -g -0.5) * x + 0.5;
}
``````

• 一种100％正确的阶乘计算方式，完全错过了以迭代或递归方式进行计算的要点。
• 您不知道它为什么起作用，并且无法将其推广到其他用途。
• 与仅使用整数数学进行计算相比，成本更高。
• `z = n - 1 + 1`如果您知道发生了什么，最明显的“次优”代码（）实际上是自记录的。
• 对于额外的拖钓，我应该`p[]`使用序列系数的递归计算来进行计算！

（这是伽玛函数Lanczos近似值

`- 1 + 1`这里有什么要点吗？我的编译器对其进行了优化（这不是浮点数，在这种情况下优化代码可能会很危险），因此似乎不需要它。

4
@xfix：`double z = n - 1`是伽马函数近似值的一部分。的`+ 1`距离关系，即`gamma(n + 1) = n!`对于整数n。

9

``````from math import log,exp

def fac_you(x):
return round(exp(sum(map(log,range(1,x+1)))))

for i in range(1,99):
print i,":",fac_you(i)
``````

Mark K Cowan 2014年

1

Number9

8

``````window.factorial = function(\$nb_number) {
\$nb_trials = 1
for(\$i = 0; \$i < \$nb_number; \$i++) \$nb_trials *= \$nb_number
\$nb_successes = 0
__trying__:
for(\$nb_trial = 0; \$nb_trial < \$nb_trials; \$nb_trial++){
\$a_trial_split = new Array
\$nb_tmp = \$nb_trial
for (\$nb_digit = 0; \$nb_digit < \$nb_number; \$nb_digit++){
\$a_trial_split[\$nb_digit] = \$nb_tmp - \$nb_number * Math.floor(\$nb_tmp / \$nb_number)
\$nb_tmp = Math.floor(\$nb_tmp / \$nb_number)
}
for(\$i = 0; \$i < \$nb_number; \$i++)
for(\$j = 0; \$j < \$nb_number; \$j++)
if(\$i != \$j)
if(\$a_trial_split[\$i] == \$a_trial_split[\$j])
continue __trying__
\$nb_successes += 1
}
return \$nb_successes
}

document.open()
document.write("<input type = text onblur = alert(factorial(parseInt(this.value))))>")
document.close()
``````

• 输入匈牙利符号，snake_case 不必要的信号。那有多邪恶？
• 发明了我自己的跳转标签约定，与该约定的当前用法不兼容。
• 每个可能的变量都是偶然的全局变量。
• 解决的办法不是`O(n)`，不是`O(n!)`，而是`O(n^n)`。仅此一项就足以在这里有资格。
• 递增一个数字然后转换为base-n是生成序列列表的一种不好的方法。即使我们确实想要重复。神秘突破n> 13并不是唯一的原因。
• 当然我们可以使用`number.toString(base)`，但是不适用于36以上的基数。是的，我知道36！是很多，但仍...
• 我是否提到Javascript具有模运算符？还是`Math.pow`？没有？那好吧。
• 拒绝`++`在for循环之外使用使它更加神秘。而且，`==`是不好的。
• 深层嵌套的无括号循环结构。同样，嵌套条件语句代替AND。同样，可以通过在处结束内部循环来避免外部条件`\$i`
• 的功能`new Array``document.write`（与朋友）和`alert`（而不是一个提示或输入标记）形成的功能选择罪一个完整的三连胜。为什么毕竟要动态添加输入？
• 内联事件处理程序。哦，深度管道调试很困难。
• 未引用的属性很有趣，并且周围的空格`=`使它们更难阅读。
• 我是否已经提到我讨厌分号？

8

Ruby和WolframAlpha

``````require 'rest-client'
require 'nokogiri'

n = gets.chomp.to_i
response = Nokogiri::XML(RestClient.get("http://api.wolframalpha.com/v2/query?input=#{n}!&format=moutput&appid=YOUR_APP_KEY"))
puts response.xpath("//*/moutput/text()").text
``````

7

# Java脚本

Javascript是一种功能编程语言，这意味着您必须对所有功能都使用函数，因为它的速度更快。

``````function fac(n){
var r = 1,
a = Array.apply(null, Array(n)).map(Number.call, Number).map(function(n){r = r * (n + 1);});
return r;
}
``````

1

Mhmd 2013年

7
1不是功能。因此，您的代码很慢。

4
@ArlaudPierre `r = -~(function(){})`一定会解决这个问题。
nitro2k01 2014年

4

joeytwiddle 2014年

3

trolling

5

# 在Java中使用Bogo-Sort

``````public class Factorial {
public static void main(String[] args) {
//take the factorial of the integers from 0 to 7:
for(int i = 0; i < 8; i++) {
System.out.println(i + ": " + accurate_factorial(i));
}
}

//takes the average over many tries
public static long accurate_factorial(int n) {
double sum = 0;
for(int i = 0; i < 10000; i++) {
sum += factorial(n);
}
return Math.round(sum / 10000);
}

public static long factorial(int n) {
//n! = number of ways to sort n
//bogo-sort has O(n!) time, a good approximation for n!
//for best results, average over several passes

//create the list {1, 2, ..., n}
int[] list = new int[n];
for(int i = 0; i < n; i++)
list[i] = i;

//mess up list once before we begin
randomize(list);

long guesses = 1;

while(!isSorted(list)) {
randomize(list);
guesses++;
}

return guesses;
}

public static void randomize(int[] list) {
for(int i = 0; i < list.length; i++) {
int j = (int) (Math.random() * list.length);

//super-efficient way of swapping 2 elements without temp variables
if(i != j) {
list[i] ^= list[j];
list[j] ^= list[i];
list[i] ^= list[j];
}
}
}

public static boolean isSorted(int[] list) {
for(int i = 1; i < list.length; i++) {
if(list[i - 1] > list[i])
return false;
}
return true;
}
}
``````

4

``````#!/usr/bin/perl -w
use strict;
use bigint;
die "usage: f.perl N (outputs N!)" unless (\$ARGV[0] > 1);
print STDOUT &main::rangeProduct(1,\$ARGV[0])."\n";
sub main::rangeProduct {
my(\$l, \$h) = @_;
return \$l    if (\$l==\$h);
return \$l*\$h if (\$l==(\$h-1));
# arghhh - multiplying more than 2 numbers at a time is too much work
# find the midpoint and split the work up :-)
my \$m = int((\$h+\$l)/2);
my \$pid = open(my \$KID, "-|");
if (\$pid){ # parent
my \$X = &main::rangeProduct(\$l,\$m);
my \$Y = <\$KID>;
chomp(\$Y);
close(\$KID);
die "kid failed" unless defined \$Y;
return \$X*\$Y;
} else {
# kid
print STDOUT &main::rangeProduct(\$m+1,\$h)."\n";
exit(0);
}
}
``````

• 分叉O（log2（N））进程
• 不检查您有多少个CPU或核心
• 隐藏在每个过程中发生的许多bigint /文本转换
• for循环通常比此代码快

`ARGV[0]`直到perl中的TIL 实际上是第一个参数，而不是脚本！
ThinkChaos 2014年

@plg我相信\$ 0可能包含脚本文件名，但这与\$ ARGV [0]不同
Paul

ThinkChaos

4

## 蟒蛇

``````def divide(n,i):
res=0
while n>=i:
res+=1
n=n-i
return res

def isdivisible(n,numbers):
for i in numbers:
if n%i!=0:
return 0
n=divide(n,i)
return 1

def factorial(n):
res = 1
if n==0: return 1 #Handling the base case
while not isdivisible(res,range(1,n+1)):
res+=1
return res
``````

3

Well, there is an easy solution in Golfscript. You could use a Golfscript interpreter and run this code:

``````.!+,1\{)}%{*}/
``````

Easy huh :) Good luck!

2
I don't know GolfScript, but this one disappoints me... Based on the other GolfScript examples on this site, I would have expected the answer to be `!`
Mr Lister

1
That is the negation operator. 0 becomes 1 and everything else becomes 0.
Martijn Courteaux

3

### Mathematica

``````factorial[n_] := Length[Permutations[Table[k, {k, 1, n}]]]
``````

It doesn't seem work for numbers larger than 11, and factorial[11] froze up my computer.

3

# Ruby

``````f=->(n) { return 1 if n.zero?; t=0; t+=1 until t/n == f[n-1]; t }
``````

The slowest one-liner I can imagine. It takes 2 minutes on an i7 processor to calculate `6!`.

2

The correct approach for these difficult math problems is a DSL. So I'll model this in terms of a simple language

``````data DSL b a = Var x (b -> a)
| Mult DSL DSL (b -> a)
| Plus DSL DSL (b -> a)
| Const Integer (b -> a)
``````

To write our DSL nicely, it's helpful to view it as a free monad generated by the algebraic functor

``````F X = X + F (DSL b (F X)) -- Informally define + to be the disjoint sum of two sets
``````

We could write this in Haskell as

``````Free b a = Pure a
| Free (DSL b (Free b a))
``````

I will leave it to the reader to derive the trivial implementation of

``````join   :: Free b (Free b a) -> Free b a
return :: a -> Free b a
liftF  :: DSL b a -> Free b a
``````

Now we can descibe an operation to model a factorial in this DSL

``````factorial :: Integer -> Free Integer Integer
factorial 0 = liftF \$ Const 1 id
factorial n = do
fact' <- factorial (n - 1)
liftF \$ Mult fact' n id
``````

Now that we've modeled this, we just need to provide an actual interpretation function for our free monad.

``````denote :: Free Integer Integer -> Integer
denote (Pure a) = a
denote (Free (Const 0 rest)) = denote \$ rest 0
...
``````

And I'll leave the rest of the denotation to the reader.

To improve readability, it's sometimes helpful to present a concrete AST of the form

``````data AST = ConstE Integer
| PlusE AST AST
| MultE AST AST
``````

``````reify :: Free b Integer -> AST
``````

2

# 蟒蛇

So here is the code: the `getDigits` function splits a string representing a number in to its digits, so "1234" becomes `[ 4, 3, 2, 1 ]` (the reverse order just makes the `increase` and `multiply` functions simpler). The `increase` function takes such a list and increases it by one. As the name suggests, the `multiply` function multiplies, e.g. `multiply([2, 1], [3])` returns `[ 6, 3 ]` because 12 times 3 is 36. This works in the same way as you would multiply something with pen and paper.

Then finally, the `factorial` function uses these helper functions to calculate the actual factorial, for example `factorial("9")` gives `"362880"` as its output.

``````import copy

def getDigits(n):
digits = []
for c in n:
digits.append(ord(c) - ord('0'))

digits.reverse()
return digits

def increase(d):
d[0] += 1
i = 0
while d[i] >= 10:
if i == len(d)-1:
d.append(0)

d[i] -= 10
d[i+1] += 1
i += 1

def multiply(a, b):
subs = [ ]
s0 = [ ]
for bi in b:

s = copy.copy(s0)
carry = 0
for ai in a:
m = ai * bi + carry
s.append(m%10)
carry = m//10

if carry != 0:
s.append(carry)

subs.append(s)
s0.append(0)

done = False
res = [ ]
termsum = 0
pos = 0
while not done:
found = False
for s in subs:
if pos < len(s):
found = True
termsum += s[pos]

if termsum != 0:
res.append(termsum%10)
termsum = termsum//10
done = True
else:
res.append(termsum%10)
termsum = termsum//10
pos += 1

while termsum != 0:
res.append(termsum%10)
termsum = termsum//10

return res

def factorial(x):
if x.strip() == "0" or x.strip() == "1":
return "1"

factorial = [ 1 ]
done = False
number = [ 1 ]
stopNumber = getDigits(x)
while not done:
if number == stopNumber:
done = True

factorial = multiply(factorial, number)
increase(number)

factorial.reverse()

result = ""
for c in factorial:
result += chr(c + ord('0'))

return result

print factorial("9")
``````

### Notes

In python an integer doesn't have a limit, so if you'd like to do this manually you can just do

``````fac = 1
for i in range(2,n+1):
fac *= i
``````

There's also the very convenient `math.factorial(n)` function.

This solution is obviously far more complex than it needs to be, but it does work and in fact it illustrates how you can calculate the factorial in case you are limited by 32 or 64 bits. So while nobody will believe this is the solution you've come up with for this simple (at least in Python) problem, you can actually learn something.

There is no limit on integer numbers in Python... right? You might need to explain this better.
Riking

@Riking Yes, in python there's no limit for integers. I've added a few notes to make it more clear.
brm

2

## Python

The most reasonable solution is clearly to check through all numbers until you find the one which is the factorial of the given number.

``````print('Enter the number')
n=int(input())
x=1
while True:
x+=1
tempx=int(str(x))
d=True
for i in range(1, n+1):
if tempx/i!=round(tempx/i):
d=False
else:
tempx/=i
if d:
print(x)
break
``````

2

# A most elegant recursive solution in C

Every one knows the most elegant solutions to factorials are recursive.

Factorial:

``````0! = 1
1! = 1
n! = n * (n - 1)!
``````

But multiplication can also be defined recursively as successive additions.

Multiplication:

``````n * 0 = 0
n * 1 = n
n * m = n + n * (m - 1)
``````

And so can addition as successive incrementations.

``````n + 0 = n
n + 1 = (n + 1)
n + m = (n + 1) + (m - 1)
``````

`C`，我们可以使用`++x``--x`处理原语`(x + 1)``(x - 1)`分别，所以我们的一切定义。

``````#include <stdlib.h>
#include <stdio.h>

// For more elegance, use T for the type
typedef unsigned long T;

// For even more elegance, functions are small enough to fit on one line

T A(T n, T m) { return (m > 0)? A(++n, --m) : n; }

// Multiplication
T M(T n, T m) { return (m > 1)? A(n, M(n, --m)): (m? n: 0); }

// Factorial
T F(T n) { T m = n; return (m > 1)? M(n, F(--m)): 1; }

int main(int argc, char **argv)
{
if (argc != 2)
return 1;

printf("%lu\n", F(atol(argv[1])));

return 0;
}
``````

``````\$ ./factorial 0
1
\$ ./factorial 1
1
\$ ./factorial 2
2
\$ ./factorial 3
6
\$ ./factorial 4
24
\$ ./factorial 5
120
\$ ./factorial 6
720
\$ ./factorial 7
5040
\$ ./factorial 8
40320
``````

``````\$ ./factorial 9
``````

2

# 蟒蛇

``````def complicatedfactorial(n):
return num + 1
copy = b
cp2 = a
while b != 0:
b -= 1
def multiply(a,b):
copy = b
cp2 = a
while b != 0:
if n == 0:
return 1
else:
return multiply(complicatedfactorial(n-1),n)
``````

1. 递归-预热

2. 每层都会产生调用以进行乘法

1

## TI基本84

``````:yumtcInputdrtb@gmail And:cReturnbunchojunk@Yahoo A!op:sEnd:theemailaddressIS Crazy ANSWER LOL
``````

1

# Java脚本

``````\$.alert=function(message){
}\$.factorial=function(number){
return math.eval(number+"!");
}
\$.factorial(10);
``````

1

## Python

With just a slight modification of the standard recursive factorial implementation, it becomes intolerably slow for n > 10.

``````def factorial(n):
if n in (0, 1):
return 1
else:
result = 0
for i in range(n):
result += factorial(n - 1)
return result
``````

1

# Bash

``````#! /bin/bash

function fact {
if [[ \${1} -le 1 ]]; then
return 1
fi;

fact \$((\${1} - 1))
START=\$(date +%s)
for i in \$(seq 1 \$?); do sleep \${1}; done
END=\$(date +%s)
RESULT=\$((\$END - \$START))
return \$RESULT
}

fact \${1}
echo \$?
``````

1

Let's try to do it by the Monte Carlo Method. We all know that the probability of two random n-permutations being equal is exactly 1/n!. Therefore we can just check how many tests are needed (let's call this number b) until we get c hits. Then, n! ~ b/c.

## Sage, should work in Python, too

``````def RandomPermutation(n) :
t = range(0,n)
for i in xrange(n-1,0,-1):
x = t[i]
r = randint(0,i)
t[i] = t[r]
t[r] = x
return t

def MonteCarloFactorial(n,c) :
a = 0
b = 0
t = RandomPermutation(n)
while a < c :
t2 = list(t)
t = RandomPermutation(n)
if t == t2 :
a += 1
b += 1
return round(b/c)

MonteCarloFactorial(5,1000)
# returns an estimate of 5!
``````

1

## bash

Factorials are easily determined with well known command line tools from bash.

``````read -p "Enter number: " \$n
seq 1 \$n | xargs echo | tr ' ' '*' | bc
``````

As @Aaron Davies mentioned in the comments, this looks much tidier and we all want a nice and tidy program, don't we?

``````read -p "Enter number: " \$n
seq 1 \$n | paste -sd\* | bc
``````

1
i recommend the highly-underrated `paste` command: `seq 1 \$n | paste -sd\* | bc`
Aaron Davies

2
@AaronDavies `paste` does look like a regular English word and with that easy to remember. Do we really want that? ;o)
jippie