我希望看到所有不同的方法,一个阶乘子程序或程序。希望任何人都可以来这里看看他们是否想要学习一门新语言。
基本上我想看一个例子,不同的编写算法的方式,以及它们在不同语言中的样子。
请将其限制为每个条目一个示例。 如果你试图突出一个特定的风格,语言,或者仅仅是一个经过深思熟虑的想法,我会允许你在每个答案中有不止一个例子。
唯一真正的要求是它必须在所有代表的语言中找到给定参数的阶乘。
# Language Name: Optional Style type - Optional bullet points Code Goes Here Other informational text goes here
我会偶尔编辑任何没有合适格式的答案。
答案 0 :(得分:184)
所以,我写了一个多语言,它使用我经常写的三种语言,以及我对这个问题的另一个答案和我今天刚学到的一种语言。它是一个独立程序,它读取包含非负整数的单行并打印包含其阶乘的单行。 Bignums用于所有语言,因此最大可计算因子仅取决于计算机的资源。
perl FILENAME
。runhugs FILENAME
或您喜欢的编译器等效运行。g++ -lgmpxx -lgmp -x c++ FILENAME
链接到正确的库。编译后,运行./a.out
。或者使用您最喜欢的编译器等效。bf < FILENAME > EXECUTABLE
进行编译。使输出可执行并运行它。或者使用您喜欢的发行版。wspace FILENAME
。 编辑:将Whitespace添加为第五种语言。顺便说一句,不用<code>
标签包装代码;它打破了空白。此外,代码在固定宽度上看起来更好。
char //# b=0+0{- |0*/; #>>>>,----------[>>>>,-------- #define a/*#--]>>>>++<<<<<<<<[>++++++[<------>-]<-<<< #Perl ><><><> <> <> <<]>>>>[[>>+<<-]>>[<<+>+>-]<-> #C++ --><><> <><><>< > < > < +<[>>>>+<<<-<[-]]>[-] #Haskell >>]>[-<<<<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]>>] #Whitespace >>>>[-[>+<-]+>>>>]<<<<[<<<<]<<<<[<<<< #brainf*ck > < ]>>>>>[>>>[>>>>]>>>>[>>>>]<<<<[[>>>>*/ exp; ;//;#+<<<<-]<<<<]>>>>+<<<<<<<[<<<<][.POLYGLOT^5. #include <gmpxx.h>//]>>>>-[>>>[>>>>]>>>>[>>>>]<<<<[>> #define eval int main()//>+<<<-]>>>[<<<+>>+>-> #include <iostream>//<]<-[>>+<<[-]]<<[<<<<]>>>>[>[>>> #define print std::cout << // > <+<-]>[<<+>+>-]<<[>>> #define z std::cin>>//<< +<<<-]>>>[<<<+>>+>-]<->+++++ #define c/*++++[-<[-[>>>>+<<<<-]]>>>>[<<<<+>>>>-]<<*/ #define abs int $n //>< <]<[>>+<<<<[-]>>[<<+>>-]]>>]< #define uc mpz_class fact(int $n){/*<<<[<<<<]<<<[<< use bignum;sub#<<]>>>>-]>>>>]>>>[>[-]>>>]<<<<[>>+<<-] z{$_[0+0]=readline(*STDIN);}sub fact{my($n)=shift;#>> #[<<+>+>-]<->+<[>-<[-]]>[-<<-<<<<[>>+<<-]>>[<<+>+>+*/ uc;if($n==0){return 1;}return $n*fact($n-1); }//;# eval{abs;z($n);print fact($n);print("\n")/*2;};#-]<-> '+<[>-<[-]]>]<<[<<<<]<<<<-[>>+<<-]>>[<<+>+>-]+<[>-+++ -}-- <[-]]>[-<<++++++++++<<<<-[>>+<<-]>>[<<+>+>-++ fact 0 = 1 -- ><><><>< > <><>< ]+<[>-<[-]]>]<<[<<+ + fact n=n*fact(n-1){-<<]>>>>[[>>+<<-]>>[<<+>+++>+-} main=do{n<-readLn;print(fact n)}-- +>-]<->+<[>>>>+<<+ {-x<-<[-]]>[-]>>]>]>>>[>>>>]<<<<[>+++++++[<+++++++>-] <--.<<<<]+written+by+++A+Rex+++2009+.';#+++x-}--x*/;}
答案 1 :(得分:124)
HAI
CAN HAS STDIO?
I HAS A VAR
I HAS A INT
I HAS A CHEEZBURGER
I HAS A FACTORIALNUM
IM IN YR LOOP
UP VAR!!1
TIEMZD INT!![CHEEZBURGER]
UP FACTORIALNUM!!1
IZ VAR BIGGER THAN FACTORIALNUM? GTFO
IM OUTTA YR LOOP
U SEEZ INT
KTHXBYE
答案 2 :(得分:52)
这是速度更快的算法之一,最高可达170!。它fails莫名其妙地超过170!,对于小因子而言相对较慢,但对于80和170之间的因子,与许多算法相比,它的速度非常快。
curl http://www.google.com/search?q=170!
还有一个在线界面try it out now!
如果您发现错误或更快地执行大型因素,请告诉我。
此算法稍慢,但结果超出170:
curl http://www58.wolframalpha.com/input/?i=171!
它还将它们简化为各种其他表示形式。
答案 3 :(得分:48)
使用经典的enum hack。
template<unsigned int n>
struct factorial {
enum { result = n * factorial<n - 1>::result };
};
template<>
struct factorial<0> {
enum { result = 1 };
};
使用。
const unsigned int x = factorial<4>::result;
基于模板参数n,在编译时完全计算因子。因此,一旦编译器完成其工作,factorial&lt; 4&gt; :: result就是常量。
答案 4 :(得分:34)
. . . . . . . . . . . . . . . . . . . . . . . . . .
很难让它在这里正确显示,但现在我尝试从预览中复制它并且它有效。您需要输入数字并按Enter键。
答案 5 :(得分:34)
答案 6 :(得分:26)
C#查找:
无需计算,只需查阅即可。要扩展它,将另外8个数字添加到表中,64位整数处于其限制。除此之外,还需要一个BigNum类。
public static int Factorial(int f)
{
if (f<0 || f>12)
{
throw new ArgumentException("Out of range for integer factorial");
}
int [] fact={1,1,2,6,24,120,720,5040,40320,362880,3628800,
39916800,479001600};
return fact[f];
}
答案 7 :(得分:26)
你纯粹的功能编程噩梦成真了!
唯一拥有Esoteric Turing-complete Programming Language的内容:
这是所有括号荣耀中的因子代码:
K(SII(S(K(S(S(KS)(S(K(S(KS)))(S(K(S(KK)))(S(K(S(K(S(K(S(K(S(SI(K(S(K(S(S(KS)K)I))
(S(S(KS)K)(SII(S(S(KS)K)I))))))))K))))))(S(K(S(K(S(SI(K(S(K(S(SI(K(S(K(S(S(KS)K)I))
(S(S(KS)K)(SII(S(S(KS)K)I))(S(S(KS)K))(S(SII)I(S(S(KS)K)I))))))))K)))))))
(S(S(KS)K)(K(S(S(KS)K)))))))))(K(S(K(S(S(KS)K)))K))))(SII))II)
特点:
如果您有兴趣尝试理解它,这里是通过Lazier编译器运行的Scheme源代码:
(lazy-def '(fac input)
'((Y (lambda (f n a) ((lambda (b) ((cons 10) ((b (cons 42)) (f (1+ n) b))))
(* a n)))) 1 1))
(对于Y,缺点,1,10,42,1 +和*的合适定义。)
编辑:
(10KB of gibberish或者我会粘贴它)。例如,在Unix提示符下:
$ echo "4" | ./lazy facdec.lazy 24 $ echo "5" | ./lazy facdec.lazy 120
上述数字相当慢,比如5。
代码有点臃肿,因为我们必须包含library code for all of our own primitives(用Hazy编写的代码,lambda演算解释器和用Haskell编写的LC-to-Lazy K编译器)。
答案 8 :(得分:21)
输入文件 factorial.xml :
<?xml version="1.0"?>
<?xml-stylesheet href="factorial.xsl" type="text/xsl" ?>
<n>
20
</n>
XSLT文件 factorial.xsl :
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" >
<xsl:output method="text"/>
<!-- 0! = 1 -->
<xsl:template match="text()[. = 0]">
1
</xsl:template>
<!-- n! = (n-1)! * n-->
<xsl:template match="text()[. > 0]">
<xsl:variable name="x">
<xsl:apply-templates select="msxsl:node-set( . - 1 )/text()"/>
</xsl:variable>
<xsl:value-of select="$x * ."/>
</xsl:template>
<!-- Calculate n! -->
<xsl:template match="/n">
<xsl:apply-templates select="text()"/>
</xsl:template>
</xsl:stylesheet>
将这两个文件保存在同一目录中,然后在IE中打开 factorial.xml 。
答案 9 :(得分:19)
factorial = lambda n: reduce(lambda x,y: x*y, range(1, n+1), 1)
注:
print factorial(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915\
608941463976156518286253697920827223758251185210916864000000000000000000000000
答案 10 :(得分:18)
×/⍳X
或使用内置运算符:
!X
来源:http://www.webber-labs.com/mpl/lectures/ppt-slides/01.ppt
答案 11 :(得分:15)
sub factorial ($n) { [*] 1..$n }
我几乎不知道Perl6。但我猜这个[*]
运算符与Haskell的product
相同。
修改强>
此代码也有效。
sub postfix:<!> ($n) { [*] 1..$n }
# This function(?) call like below ... It looks like mathematical notation.
say 10!;
答案 12 :(得分:14)
你可以用C调用它(只在linux amd64上用GCC测试过)。 大会与nasm组装在一起。
section .text
global factorial
; factorial in x86-64 - n is passed in via RDI register
; takes a 64-bit unsigned integer
; returns a 64-bit unsigned integer in RAX register
; C declaration in GCC:
; extern unsigned long long factorial(unsigned long long n);
factorial:
enter 0,0
; n is placed in rdi by caller
mov rax, 1 ; factorial = 1
mov rcx, 2 ; i = 2
loopstart:
cmp rcx, rdi
ja loopend
mul rcx ; factorial *= i
inc rcx
jmp loopstart
loopend:
leave
ret
答案 13 :(得分:13)
(它提醒你COBOL,因为它是用于编写文本冒险;比例字体是故意的):
决定什么数字是(n - 数字)的阶乘:
如果n为零,则决定一个;
否则决定(n减1)乘以n的阶乘。
如果你想从游戏中实际调用这个函数(“短语”),你需要定义一个动作和语法规则:
“阶乘游戏”[这必须是来源的第一行]
有一个房间。 [必须至少有一个!]
Factorialing是一个适用于数字的行为。
将“factorial [a number]”理解为factorialing。
执行推理:
设n是理解数的阶乘;
说“这是[n]”。
答案 14 :(得分:12)
Haskell中:
ones = 1 : ones
integers = head ones : zipWith (+) integers (tail ones)
factorials = head integers : zipWith (*) factorials (tail integers)
答案 15 :(得分:12)
public static int factorial(int n)
{
return (Enumerable.Range(1, n).Aggregate(1, (previous, value) => previous * value));
}
答案 16 :(得分:12)
fac(0) -> 1;
fac(N) when N > 0 -> fac(N, 1).
fac(1, R) -> R;
fac(N, R) -> fac(N - 1, R * N).
答案 17 :(得分:11)
+++++
>+<[[->>>>+<<<<]>>>>[-<<<<+>>+>>]<<<<>[->>+<<]<>>>[-<[->>+<<]>>[-<<+<+>>>]<]<[-]><<<-]
Michael Reitzenstein撰写。
答案 18 :(得分:10)
10 HOME
20 INPUT N
30 LET ANS = 1
40 FOR I = 1 TO N
50 ANS = ANS * I
60 NEXT I
70 PRINT ANS
答案 19 :(得分:9)
let rec fact x =
if x < 0 then failwith "Invalid value."
elif x = 0 then 1
else x * fact (x - 1)
let fact x = [1 .. x] |> List.fold_left ( * ) 1
答案 20 :(得分:9)
批次(NT):
@echo off
set n=%1
set result=1
for /l %%i in (%n%, -1, 1) do (
set /a result=result * %%i
)
echo %result%
使用方法: C:&gt; factorial.bat 15
答案 21 :(得分:8)
fac(0,1).
fac(N,X) :- N1 is N -1, fac(N1, T), X is N * T.
fac(0,N,N).
fac(X,N,T) :- A is N * X, X1 is X - 1, fac(X1,A,T).
fac(N,T) :- fac(N,1,T).
答案 22 :(得分:8)
(factorial=Hash.new{|h,k|k*h[k-1]})[1]=1
用法:
factorial[5]
=> 120
答案 23 :(得分:7)
<强>方案强>
这是一个简单的递归定义:
(define (factorial x)
(if (= x 0) 1
(* x (factorial (- x 1)))))
在Scheme中,tail-recursive函数使用常量堆栈空间。这是一个尾递归的阶乘版本:
(define factorial
(letrec ((fact (lambda (x accum)
(if (= x 0) accum
(fact (- x 1) (* accum x))))))
(lambda (x)
(fact x 1))))
答案 24 :(得分:7)
template factorial(int n : 1)
{
const factorial = 1;
}
template factorial(int n)
{
const factorial =
n * factorial!(n-1);
}
或
template factorial(int n)
{
static if(n == 1)
const factorial = 1;
else
const factorial =
n * factorial!(n-1);
}
像这样使用:
factorial!(5)
答案 25 :(得分:7)
Oddball的例子?怎么样使用伽玛功能!自,Gamma n = (n-1)!
。
let rec gamma z =
let pi = 4.0 *. atan 1.0 in
if z < 0.5 then
pi /. ((sin (pi*.z)) *. (gamma (1.0 -. z)))
else
let consts = [| 0.99999999999980993; 676.5203681218851; -1259.1392167224028;
771.32342877765313; -176.61502916214059; 12.507343278686905;
-0.13857109526572012; 9.9843695780195716e-6; 1.5056327351493116e-7;
|]
in
let z = z -. 1.0 in
let results = Array.fold_right
(fun x y -> x +. y)
(Array.mapi
(fun i x -> if i = 0 then x else x /. (z+.(float i)))
consts
)
0.0
in
let x = z +. (float (Array.length consts)) -. 1.5 in
let final = (sqrt (2.0*.pi)) *.
(x ** (z+.0.5)) *.
(exp (-.x)) *. result
in
final
let factorial_gamma n = int_of_float (gamma (float (n+1)))
答案 26 :(得分:7)
新生Haskell程序员
fac n = if n == 0
then 1
else n * fac (n-1)
麻省理工学院的二年级学生Haskell程序员
(作为新生学习计划)
fac = (\(n) ->
(if ((==) n 0)
then 1
else ((*) n (fac ((-) n 1)))))
Junior Haskell程序员 (开始Peano球员)
fac 0 = 1
fac (n+1) = (n+1) * fac n
另一位初级Haskell程序员 (读到n + k模式是“Haskell令人作呕的一部分”[1] 并加入了“Ban n + k模式” - 运动[2])
fac 0 = 1
fac n = n * fac (n-1)
高级Haskell程序员 (投票给尼克松布坎南布什 - “向右倾斜”)
fac n = foldr (*) 1 [1..n]
另一位高级Haskell程序员 (投票给麦戈文比亚夫拉纳德 - “左倾”)
fac n = foldl (*) 1 [1..n]
又一位高级Haskell程序员 (向右倾斜,他又回来了!)
-- using foldr to simulate foldl
fac n = foldr (\x g n -> g (x*n)) id [1..n] 1
记住Haskell程序员 (每日服用银杏叶)
facs = scanl (*) 1 [1..]
fac n = facs !! n
无意义(咳咳)“无点”Haskell程序员 (在牛津大学学习)
fac = foldr (*) 1 . enumFromTo 1
Isterative Haskell程序员 (前Pascal程序员)
fac n = result (for init next done)
where init = (0,1)
next (i,m) = (i+1, m * (i+1))
done (i,_) = i==n
result (_,m) = m
for i n d = until d n i
迭代单行Haskell程序员 (前APL和C程序员)
fac n = snd (until ((>n) . fst) (\(i,m) -> (i+1, i*m)) (1,1))
累积Haskell程序员 (建立一个快速的高潮)
facAcc a 0 = a
facAcc a n = facAcc (n*a) (n-1)
fac = facAcc 1
继续传递Haskell程序员 (早年养了兔子,然后搬到了新泽西州)
facCps k 0 = k 1
facCps k n = facCps (k . (n *)) (n-1)
fac = facCps id
童子军Haskell程序员 (喜欢打结;总是“虔诚”,他 属于最低定点教会[8])
y f = f (y f)
fac = y (\f n -> if (n==0) then 1 else n * f (n-1))
组合Haskell程序员 (如果不是混淆,则避开变量; 所有这些只是一个阶段,虽然它很少阻碍)
s f g x = f x (g x)
k x y = x
b f g x = f (g x)
c f g x = f x g
y f = f (y f)
cond p f g x = if p x then f x else g x
fac = y (b (cond ((==) 0) (k 1)) (b (s (*)) (c b pred)))
列表编码Haskell程序员 (更喜欢用一元计算)
arb = () -- "undefined" is also a good RHS, as is "arb" :)
listenc n = replicate n arb
listprj f = length . f . listenc
listprod xs ys = [ i (x,y) | x<-xs, y<-ys ]
where i _ = arb
facl [] = listenc 1
facl n@(_:pred) = listprod n (facl pred)
fac = listprj facl
解释性Haskell程序员 (从不“遇到他不喜欢的语言”)
-- a dynamically-typed term language
data Term = Occ Var
| Use Prim
| Lit Integer
| App Term Term
| Abs Var Term
| Rec Var Term
type Var = String
type Prim = String
-- a domain of values, including functions
data Value = Num Integer
| Bool Bool
| Fun (Value -> Value)
instance Show Value where
show (Num n) = show n
show (Bool b) = show b
show (Fun _) = ""
prjFun (Fun f) = f
prjFun _ = error "bad function value"
prjNum (Num n) = n
prjNum _ = error "bad numeric value"
prjBool (Bool b) = b
prjBool _ = error "bad boolean value"
binOp inj f = Fun (\i -> (Fun (\j -> inj (f (prjNum i) (prjNum j)))))
-- environments mapping variables to values
type Env = [(Var, Value)]
getval x env = case lookup x env of
Just v -> v
Nothing -> error ("no value for " ++ x)
-- an environment-based evaluation function
eval env (Occ x) = getval x env
eval env (Use c) = getval c prims
eval env (Lit k) = Num k
eval env (App m n) = prjFun (eval env m) (eval env n)
eval env (Abs x m) = Fun (\v -> eval ((x,v) : env) m)
eval env (Rec x m) = f where f = eval ((x,f) : env) m
-- a (fixed) "environment" of language primitives
times = binOp Num (*)
minus = binOp Num (-)
equal = binOp Bool (==)
cond = Fun (\b -> Fun (\x -> Fun (\y -> if (prjBool b) then x else y)))
prims = [ ("*", times), ("-", minus), ("==", equal), ("if", cond) ]
-- a term representing factorial and a "wrapper" for evaluation
facTerm = Rec "f" (Abs "n"
(App (App (App (Use "if")
(App (App (Use "==") (Occ "n")) (Lit 0))) (Lit 1))
(App (App (Use "*") (Occ "n"))
(App (Occ "f")
(App (App (Use "-") (Occ "n")) (Lit 1))))))
fac n = prjNum (eval [] (App facTerm (Lit n)))
静态Haskell程序员 (他是上课的,他有那个有趣的琼斯! 在Thomas Hallgren的“功能依赖性的乐趣”之后[7])
-- static Peano constructors and numerals
data Zero
data Succ n
type One = Succ Zero
type Two = Succ One
type Three = Succ Two
type Four = Succ Three
-- dynamic representatives for static Peanos
zero = undefined :: Zero
one = undefined :: One
two = undefined :: Two
three = undefined :: Three
four = undefined :: Four
-- addition, a la Prolog
class Add a b c | a b -> c where
add :: a -> b -> c
instance Add Zero b b
instance Add a b c => Add (Succ a) b (Succ c)
-- multiplication, a la Prolog
class Mul a b c | a b -> c where
mul :: a -> b -> c
instance Mul Zero b Zero
instance (Mul a b c, Add b c d) => Mul (Succ a) b d
-- factorial, a la Prolog
class Fac a b | a -> b where
fac :: a -> b
instance Fac Zero One
instance (Fac n k, Mul (Succ n) k m) => Fac (Succ n) m
-- try, for "instance" (sorry):
--
-- :t fac four
毕业的Haskell程序员 (研究生教育倾向于从小问题中解放出来 关于,例如,基于硬件的整数的效率)
-- the natural numbers, a la Peano
data Nat = Zero | Succ Nat
-- iteration and some applications
iter z s Zero = z
iter z s (Succ n) = s (iter z s n)
plus n = iter n Succ
mult n = iter Zero (plus n)
-- primitive recursion
primrec z s Zero = z
primrec z s (Succ n) = s n (primrec z s n)
-- two versions of factorial
fac = snd . iter (one, one) (\(a,b) -> (Succ a, mult a b))
fac' = primrec one (mult . Succ)
-- for convenience and testing (try e.g. "fac five")
int = iter 0 (1+)
instance Show Nat where
show = show . int
(zero : one : two : three : four : five : _) = iterate Succ Zero
Origamist Haskell程序员 (总是从“基本鸟褶”开始)
-- (curried, list) fold and an application
fold c n [] = n
fold c n (x:xs) = c x (fold c n xs)
prod = fold (*) 1
-- (curried, boolean-based, list) unfold and an application
unfold p f g x =
if p x
then []
else f x : unfold p f g (g x)
downfrom = unfold (==0) id pred
-- hylomorphisms, as-is or "unfolded" (ouch! sorry ...)
refold c n p f g = fold c n . unfold p f g
refold' c n p f g x =
if p x
then n
else c (f x) (refold' c n p f g (g x))
-- several versions of factorial, all (extensionally) equivalent
fac = prod . downfrom
fac' = refold (*) 1 (==0) id pred
fac'' = refold' (*) 1 (==0) id pred
笛卡尔倾向于Haskell程序员 (喜欢希腊食物,避免辛辣的印度菜; 灵感来自Lex Augusteijn的“Sorting Morphisms”[3])
-- (product-based, list) catamorphisms and an application
cata (n,c) [] = n
cata (n,c) (x:xs) = c (x, cata (n,c) xs)
mult = uncurry (*)
prod = cata (1, mult)
-- (co-product-based, list) anamorphisms and an application
ana f = either (const []) (cons . pair (id, ana f)) . f
cons = uncurry (:)
downfrom = ana uncount
uncount 0 = Left ()
uncount n = Right (n, n-1)
-- two variations on list hylomorphisms
hylo f g = cata g . ana f
hylo' f (n,c) = either (const n) (c . pair (id, hylo' f (c,n))) . f
pair (f,g) (x,y) = (f x, g y)
-- several versions of factorial, all (extensionally) equivalent
fac = prod . downfrom
fac' = hylo uncount (1, mult)
fac'' = hylo' uncount (1, mult)
博士。 Haskell程序员 (吃了很多香蕉,他的眼睛出了问题,现在他需要新的镜片!)
-- explicit type recursion based on functors
newtype Mu f = Mu (f (Mu f)) deriving Show
in x = Mu x
out (Mu x) = x
-- cata- and ana-morphisms, now for *arbitrary* (regular) base functors
cata phi = phi . fmap (cata phi) . out
ana psi = in . fmap (ana psi) . psi
-- base functor and data type for natural numbers,
-- using a curried elimination operator
data N b = Zero | Succ b deriving Show
instance Functor N where
fmap f = nelim Zero (Succ . f)
nelim z s Zero = z
nelim z s (Succ n) = s n
type Nat = Mu N
-- conversion to internal numbers, conveniences and applications
int = cata (nelim 0 (1+))
instance Show Nat where
show = show . int
zero = in Zero
suck = in . Succ -- pardon my "French" (Prelude conflict)
plus n = cata (nelim n suck )
mult n = cata (nelim zero (plus n))
-- base functor and data type for lists
data L a b = Nil | Cons a b deriving Show
instance Functor (L a) where
fmap f = lelim Nil (\a b -> Cons a (f b))
lelim n c Nil = n
lelim n c (Cons a b) = c a b
type List a = Mu (L a)
-- conversion to internal lists, conveniences and applications
list = cata (lelim [] (:))
instance Show a => Show (List a) where
show = show . list
prod = cata (lelim (suck zero) mult)
upto = ana (nelim Nil (diag (Cons . suck)) . out)
diag f x = f x x
fac = prod . upto
博士后Haskell程序员 (来自Uustalu,Vene和Pardo的“来自Comonads的递归计划”[4])
-- explicit type recursion with functors and catamorphisms
newtype Mu f = In (f (Mu f))
unIn (In x) = x
cata phi = phi . fmap (cata phi) . unIn
-- base functor and data type for natural numbers,
-- using locally-defined "eliminators"
data N c = Z | S c
instance Functor N where
fmap g Z = Z
fmap g (S x) = S (g x)
type Nat = Mu N
zero = In Z
suck n = In (S n)
add m = cata phi where
phi Z = m
phi (S f) = suck f
mult m = cata phi where
phi Z = zero
phi (S f) = add m f
-- explicit products and their functorial action
data Prod e c = Pair c e
outl (Pair x y) = x
outr (Pair x y) = y
fork f g x = Pair (f x) (g x)
instance Functor (Prod e) where
fmap g = fork (g . outl) outr
-- comonads, the categorical "opposite" of monads
class Functor n => Comonad n where
extr :: n a -> a
dupl :: n a -> n (n a)
instance Comonad (Prod e) where
extr = outl
dupl = fork id outr
-- generalized catamorphisms, zygomorphisms and paramorphisms
gcata :: (Functor f, Comonad n) =>
(forall a. f (n a) -> n (f a))
-> (f (n c) -> c) -> Mu f -> c
gcata dist phi = extr . cata (fmap phi . dist . fmap dupl)
zygo chi = gcata (fork (fmap outl) (chi . fmap outr))
para :: Functor f => (f (Prod (Mu f) c) -> c) -> Mu f -> c
para = zygo In
-- factorial, the *hard* way!
fac = para phi where
phi Z = suck zero
phi (S (Pair f n)) = mult f (suck n)
-- for convenience and testing
int = cata phi where
phi Z = 0
phi (S f) = 1 + f
instance Show (Mu N) where
show = show . int
终身教授 (将Haskell教给新生)
fac n = product [1..n]
答案 27 :(得分:6)
PowerShell的
function factorial( [int] $n )
{
$result = 1;
if ( $n -gt 1 )
{
$result = $n * ( factorial ( $n - 1 ) )
}
$result
}
这是一个单行:
$n..1 | % {$result = 1}{$result *= $_}{$result}
答案 28 :(得分:6)
private static Map<BigInteger, BigInteger> _results = new HashMap()
public static BigInteger factorial(BigInteger n){
if (0 >= n.compareTo(BigInteger.ONE))
return BigInteger.ONE.max(n);
if (_results.containsKey(n))
return _results.get(n);
BigInteger result = factorial(n.subtract(BigInteger.ONE)).multiply(n);
_results.put(n, result);
return result;
}
答案 29 :(得分:6)
在bash和递归中,但具有额外的优势,即它处理新进程中的每次迭代。在溢出之前它可以计算的最大值是!20,但是如果你不关心答案并希望你的系统能够翻倒,你仍然可以运行大数字;)
#!/bin/bash
echo $(($1 * `( [[ $1 -gt 1 ]] && ./$0 $(($1 - 1)) ) || echo 1`));
答案 30 :(得分:5)
C / C ++ :程序
unsigned long factorial(int n)
{
unsigned long factorial = 1;
int i;
for (i = 2; i <= n; i++)
factorial *= i;
return factorial;
}
PHP :程序
function factorial($n)
{
for ($factorial = 1, $i = 2; $i <= $n; $i++)
$factorial *= $i;
return $factorial;
}
@Niyaz:您没有为函数指定返回类型
答案 31 :(得分:5)
上述大部分内容的问题是它们在大约25时会耗尽精度! (12!有32位整数)或只是溢出。这是一个突破这些限制的c#实现!
class Number
{
public Number ()
{
m_number = "0";
}
public Number (string value)
{
m_number = value;
}
public int this [int column]
{
get
{
return column < m_number.Length ? m_number [m_number.Length - column - 1] - '0' : 0;
}
}
public static implicit operator Number (string rhs)
{
return new Number (rhs);
}
public static bool operator == (Number lhs, Number rhs)
{
return lhs.m_number == rhs.m_number;
}
public static bool operator != (Number lhs, Number rhs)
{
return lhs.m_number != rhs.m_number;
}
public override bool Equals (object obj)
{
return this == (Number) obj;
}
public override int GetHashCode ()
{
return m_number.GetHashCode ();
}
public static Number operator + (Number lhs, Number rhs)
{
StringBuilder
result = new StringBuilder (new string ('0', lhs.m_number.Length + rhs.m_number.Length));
int
carry = 0;
for (int i = 0 ; i < result.Length ; ++i)
{
int
sum = carry + lhs [i] + rhs [i],
units = sum % 10;
carry = sum / 10;
result [result.Length - i - 1] = (char) ('0' + units);
}
return TrimLeadingZeros (result);
}
public static Number operator * (Number lhs, Number rhs)
{
StringBuilder
result = new StringBuilder (new string ('0', lhs.m_number.Length + rhs.m_number.Length));
for (int multiplier_index = rhs.m_number.Length - 1 ; multiplier_index >= 0 ; --multiplier_index)
{
int
multiplier = rhs.m_number [multiplier_index] - '0',
column = result.Length - rhs.m_number.Length + multiplier_index;
for (int i = lhs.m_number.Length - 1 ; i >= 0 ; --i, --column)
{
int
product = (lhs.m_number [i] - '0') * multiplier,
units = product % 10,
tens = product / 10,
hundreds = 0,
unit_sum = result [column] - '0' + units;
if (unit_sum > 9)
{
unit_sum -= 10;
++tens;
}
result [column] = (char) ('0' + unit_sum);
int
tens_sum = result [column - 1] - '0' + tens;
if (tens_sum > 9)
{
tens_sum -= 10;
++hundreds;
}
result [column - 1] = (char) ('0' + tens_sum);
if (hundreds > 0)
{
int
hundreds_sum = result [column - 2] - '0' + hundreds;
result [column - 2] = (char) ('0' + hundreds_sum);
}
}
}
return TrimLeadingZeros (result);
}
public override string ToString ()
{
return m_number;
}
static string TrimLeadingZeros (StringBuilder number)
{
while (number [0] == '0' && number.Length > 1)
{
number.Remove (0, 1);
}
return number.ToString ();
}
string
m_number;
}
static void Main (string [] args)
{
Number
a = new Number ("1"),
b = new Number (args [0]),
one = new Number ("1");
for (Number c = new Number ("1") ; c != b ; )
{
c = c + one;
a = a * c;
}
Console.WriteLine (string.Format ("{0}! = {1}", new object [] { b, a }));
}
FWIW:10000!超过35500个字符。
Skizz
答案 32 :(得分:5)
输入和输出是教会数字(即自然数k
是\f n. f^k n
;所以3 = \f n. f (f (f n)))
(\x. x x) (\y f. f (y y f)) (\y n. n (\x y z. z) (\x y. x) (\f n. f n) (\f. n (y (\f m. n (\g h. h (g f)) (\x. m) (\x. x)) f)))
答案 33 :(得分:5)
下面的代码是舌头,但是当你考虑到返回值被限制为n <1时。对于uint32 34,&lt; 65 uint64,在我们用uint返回值的空间之前,硬编码33值并不那么疯狂:)
public static int Factorial(int n)
{
switch (n)
{
case 1:
return 1;
case 2:
return 2;
case 3:
return 6;
case 4:
return 24;
default:
throw new Exception("Sorry, I can only count to 4");
}
}
答案 34 :(得分:4)
Ruby:功能
def factorial(n)
return 1 if n == 1
n * factorial(n -1)
end
答案 35 :(得分:4)
procedure factorial(n)
return (0<n) * factorial(n-1) | 1
end
我已经欺骗了一些允许负数返回1.如果你想让它失败,给出一个负面的论点,它会略微简洁:
return (0<n) * factorial(n-1) | (n=0 & 1)
然后
write(factorial(3))
write(factorial(-1))
write(factorial(20))
打印
6
2432902008176640000
procedure factorials()
local f,n
f := 1; n := 0
repeat suspend f *:= (n +:= 1)
end
然后
every write(factorials() \ 5)
打印
1
2
6
24
120
要理解这一点:评估是目标导向的,并且在失败时回溯。没有布尔类型,并且在其他语言中返回布尔值的二元运算符要么失败要么返回它们的第二个参数 - 除了|,如果成功则在单值上下文中返回其第一个参数,否则尝试其第二个论点。 (在多值上下文中,它返回其第一个参数然后它的第二个参数)
suspend
与其他语言中的yield
类似,不同之处在于未多次显式调用生成器以返回其结果。代替,
every
询问所有值的参数,但默认情况下不返回任何值;它对副作用很有用(在这种情况下是I / O)。
\
限制生成器返回的值的数量,在factorials
的情况下,它将是无限的。
答案 36 :(得分:4)
(defn fact
([n] (fact n 1))
([n acc] (if (= n 0)
acc
(recur (- n 1) (* acc n)))))
(defn fact [n] (apply * (range 1 (+ n 1))))
答案 37 :(得分:4)
factorial n = product [1..n]
答案 38 :(得分:4)
没有什么比 bash &amp;的 BC 强>:
function fac { seq $1 | paste -sd* | bc; }
$ fac 42
1405006117752879898543142606244511569936384000000000
$
答案 39 :(得分:3)
Mathematica :使用纯递归函数
(If[#>1,# #0[#-1],1])&
答案 40 :(得分:3)
function factorial (n)
if (n <= 1) then return 1 end
return n*factorial(n-1)
end
这是一个在野外陷入的堆栈溢出:
> print (factorial(234132))
stdin:3: stack overflow
stack traceback:
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
...
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:3: in function 'factorial'
stdin:1: in main chunk
[C]: ?
答案 41 :(得分:3)
Agda 2:功能性,依赖性打字。
data Nat = zero | suc (m::Nat)
add (m::Nat) (n::Nat) :: Nat
= case m of
(zero ) -> n
(suc p) -> suc (add p n)
mul (m::Nat) (n::Nat)::Nat
= case m of
(zero ) -> zero
(suc p) -> add n (mul p n)
factorial (n::Nat)::Nat
= case n of
(zero ) -> suc zero
(suc p) -> mul n (factorial p)
答案 42 :(得分:3)
facts: array[2..12] of integer;
function TForm1.calculate(f: integer): integer;
begin
if f = 1 then
Result := f
else if f > High(facts) then
Result := High(Integer)
else if (facts[f] > 0) then
Result := facts[f]
else begin
facts[f] := f * Calculate(f-1);
Result := facts[f];
end;
end;
initialize
for i := Low(facts) to High(facts) do
facts[i] := 0;
在第一次计算出高于或等于所需值的阶乘后,该算法只返回恒定时间O(1)中的阶乘。
考虑到int32最多只能容纳12个!
答案 43 :(得分:3)
Nemerle:功能性
def fact(n) {
| 0 => 1
| x => x * fact(x-1)
}
答案 44 :(得分:3)
#Language: T-SQL
#Style: Recursive, divide and conquer
只是为了好玩 - 在T-SQL中使用分而治之的递归方法。是的,递归 - 在没有堆栈溢出的SQL中。
create function factorial(@b int=1, @e int) returns float as begin
return case when @b>=@e then @e else
convert(float,dbo.factorial(@b,convert(int,@b+(@e-@b)/2)))
* convert(float,dbo.factorial(convert(int,@b+1+(@e-@b)/2),@e)) end
end
这样称呼:
print dbo.factorial(1,170) -- the 1 being the starting number
答案 45 :(得分:3)
/fact0 { dup 2 lt { pop } { 2 copy mul 3 1 roll 1 sub exch pop fact0 } ifelse } def
/fact { 1 exch fact0 } def
答案 46 :(得分:3)
Forth(递归):
: factorial ( n -- n ) dup 1 > if dup 1 - recurse * else drop 1 then ;
答案 47 :(得分:3)
阶乘可以在功能上定义为:
def fact(n: Int): BigInt = 1 to n reduceLeft(_*_)
传统上或更多
def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n
我们可以制作! Ints的有效方法:
object extendBuiltins extends Application {
class Factorizer(n: Int) {
def ! = 1 to n reduceLeft(_*_)
}
implicit def int2fact(n: Int) = new Factorizer(n)
println("10! = " + (10!))
}
答案 48 :(得分:3)
用C ++编译时间
template<unsigned i>
struct factorial
{ static const unsigned value = i * factorial<i-1>::value; };
template<>
struct factorial<0>
{ static const unsigned value = 1; };
在代码中使用:
Factorial<5>::value
答案 49 :(得分:3)
Java Script:使用“面试问题”计算位fnc的创意方法。
function nu(x)
{
var r=0
while( x ) {
x &= x-1
r++
}
return r
}
function fac(n)
{
var r= Math.pow(2,n-nu(n))
for ( var i=3 ; i <= n ; i+= 2 )
r *= Math.pow(i,Math.floor(Math.log(n/i)/Math.LN2)+1)
return r
}
最多可以工作21个!然后Chrome切换到科学记数法。灵感归功于缺乏睡眠和Knuth,等人的“具体数学”。
答案 50 :(得分:3)
接受非负整数后跟换行作为输入,并输出相应的因子,然后换行。
>>>>,----------[>>>>,----------]>>>>++<<<<<<<<[>++++++[<----
-->-]<-<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>>+<<<-<[-]]>[-]
>>]>[-<<<<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]>>]>>>>[-[>+<-]+>>>
>]<<<<[<<<<]<<<<[<<<<]>>>>>[>>>[>>>>]>>>>[>>>>]<<<<[[>>>>+<<
<<-]<<<<]>>>>+<<<<<<<[<<<<]>>>>-[>>>[>>>>]>>>>[>>>>]<<<<[>>>
+<<<-]>>>[<<<+>>+>-]<-[>>+<<[-]]<<[<<<<]>>>>[>[>+<-]>[<<+>+>
-]<<[>>>+<<<-]>>>[<<<+>>+>-]<->+++++++++[-<[-[>>>>+<<<<-]]>>
>>[<<<<+>>>>-]<<<]<[>>+<<<<[-]>>[<<+>>-]]>>]<<<<[<<<<]<<<[<<
<<]>>>>-]>>>>]>>>[>[-]>>>]<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-
]]>[-<<-<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-]]>]<<[<<<<]<<<<-[
>>+<<-]>>[<<+>+>-]+<[>-<[-]]>[-<<++++++++++<<<<-[>>+<<-]>>[<
<+>+>-]+<[>-<[-]]>]<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>
>+<<<-<[-]]>[-]>>]>]>>>[>>>>]<<<<[>+++++++[<+++++++>-]<--.<<
<<]++++++++++.
与之前发布的brainf * ck答案不同,此不会溢出任何内存位置。 (该实现将n!放在单个内存位置,在标准bf规则下将其有效地限制为小于6。)此程序将输出n!对于n的任何值,仅受时间和内存(或bf实现)的限制。例如,在我的机器上使用Urban Muller的编译器,计算1000需要12秒!考虑到程序只能向左/向右移动并递增/递减1,我认为这很不错。
信不信由你,这是我写的第一个bf计划;花了大约10个小时,大部分时间用于调试。不幸的是,我后来发现Daniel B Cristofani编写了一个factorial generator,它只输出了更大的因子,从未终止:
>++++++++++>>>+>+[>>>+[-[<<<<<[+<<<<<]>>[[-]>[<<+>+>-]<[>+<-
]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>>>>+>+<
<<<<<-[>+<-]]]]]]]]]]]>[<+>-]+>>>>>]<<<<<[<<<<<]>>>>>>>[>>>>
>]++[-<<<<<]>>>>>>-]+>>>>>]<[>++<-]<<<<[<[>+<-]<<<<]>>[->[-]
++++++[<++++++++>-]>>>>]<<<<<[<[>+>+<<-]>.<<<<<]>.>>>>]
他的节目要短得多,但他实际上是一名职业高尔夫球手。
答案 51 :(得分:3)
它是Agda2,使用非常好的Agda2语法。
module fac where
data Nat : Set where -- Peano numbers
zero : Nat
suc : Nat -> Nat
{-# BUILTIN NATURAL Nat #-}
{-# BUILTIN SUC suc #-}
{-# BUILTIN ZERO zero #-}
infixl 10 _+_ -- Addition over Peano numbers
_+_ : Nat -> Nat -> Nat
zero + n = n
(suc n) + m = suc (n + m)
infixl 20 _*_ -- Multiplication over Peano numbers
_*_ : Nat -> Nat -> Nat
zero * n = zero
n * zero = zero
(suc n) * (suc m) = suc n + (suc n * m)
_! : Nat -> Nat -- Factorial function, syntax: "x !"
zero ! = suc zero
(suc n) ! = (suc n) * (n !)
答案 52 :(得分:3)
<强>的Python:强> 功能,递归单线程使用短路布尔评估。
factorial = lambda n: ((n <= 1) and 1) or factorial(n-1) * n
答案 53 :(得分:2)
multi factorial ( Int $n where { $n <= 0 } ){
return 1;
}
multi factorial ( Int $n ){
return $n * factorial( $n-1 );
}
这也有效:
multi factorial(0) { 1 }
multi factorial(Int $n) { $n * factorial($n - 1) }
在Jonathan Worthington's上查看use.perl.org日记,了解有关上一个示例的详细信息。
答案 54 :(得分:2)
sub factorial ( int $n ){
my $result = 1;
loop ( ; $n > 0; $n-- ){
$result *= $n;
}
return $result;
}
答案 55 :(得分:2)
C:
编辑:实际上我猜C ++,因为for循环中的变量声明。
int factorial(int x) {
int product = 1;
for (int i = x; i > 0; i--) {
product *= i;
}
return product;
}
答案 56 :(得分:2)
factorial = function( n )
{
return n > 0 ? n * factorial( n - 1 ) : 1;
}
我不确定Factorial是什么,但是其他程序在javascript中执行的操作。
答案 57 :(得分:2)
<强>的Python:强>
递归
def fact(x):
return (1 if x==0 else x * fact(x-1))
使用迭代器
import operator
def fact(x):
return reduce(operator.mul, xrange(1, x+1))
答案 58 :(得分:2)
许多Mathematica解决方案中的两个(虽然!内置且高效):
(* returns pure function *)
(FixedPoint[(If[#[[2]]>1,{#[[1]]*#[[2]],#[[2]]-1},#])&,{1,n}][[1]])&
(* not using built-in, returns pure function, don't use: might build 1..n list *)
(Times @@ Range[#])&
答案 59 :(得分:2)
<Extension()> _
Public Function Product(ByVal xs As IEnumerable(Of Integer)) As Integer
Return xs.Aggregate(1, Function(a, b) a * b)
End Function
Public Function Fact(ByVal n As Integer) As Integer
Return Aggregate x In Enumerable.Range(1, n) Into Product()
End Function
这显示了如何在VB中使用Aggregate
关键字。 C#不能这样做(虽然C#当然可以直接调用扩展方法)。
答案 60 :(得分:2)
(define (factorial n)
(define (fac-times n acc)
(if (= n 0)
acc
(fac-times (- n 1) (* acc n))))
(if (< n 0)
(display "Wrong argument!")
(fac-times n 1)))
答案 61 :(得分:2)
def factorial(n)
(1 .. n).inject{|a, b| a*b}
end
def factorial(n)
n == 1 ? 1 : n * factorial(n-1)
end
答案 62 :(得分:2)
#Language: T-SQL
#Style: Big Numbers
这是另一个T-SQL解决方案 - 以大多数Rube Goldbergian方式支持大数字。很多基于集合的操作。试图保持它唯一的SQL。糟糕的表现(400!戴尔Latitude D830需要33秒)
create function bigfact(@x varchar(max)) returns varchar(max) as begin
declare @c int
declare @n table(n int,e int)
declare @f table(n int,e int)
set @c=0
while @c<len(@x) begin
set @c=@c+1
insert @n(n,e) values(convert(int,substring(@x,@c,1)),len(@x)-@c)
end
-- our current factorial
insert @f(n,e) select 1,0
while 1=1 begin
declare @p table(n int,e int)
delete @p
-- product
insert @p(n,e) select sum(f.n*n.n), f.e+n.e from @f f cross join @n n group by f.e+n.e
-- normalize
while 1=1 begin
delete @f
insert @f(n,e) select sum(n),e from (
select (n % 10) as n,e from @p union all
select (n/10) % 10,e+1 from @p union all
select (n/100) %10,e+2 from @p union all
select (n/1000)%10,e+3 from @p union all
select (n/10000) % 10,e+4 from @p union all
select (n/100000)% 10,e+5 from @p union all
select (n/1000000)%10,e+6 from @p union all
select (n/10000000) % 10,e+7 from @p union all
select (n/100000000)% 10,e+8 from @p union all
select (n/1000000000)%10,e+9 from @p
) f group by e having sum(n)>0
set @c=0
select @c=count(*) from @f where n>9
if @c=0 break
delete @p
insert @p(n,e) select n,e from @f
end
-- decrement
update @n set n=n-1 where e=0
-- normalize
while 1=1 begin
declare @e table(e int)
delete @e
insert @e(e) select e from @n where n<0
if @@rowcount=0 break
update @n set n=n+10 where e in (select e from @e)
update @n set n=n-1 where e in (select e+1 from @e)
end
set @c=0
select @c=count(*) from @n where n>0
if @c=0 break
end
select @c=max(e) from @f
set @x=''
declare @l varchar(max)
while @c>=0 begin
set @l='0'
select @l=convert(varchar(max),n) from @f where e=@c
set @x=@x+@l
set @c=@c-1
end
return @x
end
示例:
print dbo.bigfact('69')
返回:
171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000
答案 63 :(得分:2)
Moog moog => dac;
4.0 => moog.gain;
for (0 => int i; i < 8; i++) {
<<< factorial(i) >>>;
}
fun int factorial(int n) {
1 => int result;
if (n != 0) {
n * factorial(n - 1) => result;
}
Std.mtof(result % 128) => moog.freq;
0.25::second => now;
return result;
}
听起来像this。不是非常有趣,但是,嘿,这只是一个因子功能!
答案 64 :(得分:2)
简单的解决方案是最好的:
#include <stdexcept>;
long fact(long f)
{
static long fact [] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 1932053504, 1278945280, 2004310016, 2004189184 };
static long max = sizeof(fact)/sizeof(long);
if ((f < 0) || (f >= max))
{ throw std::range_error("Factorial Range Error");
}
return fact[f];
}
答案 65 :(得分:2)
(defun fact (n)
(loop for i from 1 to n
for acc = 1 then (* acc i)
finally (return acc)))
现在,如果有人能够提出基于FORMAT的版本......
答案 66 :(得分:2)
好的,我会自己尝试一下。
(defun format-fact (stream arg colonp atsignp &rest args)
(destructuring-bind (n acc) arg
(format stream
"~[~A~:;~*~/format-fact/~]"
(1- n)
acc
(list (1- n) (* acc n)))))
(defun fact (n)
(parse-integer (format nil "~/format-fact/" (list n 1))))
必须有一个更好,更模糊的基于FORMAT的实现。这个非常直接和无聊,只需使用FORMAT作为IF替代品。显然,我不是格式专家。
答案 67 :(得分:2)
<强> AWK 强>
#!/usr/bin/awk -f
{
result=1;
for(i=$1;i>0;i--){
result=result*i;
}
print result;
}
答案 68 :(得分:2)
#Language: T-SQL, C#
#Style: Custom Aggregate
另一种疯狂的方法是创建一个自定义聚合并将其应用于整数1..n的临时表。
/* ProductAggregate.cs */
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
[Serializable]
[SqlUserDefinedAggregate(Format.Native)]
public struct product {
private SqlDouble accum;
public void Init() { accum = 1; }
public void Accumulate(SqlDouble value) { accum *= value; }
public void Merge(product value) { Accumulate(value.Terminate()); }
public SqlDouble Terminate() { return accum; }
}
将其添加到sql
create assembly ProductAggregate from 'ProductAggregate.dll' with permission_set=safe -- mod path to point to actual dll location on disk.
create aggregate product(@a float) returns float external name ProductAggregate.product
创建表(在SQL中应该有一种内置的方法来实现这一点 - 嗯。对于SO来说是question吗?)
select 1 as n into #n union select 2 union select 3 union select 4 union select 5
然后终于
select dbo.product(n) from #n
答案 69 :(得分:2)
Haskell中:
factorial n = product [1..n]
答案 70 :(得分:2)
class
APPLICATION
inherit
ARGUMENTS
create
make
feature -- Initialization
make is
-- Run application.
local
l_fact: NATURAL_64
do
l_fact := factorial(argument(1).to_natural_64)
print("Result is: " + l_fact.out)
end
factorial(n: NATURAL_64): NATURAL_64 is
--
require
positive_n: n >= 0
do
if n = 0 then
Result := 1
else
Result := n * factorial(n-1)
end
end
end -- class APPLICATION
答案 71 :(得分:2)
v
>v"Please enter a number (1-16) : "0<
,: >$*99g1-:99p#v_.25*,@
^_&:1-99p>:1-:!|10 <
^ <
克里斯普雷西对Cat's Eye Technologies的一种深奥的语言。
答案 72 :(得分:2)
Perl(Y-combinator / Functional)
print sub {
my $f = shift;
sub {
my $f1 = shift;
$f->( sub { $f1->( $f1 )->( @_ ) } )
}->( sub {
my $f2 = shift;
$f->( sub { $f2->( $f2 )->( @_ ) } )
} )
}->( sub {
my $h = shift;
sub {
my $n = shift;
return 1 if $n <=1;
return $n * $h->($n-1);
}
})->(5);
'print'之后和' - &gt;(5)'之前的所有内容代表子程序。 阶乘部分在最后的“sub {...}”中。其他一切都是为了实现Y-combinator。
答案 73 :(得分:2)
fact=. verb define
*/ >:@i. y
)
答案 74 :(得分:2)
fac := [ :x | x = 0 ifTrue: [ 1 ] ifFalse: [ x * (fac value: x -1) ]].
Transcript show: (fac value: 24) "-> 620448401733239439360000"
NB在Squeak中不起作用,需要完全关闭。
答案 75 :(得分:2)
在Dictionary上定义方法
Dictionary >> fac: x
^self at: x ifAbsentPut: [ x * (self fac: x - 1) ]
使用
d := Dictionary new.
d at: 0 put: 1.
d fac: 24
答案 76 :(得分:2)
(1 to: 24) inject: 1 into: [ :a :b | a * b ]
答案 77 :(得分:2)
fact[n_] := Times @@ Range[n]
Apply[Times, Range[n]]
的语法糖。我认为这是最好的方法,当然不包括内置的n!
。请注意,这会自动使用bignums。
答案 78 :(得分:2)
Common Lisp版本:
(defun ! (n) (reduce #'* (loop for i from 2 below (+ n 1) collect i)))
似乎很快。
* (! 42)
1405006117752879898543142606244511569936384000000000
答案 79 :(得分:2)
虽然递归可能是解决问题的唯一合适的解决方案,但对于阶乘却不是。描述一下,是的。要编程,没有。迭代是最便宜的。
此函数计算较大参数的阶乘。
function Factorial(aNumber: Int64): String;
var
F: Double;
begin
F := 0;
while aNumber > 1 do begin
F := F + log10(aNumber);
dec(aNumber);
end;
Result := FloatToStr(Power(10, Frac(F))) + ' * 10^' + IntToStr(Trunc(F));
end;
百万! = 8.2639327850046 * 10 ^ 5565708
答案 80 :(得分:2)
? to factorial :n
> ifelse :n = 0 [output 1] [output :n * factorial :n - 1]
> end
并调用:
? print factorial 5
120
这是使用UCBLogo标志的方言。
答案 81 :(得分:2)
Perl,pessimal:
# Because there are just so many other ways to get programs wrong...
use strict;
use warnings;
sub factorial {
my ($x)=@_;
for(my $f=1;;$f++) {
my $tmp=$f;
foreach my $g (1..$x) {
$tmp/=$g;
}
return $f if $tmp == 1;
}
}
我相信我没有使用'*'运算符......
答案 82 :(得分:2)
* NIX Shell
Linux版本:
seq -s'*' 42 | bc
BSD版本:
jot -s'*' 42 | bc
答案 83 :(得分:2)
FORTH,迭代1班轮
: FACT 1 SWAP 1 + 1 DO I * LOOP ;
答案 84 :(得分:2)
(define factorial
(lambda (n)
(if (= n 0)
1
(* n (factorial (- n 1))))))
应该可以工作,但请注意,在大数字上调用此函数会在每次递归时扩展堆栈,这在C和Java等语言中是不好的。
(define factorial
(lambda (n)
(factorial_cps n (lambda (k) k))))
(define factorial_cps
(lambda (n k)
(if (zero? n)
(k 1)
(factorial (- n 1) (lambda (v)
(k (* n v)))))))
啊,这样,我们不会在每次递归时增加堆栈,因为我们可以扩展延续。但是,C没有延续。
(define factorial
(lambda (n)
(factorial_cps n (k_))))
(define factorial_cps
(lambda (n k)
(if (zero? n)
(apply_k 1)
(factorial (- n 1) (k_extend n k))))
(define apply_k
(lambda (ko v)
(ko v)))
(define kt_empty
(lambda ()
(lambda (v) v)))
(define kt_extend
(lambda ()
(lambda (v)
(apply_k k (* n v)))))
请注意,原始CPS计划中使用的延续的代表责任已转移到kt_
帮助程序。
由于延续的表示在辅助程序中,我们可以切换到使用ParentheC,而kt_
是一个类型指示符。
(define factorial
(lambda (n)
(factorial_cps n (kt_empty))))
(define factorial_cps
(lambda (n k)
(if (zero? n)
(apply_k 1)
(factorial (- n 1) (kt_extend n k))))
(define-union kt
(empty)
(extend n k))
(define apply_k
(lambda ()
(union-case kh kt
[(empty) v]
[(extend n k) (begin
(set! kh k)
(set! v (* n v))
(apply_k))])))
这还不够。我们现在通过设置全局变量和程序计数器来替换所有函数调用。程序现在是适用于GOTO声明的标签。
(define-registers n k kh v)
(define-program-counter pc)
(define-label main
(begin
(set! n 5) ; what is the factorial of 5??
(set! pc factorial_cps)
(mount-trampoline kt_empty k pc)
(printf "Factorial of 5: ~d\n" v)))
(define-label factorial_cps
(if (zero? n)
(begin
(set! kh k)
(set! v 1)
(set! pc apply_k))
(begin
(set! k (kt_extend n k))
(set! n (- n 1))
(set! pc factorial_cps))))
(define-union kt
(empty dismount) ; get off the trampoline!
(extend n k))
(define-label apply_k
(union-case kh kt
[(empty dismount) (dismount-trampoline dismount)]
[(extend n k) (begin
(set! kh k)
(set! v (* n v))
(set! pc apply_k))]))
哦,看,我们现在也有main
程序。现在剩下要做的就是将此文件保存为fact5.pc
并通过ParentheC的pc2c运行:
> (load "pc2c.ss")
> (pc2c "fact5.pc" "fact5.c" "fact5.h")
可能吗?我们得到fact5.c
和fact5.h
。我们看看......
$ gcc fact5.c -o fact5
$ ./fact5
Factorial of 5: 120
成功!我们已将递归Scheme程序转换为非递归C程序!它只花了几个小时,墙上有许多额头形状的印象来做到这一点!为方便起见,fact5.c和 和fact5.h。
答案 85 :(得分:1)
C ++
factorial(int n)
{
for(int i=1, f = 1; i<=n; i++)
f *= i;
return f;
}
答案 86 :(得分:1)
Java :功能
int factorial(int x) {
return x == 0 ? 1 : x * factorial(x-1);
}
答案 87 :(得分:1)
fact 0 = 1
fact n = n * fact (n-1)
答案 88 :(得分:1)
这个不仅计算n!,它也是O(n!)。如果你想计算任何“大”的东西,它可能会有问题。
long f(long n)
{
long r=1;
for (long i=1; i<n; i++)
r=r*i;
return r;
}
long factorial(long n)
{
// iterative implementation should be efficient
long result;
for (long i=0; i<f(n); i++)
result=result+1;
return result;
}
答案 89 :(得分:1)
Bourne Shell:功能性
factorial() {
if [ $1 -eq 0 ]
then
echo 1
return
fi
a=`expr $1 - 1`
expr $1 \* `factorial $a`
}
也适用于Korn Shell和Bourne Again Shell。 : - )
答案 90 :(得分:1)
Lisp递归:
(defun factorial (x)
(if (<= x 1)
1
(* x (factorial (- x 1)))))
答案 91 :(得分:1)
<强>的JavaScript 强> 使用匿名函数:
var f = function(n){
if(n>1){
return arguments.callee(n-1)*n;
}
return 1;
}
答案 92 :(得分:1)
int f(int n) { for (int i = n - 1; i > 0; n *= i, i--); return n ? n : 1; }
我使用int来简洁;使用其他类型来支持更大的数字。
答案 93 :(得分:1)
四种实施方式:
代码:
#!/usr/bin/env python
""" weave_factorial.py
"""
# [weave] factorial() as extension module in C++
from scipy.weave import ext_tools
def build_factorial_ext():
func = ext_tools.ext_function(
'factorial',
r"""
unsigned long long i = 1;
for ( ; n > 1; --n)
i *= n;
PyObject *o = PyLong_FromUnsignedLongLong(i);
return_val = o;
Py_XDECREF(o);
""",
['n'],
{'n': 1}, # effective type declaration
{})
mod = ext_tools.ext_module('factorial_ext')
mod.add_function(func)
mod.compile()
try: from factorial_ext import factorial as factorial_weave
except ImportError:
build_factorial_ext()
from factorial_ext import factorial as factorial_weave
# [python] pure python procedural factorial()
def factorial_python(n):
i = 1
while n > 1:
i *= n
n -= 1
return i
# [psyco] factorial() psyco-optimized
try:
import psyco
factorial_psyco = psyco.proxy(factorial_python)
except ImportError:
pass
# [list] list-lookup factorial()
factorials = map(factorial_python, range(21))
factorial_list = lambda n: factorials[n]
衡量相对表现:
$ python -mtimeit \
-s "from weave_factorial import factorial_$label as f" "f($n)"
n = 12
n = 20
μsec代表微秒。
答案 94 :(得分:1)
这是一个有趣的Ruby版本。在我的笔记本电脑上它会找到30000!在一秒钟之内。 (Ruby需要更长的时间才能将其格式化以进行打印而不是计算它。)这比仅按顺序乘以数字的天真解决方案要快得多。
def factorial (n)
return multiply_range(1, n)
end
def multiply_range(n, m)
if (m < n)
return 1
elsif (n == m)
return m
else
i = (n + m) / 2
return multiply_range(n, i) * multiply_range(i+1, m)
end
end
答案 95 :(得分:1)
def factorial( value: BigInt ): BigInt = value match {
case 0 => 1
case _ => value * factorial( value - 1 )
}
答案 96 :(得分:1)
奥坎姆-π
PROC subprocess(MOBILE CHAN INT parent.out!,parent.in?)
INT value:
SEQ
parent.in ? value
IF
value = 1
SEQ
parent.out ! value
OTHERWISE
INITIAL MOBILE CHAN INT child.in IS MOBILE CHAN INT:
INITIAL MOBILE CHAN INT child.out IS MOBILE CHAN INT:
FORKING
INT newvalue:
SEQ
FORK subprocess(child.in!,child.out?)
child.out ! (value-1)
child.in ? newvalue
parent.out ! (newalue*value)
:
PROC main(CHAN BYTE in?,src!,kyb?)
INITIAL INT value IS 0:
INITIAL MOBILE CHAN INT child.out is MOBILE CHAN INT
INITIAL MOBILE CHAN INT child.in is MOBILE CHAN INT
SEQ
WHILE TRUE
SEQ
subprocess(child.in!,child.out?)
child.out ! value
child.in ? value
src ! value:
value := value + 1
:
答案 97 :(得分:1)
为了不让任何人相信OCaml和古怪的东西齐头并进,我想我会提供一个理智的阶乘实现。
# let rec factorial n =
if n=0 then 1 else n * factorial(n - 1);;
我认为我的情况并不好......
答案 98 :(得分:1)
真正的功能性Java:
public final class Factorial {
public static void main(String[] args) {
final int n = Integer.valueOf(args[0]);
System.out.println("Factorial of " + n + " is " + create(n).apply());
}
private static Function create(final int n) {
return n == 0 ? new ZeroFactorialFunction() : new NFactorialFunction(n);
}
interface Function {
int apply();
}
private static class NFactorialFunction implements Function {
private final int n;
public NFactorialFunction(final int n) {
this.n = n;
}
@Override
public int apply() {
return n * Factorial.create(n - 1).apply();
}
}
private static class ZeroFactorialFunction implements Function {
@Override
public int apply() {
return 1;
}
}
}
答案 99 :(得分:1)
在一行中使用递归的C#factorial
private static int factorial(int n){ if (n == 0)return 1;else return n * factorial(n - 1); }
答案 100 :(得分:1)
注意:e
和f
寄存器:
[2++d]se[d1-d_1<fd0>e*]sf
要使用,请将您想要的值放在堆栈顶部,然后执行lfx
(加载f
寄存器并执行它),然后弹出顶部堆栈并推动该值的阶乘。
说明:如果堆栈的顶部是x
,那么第一部分使堆栈的顶部看起来像(x, x-1)
。如果新的栈顶是非负的,它会递归调用阶乘,所以现在(x, (x-1)!)
&gt; = 1的堆栈为x
,{{1}为(0, -1)
} = 0.然后,如果新的堆栈顶部为负数,则执行x
,将2++d
替换为(0, -1)
。最后,它将堆栈顶部的两个值相乘。
答案 101 :(得分:1)
setGeneric( 'fct', function( x ) { standardGeneric( 'fct' ) } )
setMethod( 'fct', 'numeric', function( x ) {
lapply( x, function(a) {
if( a == 0 ) 1 else a * fact( a - 1 )
} )
} )
有一个优点,你可以传递数字数组,它将全部用完......
例如:
> fct( c( 3, 5, 6 ) )
[[1]]
[1] 6
[[2]]
[1] 120
[[3]]
[1] 720
答案 102 :(得分:1)
ISWIM /清醒:
factorial = 1 fby factorial * (time+1);
答案 103 :(得分:1)
Python,一个班轮:
比其他python答案更干净。 如果输入小于1,则此和前一个答案将失败。
def fact(n):return reduce(int。 mul ,xrange(2,n))
答案 104 :(得分:1)
!
(defun ! (n) "factorial" (labels ((fac (n prod) (if (zerop n) prod (fac (- n 1) (* prod n))))) (fac n 1)))
编辑:或使用累加器作为可选参数:
(defun ! (n &optional prod) "factorial" (if (zerop n) prod (! (- n 1) (* prod n))))
或作为减少,代价是更大的内存占用和更多的消耗:
(defun range (start end &optional acc) "range from start inclusive to end exclusive, start = start end) (nreverse acc) (range (+ start 1) end (cons start acc)))) (defun ! (n) "factorial" (reduce #'* (range 1 (+ n 1))))
答案 105 :(得分:1)
USE:math.ranges
:factorial(n - n!)1 [a,b]乘积;
答案 106 :(得分:1)
在MUMPS中:
fact(N)
N F,I S F=1 F I=2:1:N S F=F*I
QUIT F
或者,如果你是间接的粉丝:
fact(N)
N F,I S F=1 F I=2:1:N S F=F_"*"_I
QUIT @F
答案 107 :(得分:1)
ActionScript:Procedural / OOP
function f(n) {
var result = n>1 ? arguments.callee(n-1)*n : 1;
return result;
}
// function call
f(3);
答案 108 :(得分:1)
嗯...没有TCL
proc factorial {n} {
if { $n == 0 } { return 1 }
return [expr {$n*[factorial [expr {$n-1}]]}]
}
puts [factorial 6]
但是当然这不适用于大量的n ......我们可以用tcllib做得更好!
package require math::bignum
proc factorial {n} {
if { $n == 0 } { return 1 }
return [ ::math::bignum::tostr [ ::math::bignum::mul [
::math::bignum::fromstr $n] [ ::math::bignum::fromstr [
factorial [expr {$n-1} ]
]]]]
}
puts [factorial 60]
最后看看那些]。这实际上就是LISP!
我将保留n> 2 ^ 32值的版本作为读者的例外
答案 109 :(得分:1)
f[n_ /; n < 2] := 1
f[n_] := (f[n] = n*f[n - 1])
Mathematica支持n!本地,但这显示了如何动态定义。执行f [2]时,此代码将生成一个定义f [2] = 2,随后执行时与执行硬编码时的执行方式不同;不需要内部数据结构;你只需使用语言自己的函数定义机制。
答案 110 :(得分:1)
Lisp:tail-recursive
(defun factorial(x)
(labels((f (x acc)
(if (> x 1)
(f (1- x)(* x acc))
acc)))
(f x 1)))
答案 111 :(得分:1)
另一个红宝石。
class Integer
def fact
return 1 if self.zero?
(1..self).to_a.inject(:*)
end
end
如果符号支持to_proc,则此方法有效。
答案 112 :(得分:1)
数学绝对不是REBOL的优点之一,因为它没有任意精度整数。为了完整起见,我还以为我会添加它。
这是一个标准的,天真的递归实现:
fac: func [ [catch] n [integer!] ] [ if n < 0 [ throw make error! "Hey dummy, your argument was less than 0!" ] either n = 0 [ 1 ] [ n * fac (n - 1) ] ]
就是这样。移动,伙计们,没有什么可看的......:)
答案 113 :(得分:1)
这是我的建议。在Mathematica中运行,运行良好:
gen[f_, n_] := Module[{id = -1, val = Table[Null, {n}], visit},
visit[k_] := Module[{t},
id++; If[k != 0, val[[k]] = id];
If[id == n, f[val]];
Do[If[val[[t]] == Null, visit[t]], {t, 1, n}];
id--; val[[k]] = Null;];
visit[0];
]
Factorial[n_] := Module[{res=0}, gen[res++&, n]; res]
<强>更新强> 好的,这是它的工作原理:访问函数来自Sedgewick的算法书,它“访问”长度为n的所有排列。在访问时,它以排列作为参数调用函数f。
因此,Factorial枚举长度为n的所有排列,并且对于每个排列,计数器res增加,因此计算n!在O(n + 1)!时间。
答案 114 :(得分:1)
Python:
def factorial(n):
return reduce(lambda x, y: x * y,range(1, n + 1))
答案 115 :(得分:1)
function f($n){return array_reduce(range(1,$n),'bcmul',1);}
array_product(range(1,$n));
答案 116 :(得分:1)
... Haskell和Python从中借用了列表推导。
proc factorial(n);
return 1 */ {1..n};
end factorial;
内置的INTEGER
类型是任意精度的,因此这适用于任何正n
。
答案 117 :(得分:1)
答案 118 :(得分:1)
我看到Common Lisp解决方案滥用递归,LOOP甚至格式化。我想是时候有人写一个滥用CLOS的解决方案了!
(defgeneric factorial (n))
(defmethod factorial ((n (eql 0))) 1)
(defmethod factorial ((n integer)) (* n (factorial (1- n))))
(您最喜欢的语言的对象系统调度员可以这样做吗?)
答案 119 :(得分:1)
~),1>{*}*
~
计算输入字符串(到整数))
增加数字,
是范围(4,变为[0 1 2 3])1>
选择索引为1或更大的值{*}*
折叠列表中的乘法运行:
echo 5 | ruby gs.rb fact.gs
答案 120 :(得分:1)
这将使用您的多核CPU ...尽管可能不是最有效的方式。 open 语句使用fork克隆进程,并打开从子进程到父进程的管道。将数字2一次乘以2的工作分为非常短暂的过程树。当然,这个例子有点傻。关键是如果你实际上有更难的计算,那么这个例子说明了一种平行分割工作的方法。
#!/usr/bin/perl -w
use strict;
use bigint;
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);
}
}
答案 121 :(得分:1)
使用递归公用表表达式的内联表函数。 SQL Server 2005及更高版本。
CREATE FUNCTION dbo.Factorial(@n int) RETURNS TABLE
AS
RETURN
WITH RecursiveCTE (N, Value) AS
(
SELECT 1, CAST(1 AS decimal(38,0))
UNION ALL
SELECT N+1, CAST(Value*(N+1) AS decimal(38,0))
FROM RecursiveCTE
)
SELECT TOP 1 Value
FROM RecursiveCTE
WHERE N = @n
答案 122 :(得分:0)
factorial n = factorial' n 1
factorial' 0 a = a
factorial' n a = factorial' (n-1) (n*a)
答案 123 :(得分:0)
<强>的FoxPro:强>
function factorial
parameters n
return iif( n>0, n*factorial(n-1), 1)
答案 124 :(得分:0)
Common Lisp,因为还没有人提交过:
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (1- n)))))
答案 125 :(得分:0)
我很确定这可能会更有效率。这是我的第一个lisp函数,而不是“hello,world”,并在第三章中输入示例代码。 Practical Common Lisp 是一篇很棒的文章。这个函数确实可以很好地处理大型因子。
(defun factorial (x)
(if (< x 2) (return-from factorial (print 1)))
(let ((tempx 1) (ans 1))
(loop until (equalp x tempx) do
(incf tempx)
(setf ans (* tempx ans)))
(list ans)))
答案 126 :(得分:0)
在Io中:
factorial := method(n,
if (list(0, 1) contains(n),
1,
n * factorial(n - 1)
)
)
答案 127 :(得分:0)
C ++ constexpr
constexpr uint64_t fact(uint32_t n)
{
return (n==0) ? 1:n*fact(n-1);
}
答案 128 :(得分:0)
Vb6:
Private Function factCalculation(ByVal Number%)
Dim intNum%
intNum = 1
For i = 2 To Number
intNum = intNum * Number
Next i
return intNum
End Function
Private Sub Form_Load()
Dim FactResult% : FactResult = factCalculation(3) 'e.g
Print FactResult
End Sub