不同语言的阶乘算法
我想了解阶乘子例程或者程序的所有不同处理方法。希望任何人都可以来这里看看他们是否想学习一种新的语言。
想法:
- 程序
- 功能性
- 面向对象
- 一班轮
- 迷惑
- 奇数球
- 错误代码
- 多种语言
基本上,我想看一个例子,说明编写算法的不同方法,以及它们在不同语言中的外观。
请限制为每个条目一个示例。
如果我们想突出显示一种特定的样式,语言或者只是一个经过深思熟虑的想法以使其适合发表在一篇文章中,那么我将为每个答案提供一个以上的示例。
唯一真正的要求是,必须以所有表示的语言找到给定参数的阶乘。
推荐指南:
# Language Name: Optional Style type - Optional bullet points Code Goes Here Other informational text goes here
我将偶尔地编辑所有格式不正确的答案。
解决方案
回答
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的use.perl.org日记。
回答
sub factorial ( int $n ){ my $result = 1; loop ( ; $n > 0; $n-- ){ $result *= $n; } return $result; }
回答
C:
编辑:实际上我猜是C ++,因为for循环中的变量声明。
int factorial(int x) { int product = 1; for (int i = x; i > 0; i--) { product *= i; } return product; }
回答
factorial = function( n ) { return n > 0 ? n * factorial( n - 1 ) : 1; }
我不确定什么是阶乘,但是其他程序在javascript中会做什么。
回答
Haskell:
ones = 1 : ones integers = head ones : zipWith (+) integers (tail ones) factorials = head integers : zipWith (*) factorials (tail integers)
回答
方案
这是一个简单的递归定义:
(define (factorial x) (if (= x 0) 1 (* x (factorial (- x 1)))))
在Scheme中,尾递归函数使用恒定的堆栈空间。这是尾递归的阶乘版本:
(define factorial (letrec ((fact (lambda (x accum) (if (= x 0) accum (fact (- x 1) (* accum x)))))) (lambda (x) (fact x 1))))
回答
C ++
factorial(int n) { for(int i=1, f = 1; i<=n; i++) f *= i; return f; }
回答
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:我们未指定函数的返回类型
回答
大声笑代码:
对不起,我无法抗拒xD
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
回答
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)
回答
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))
回答
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[#])&
回答
Java:功能
int factorial(int x) { return x == 0 ? 1 : x * factorial(x-1); }
回答
Mathematica:使用纯递归函数
(If[#>1,# #0[#-1],1])&
回答
Ruby:功能
def factorial(n) return 1 if n == 1 n * factorial(n -1) end
回答
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]: ?
回答
直截了当:
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
回答
fact 0 = 1 fact n = n * fact (n-1)
回答
使用经典的枚举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 <4> :: result就为常数。
回答
这个不仅计算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; }
回答
我们可以从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
回答
<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当然当然可以直接调用扩展方法)。
回答
电源外壳
function factorial( [int] $n ) { $result = 1; if ( $n -gt 1 ) { $result = $n * ( factorial ( $n - 1 ) ) } $result }
这里是单线:
$n..1 | % {$result = 1}{$result *= $_}{$result}
回答
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).
回答
Bourne Shell:实用
factorial() { if [ -eq 0 ] then echo 1 return fi a=`expr - 1` expr \* `factorial $a` }
也适用于Korn Shell和Bourne Again Shell。 :-)
回答
Lisp递归:
(defun factorial (x) (if (<= x 1) 1 (* x (factorial (- x 1)))))
回答
的JavaScript
使用匿名函数:
var f = function(n){ if(n>1){ return arguments.callee(n-1)*n; } return 1; }
回答
奇怪的例子?怎么使用伽玛功能!因为,"伽马n =(n-1)!"。
OCaml:使用Gamma
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)))
回答
int f(int n) { for (int i = n - 1; i > 0; n *= i, i--); return n ? n : 1; }
为了简洁起见,我使用int表示。使用其他类型来支持更大的数字。
回答
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
回答
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; }
回答
(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)))
回答
批次(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:> factorial.bat 15
回答
factorial n = factorial' n 1 factorial' 0 a = a factorial' n a = factorial' (n-1) (n*a)
回答
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)
回答
查询:
没什么要计算的,只是查找一下即可。要扩展它,请将另外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]; }
回答
. . . . . . . . . . . . . . . . . . . . . . . . . .
很难正确显示它,但是现在我尝试从预览中复制它,并且可以正常工作。我们需要输入数字,然后按Enter。
回答
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个!
回答
我们纯函数式编程的噩梦成真!
唯一深奥的图灵完备的编程语言具有:
- 纯粹的功能基础,核心和库-实际上,这是完整的API:S K I
- 甚至没有lambda!
- 不需要或者不允许数字或者列表
- 没有明确的递归,但允许递归
- 一个简单的基于无限惰性流的I / O机制
这是所有附带括号内的阶乘代码:
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)
特征:
- 无减法或者有条件
- 打印所有阶乘(如果我们等待足够长的时间)
- 使用第二层教堂数字将第N个阶乘转换为N!星号后跟换行符
- 使用Y组合器进行递归
如果我们有兴趣尝试理解它,以下是通过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,cons,1、10、42、1 +和*的适当定义)。
编辑:
(10KB乱码,否则我将其粘贴)。例如,在Unix提示符下:
$ echo "4" | ./lazy facdec.lazy 24 $ echo "5" | ./lazy facdec.lazy 120
上面的数字(例如5)相对较慢。
该代码有点of肿,因为我们必须包括所有我们自己的原语的库代码(用Hazy编写的代码,Lambda演算解释器和用Haskell编写的LC-to-Lazy K编译器)。
回答
public static int factorial(int n) { return (Enumerable.Range(1, n).Aggregate(1, (previous, value) => previous * value)); }
回答
上述大多数问题是,它们的精度将达到25左右! (12!具有32位整数)或者只是溢出。这是突破这些限制的一种实现!
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个字符。
斯基兹
回答
factorial = lambda n: reduce(lambda x,y: x*y, range(1, n+1), 1)
笔记:
- 它支持大整数。例子:
print factorial(100) 93326215443944152681699238856266700490715968264381621468592963895217599993229915\ 608941463976156518286253697920827223758251185210916864000000000000000000000000
- 对于n <0,它不起作用。
回答
这是最快的算法之一,最高可达170!。它在超过170!时莫名其妙地失败了,对于较小的阶乘来说它相对较慢,但是对于80到170之间的阶乘来说,与许多算法相比,它的速度非常快。
curl http://www.google.com/search?q=170!
还有一个在线界面,立即尝试!
如果我们发现错误或者大型阶乘的更快实现,请告诉我。
编辑:
该算法稍慢一些,但结果却超过了170:
curl http://www58.wolframalpha.com/input/?i=171!
它还将它们简化为其他各种表示形式。
回答
四个实现:
- [编织]
- [Python]
- [psyco]
- [列表]
代码:
#!/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)"
- [python] 3.8秒(9)
- [psyco] 1.2秒(3)
- [列表] 0.43秒(1)
- [python] 9.2秒(21)
- [psyco] 4.3秒(10)
- [清单] 0.43秒(1)
sec代表微秒。
回答
输入和输出是教堂数字(即自然数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)))
回答
def factorial(n) (1 .. n).inject{|a, b| a*b} end
def factorial(n) n == 1 ? 1 : n * factorial(n-1) end
回答
Nemerle:实用
def fact(n) { | 0 => 1 | x => x * fact(x-1) }
回答
#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
回答
#Language: T-SQL #Style: Big Numbers
这是另一个T-SQL解决方案-以大多数Rube Goldbergian的方式支持大量数据。很多基于集合的操作。试图使它保持唯一的SQL。糟糕的性能(400!在Dell 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
回答
我发现以下实现非常有趣:
Haskell编程器的演变
Python程序员的演变
享受!
回答
(factorial=Hash.new{|h,k|k*h[k-1]})[1]=1
用法:
factorial[5] => 120
回答
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; }
听起来像这样。并不是很有趣,但是,嘿,这只是一个析因函数!
回答
+++++ >+<[[->>>>+<<<<]>>>>[-<<<<+>>+>>]<<<<>[->>+<<]<>>>[-<[->>+<<]>>[-<<+<+>>>]<]<[-]><<<-]
由Michael Reitzenstein撰写。
回答
×/?X
- ?X将X扩展为整数1..X的数组
- /将数组中的每个元素相乘
或者使用内置运算符:
!X
资料来源:http://www.webber-labs.com/mpl/lectures/ppt-slides/01.ppt
回答
以bash和递归方式提供,但具有额外的优势,即它可以处理新流程中的每次迭代。在溢出之前,它可以计算的最大值为!20,但是如果我们不关心答案并希望系统崩溃,仍然可以对较大的数字运行它。)
#!/bin/bash echo $(( * `( [[ -gt 1 ]] && ./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$(( - 1)) ) || echo 1`));
回答
这是一个有趣的Ruby版本。在我的笔记本电脑上,它将找到30000个!一秒钟之内。 (Ruby对其进行格式化以进行打印所需的时间比对其进行计算所需的时间更长。)这比仅按顺序将数字相乘的天真的解决方案要快得多。
#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]; }
回答
简单的解决方案是最好的:
(defun fact (n) (loop for i from 1 to n for acc = 1 then (* acc i) finally (return acc)))
回答
(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的版本...
回答
好的,我自己尝试一下。
To decide what number is the factorial of (n - a number): if n is zero, decide on one; otherwise decide on the factorial of (n minus one) times n.
必须有一个更好,甚至更晦涩的基于FORMAT的实现。只需使用FORMAT作为IF替换,这就是非常简单和无聊的操作。显然,我不是FORMAT专家。
回答
在Inform 7中递归
(它使我们想起COBOL,因为它是用于编写文字冒险游戏的;比例字体是有意的):
"The factorial game" [this must be the first line of the source] There is a room. [there has to be at least one!] Factorialing is an action applying to a number. Understand "factorial [a number]" as factorialing. Carry out factorialing: Let n be the factorial of the number understood; Say "It's [n]".
如果我们想从游戏中实际调用此功能(短语),则需要定义一个动作和语法规则:
def factorial( value: BigInt ): BigInt = value match { case 0 => 1 case _ => value * factorial( value - 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 :
回答
奥卡姆皮
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
回答
fact=. verb define */ >:@i. y )
回答
factorial n = product [1..n]
回答
用途:math.ranges
:阶乘(n -n!)1 [a,b]乘积;
回答
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)))))
麻省理工学院二年级Haskell程序员
(作为大一新生研究计划)
fac 0 = 1 fac (n+1) = (n+1) * fac n
初级Haskell程序员
(Peano玩家开始)
fac 0 = 1 fac n = n * fac (n-1)
另一个初级Haskell程序员
(请注意,n + k模式是Haskell的令人作呕的部分[1]
并加入了Ban n + k模式运动[2])
fac n = foldr (*) 1 [1..n]
Haskell高级程序员
(投票给尼克松·布坎南·布什靠右)
fac n = foldl (*) 1 [1..n]
另一位高级Haskell程序员
(投票给麦戈文·比亚夫拉·内德尔(McGovern Biafra Nader)靠左)
-- 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
无意义的(无意义的)Haskell无积分程序员
(在牛津大学学习)
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程序员
(前Pascal程序员)
fac n = snd (until ((>n) . fst) (\(i,m) -> (i+1, i*m)) (1,1))
迭代式单行Haskell程序员
(前APL和C程序员)
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程序员
(早年提出RABBITS,然后移居新泽西州)
y f = f (y f) fac = y (\f n -> if (n==0) then 1 else n * f (n-1))
童子军Haskell程序员
(喜欢打结;总是很敬重,他
属于最小定点教堂[8])
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程序员
(从未遇到他不喜欢的语言)
-- 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程序员
(他在课堂上做到这一点,他得到了那名基金会长琼斯!
在托马斯·哈格伦斯(Thomas Hallgrens)获得功能性依赖之后[7]
-- 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
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
Origamist Haskell程序员
(总是从基本的Bird折叠开始)
-- (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程序员
(喜欢希腊菜,避免辛辣的印度菜;
受Lex Augusteijns排序形态学启发[3])
-- 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程序员
(吃了很多香蕉,他的眼睛烦了,现在他需要新的镜片了!)
-- 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程序员
(摘自Comonads的Uustalu,Vene和Pardos递归计划[4])
fac n = product [1..n]
终身教授
(将Haskell教给新生)
(defun factorial(x) (labels((f (x acc) (if (> x 1) (f (1- x)(* x acc)) acc))) (f x 1)))
回答
Lisp:尾递归
template<unsigned i> struct factorial { static const unsigned value = i * factorial<i-1>::value; }; template<> struct factorial<0> { static const unsigned value = 1; };
回答
C ++编译时间
Factorial<5>::value
在代码中用作:
def fact(n: Int): BigInt = 1 to n reduceLeft(_*_)
回答
阶乘可以在功能上定义为:
def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n
或者更传统地
object extendBuiltins extends Application { class Factorizer(n: Int) { def ! = 1 to n reduceLeft(_*_) } implicit def int2fact(n: Int) = new Factorizer(n) println("10! = " + (10!)) }
我们可以做到!一个有效的Ints方法:
(defun ! (n) "factorial" (labels ((fac (n prod) (if (zerop n) prod (fac (- n 1) (* prod n))))) (fac n 1)))
回答
- 叫它名字:
!
- 尾递归
- Common Lisp处理任意数量的数字
(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))))
或者作为减少,以更大的内存占用和更多的代价为代价:
(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))))
简短而简单
<?xml version="1.0"?> <?xml-stylesheet href="factorial.xsl" type="text/xsl" ?> <n> 20 </n>
回答
Python,一个内衬:
比其他python答案更干净。
如果输入小于1,则此问题和上一个答案将失败。
def fact(n):返回reduce(int.mul,xrange(2,n))
回答
Iswim / Lucid:
阶乘= 1 fby阶乘*(时间+1);
回答
XSLT 1.0
输入文件factorial.xml:
<?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>
XSLT文件factorial.xsl:
: factorial ( n -- n ) dup 1 > if dup 1 - recurse * else drop 1 then ;
将两个文件保存在同一目录中,然后在IE中打开factorial.xml。
回答
第四(递归):
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);
回答
Perl(Y组合器/功能)
setGeneric( 'fct', function( x ) { standardGeneric( 'fct' ) } ) setMethod( 'fct', 'numeric', function( x ) { lapply( x, function(a) { if( a == 0 ) 1 else a * fact( a - 1 ) } ) } )
'print'之后和'->(5)'之前的所有内容均代表该子例程。
阶乘部分位于最后的" sub {...}"中。其他所有事情都是实现Y组合器。
回答
> fct( c( 3, 5, 6 ) ) [[1]] [1] 6 [[2]] [1] 120 [[3]] [1] 720
优点是我们可以传入数字数组,这样可以解决所有问题……
例如:
[2++d]se[d1-d_1<fd0>e*]sf
回答
注意:修饰e
和f
寄存器:
v >v"Please enter a number (1-16) : "0< ,: >$*99g1-:99p#v_.25*,@ ^_&:1-99p>:1-:!|10 < ^ <
使用时,将要取的阶乘值放在堆栈的顶部,然后执行lfx(加载f寄存器并执行),然后弹出堆栈的顶部并将该值压入阶乘。
说明:如果堆栈的顶部是x
,则第一部分使堆栈的顶部看起来像(x,x-1)
。如果新的栈顶为非负数,它将递归调用阶乘,因此对于x≥1或者(0,-1而言,现在栈为((x,(x-1)!)) )表示
x=0。然后,如果新的堆栈顶数为负,则执行
2 ++ d,将
(0,-1)替换为((1,1)
)。 。最后,它会将堆栈中的前两个值相乘。
回答
/fact0 { dup 2 lt { pop } { 2 copy mul 3 1 roll 1 sub exch pop fact0 } ifelse } def /fact { 1 exch fact0 } def
Cat's Eye Technologies的Chris Pressey的一种深奥的语言。
回答
factorial n = product [1..n]
回答
Haskell:
sub factorial ($n) { [*] 1..$n }
回答
sub postfix:<!> ($n) { [*] 1..$n } # This function(?) call like below ... It looks like mathematical notation. say 10!;
我几乎不了解Perl6. 但是我猜想这个[*]运算符和Haskell的product是一样的。
这段代码在Pugs上运行,也可能在Parrot上运行(我没有检查)。
编辑
此代码也适用。
private static int factorial(int n){ if (n == 0)return 1;else return n * factorial(n - 1); }
回答
Cfactorial在一行中使用递归
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"); } }
回答
下面的代码让人难以置信,但是当我们考虑到uint32的返回值限制为n <34,uint64的限制为<65 uint64之前,我们用uint占用了返回值的空间时,硬编码33个值并不是疯狂的 :)
#Language: T-SQL, C# #Style: Custom Aggregate
回答
/* 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; } }
另一种疯狂的方法是创建自定义聚合并将其应用于整数1..n的临时表。
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
select 1 as n into #n union select 2 union select 3 union select 4 union select 5
创建表(在SQL -hmm中应该有一种内置方法来实现。对SO有疑问吗?)
select dbo.product(n) from #n
然后最后
fac(0) -> 1; fac(N) when N > 0 -> fac(N, 1). fac(1, R) -> R; fac(N, R) -> fac(N - 1, R * N).
回答
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; } } }
回答
真正具有功能的Java:
#!/usr/bin/awk -f { result=1; for(i=;i>0;i--){ result=result*i; } print result; }
回答
AWK
# let rec factorial n = if n=0 then 1 else n * factorial(n - 1);;
回答
OCaml
以免有人相信OCaml和oddball齐头并进,我想我将提供一个理性的阶乘实现。
function factorial parameters n return iif( n>0, n*factorial(n-1), 1)
我认为我的情况做得不好...
回答
FoxPro:
procedure factorial(n) return (0<n) * factorial(n-1) | 1 end
回答
递归函数
return (0<n) * factorial(n-1) | (n=0 & 1)
我作弊了一点,允许负数返回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
印刷
(define factorial (lambda (n) (if (= n 0) 1 (* n (factorial (- n 1))))))
要理解这一点:评估是目标导向的,失败则回溯。没有布尔类型,二进制运算符将返回其他语言的布尔值,否则将失败或者返回其第二个参数,但|除外;在单值上下文中,如果成功则返回其第一个参数,否则尝试第二个争论。 (在多值上下文中,它返回第一个参数,然后返回第二个参数)
" suspend"类似于其他语言中的" yield",除了没有多次多次显式调用生成器以返回其结果。反而,every
向其参数询问所有值,但默认情况下不返回任何值;它对副作用(在这种情况下为I / O)很有用。
" "限制了生成器返回的值的数量,在"阶乘"的情况下,该数量是无限的。
回答
常规计划计划:
(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和Java之类的语言中是不利的。
连续传球风格
(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)))))
嗯,这样,我们不必每次递归都增加堆栈,因为我们可以扩展延续。但是,C没有延续。
独立于表示的CPS
(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))])))
注意,表示原始CPS程序中使用的连续性的责任已经转移到kt_帮助程序中。
使用ParentheC并集的与表示无关的CPS
因为延续的表示在帮助程序中,所以我们可以改为使用ParentheC,而kt_是类型指示符。
(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))]))
踩踏的,已注册的ParentheC程序
这还不够。现在,我们通过设置全局变量和程序计数器来替换所有函数调用。现在,过程是适用于GOTO语句的标签。
> (load "pc2c.ss") > (pc2c "fact5.pc" "fact5.c" "fact5.h")
哦,看,我们现在也有一个" main"程序。现在剩下要做的就是将此文件另存为fact5.pc
并通过ParentheC的pc2c运行它:
$ gcc fact5.c -o fact5 $ ./fact5 Factorial of 5: 120
可以吗?我们得到了" fact5.c"和" fact5.h"。让我们来看看...
(defgeneric factorial (n)) (defmethod factorial ((n (eql 0))) 1) (defmethod factorial ((n integer)) (* n (factorial (1- n))))
成功!我们已经将递归Scheme程序转换为非递归C程序!而且只花了几个小时,就在墙上留下了许多额头形的印痕!为了方便起见,fact5.c和
和fact5.h。
回答
克洛斯
我看到Common Lisp解决方案滥用了递归,LOOP甚至FORMAT。我想是时候该写一个滥用CLOS的解决方案了!
0&>:1-:v v *_$.@ ^ _$>\:^
(我们喜欢的语言的对象系统调度程序可以做到这一点吗?)
回答
function f($n){return array_reduce(range(1,$n),'bcmul',1);}
回答
array_product(range(1,$n));
def factorial(n): return reduce(lambda x, y: x * y,range(1, n + 1))
回答
Python:
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]
回答
这是我的建议。在Mathematica中运行,效果很好:
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) ] ]
更新
好的,这是它的工作方式:visit函数来自Sedgewick的Algorithmic书,它"访问"长度为n的所有排列。访问时,它将使用排列作为参数来调用函数f。
因此,阶乘会枚举长度为n的所有排列,并且对于每个排列,计数器res都会增加,从而计算n!在O(n + 1)中!时间。
回答
数学绝对不是REBOL的强项之一,因为它缺少任意精度的整数。为了完整起见,我想还是应该添加它。
这是一个标准的,简单的递归实现:
? to factorial :n > ifelse :n = 0 [output 1] [output :n * factorial :n - 1] > end
就是这样。伙计们,继续前进,这里什么也没看到... :)
回答
? print factorial 5 120
并调用:
proc factorial {n} { if { $n == 0 } { return 1 } return [expr {$n*[factorial [expr {$n-1}]]}] } puts [factorial 6]
这是使用徽标的UCBLogo方言。
回答
嗯...没有TCL
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]
但是,当然,这对于该死的n值大是不可行的。tcllib可以做得更好!
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;
最后看看所有那些]。这实际上是LISP!
我将n> 2 ^ 32的值的版本留给读者看
回答
虽然递归可能是解决问题的唯一合适的解决方案,但对于析因而言却并非如此。要描述它,是的。要编程,没有。迭代最便宜。
此函数为较大的参数计算阶乘。
(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)))
1000000! = 8.2639327850046 * 10 ^ 5565708
回答
我相当确定这可能是更有效的方法。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。这是我的第一个lisp函数,不是" hello,world",而是在第三章中输入示例代码。实用Common Lisp是一本好书。此功能似乎确实可以很好地处理大型阶乘。
function f(n) { var result = n>1 ? arguments.callee(n-1)*n : 1; return result; } // function call f(3);
回答
动作脚本:过程/ OOP
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*/;}
回答
因此,我写了一个通俗易懂的语言,可以用我经常用的三种语言编写,也可以是我对这个问题的其他回答中的一种,也是我今天刚刚学到的。这是一个独立的程序,它读取包含非负整数的单行并打印包含其阶乘的单行。 Bignum用于所有语言,因此最大可计算阶乘仅取决于计算机的资源。
- Perl:使用内置的bignum包。用
perl FILENAME
运行。 - Haskell:使用内置的bignums。使用
runhugs FILENAME
或者我们最喜欢的编译器等效文件运行。 - C ++:需要GMP才能获得bignum支持。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。要使用g ++进行编译,请使用
g ++ -lgmpxx -lgmp -x c ++ FILENAME
链接正确的库。编译后,运行。/ a.out
。或者使用我们喜欢的编译器的等效项。 - brainf * ck:我在这篇文章中写了一些bignum支持。使用Muller的经典发行版,使用
bf <FILENAME> EXECUTABLE
进行编译。使输出可执行并运行。或者使用我们喜欢的发行版。 - 空格:使用内置的bignum支持。用
wspace FILENAME
运行。
编辑:添加了空白作为第五种语言。顺便说一句,不要用<code>
标签包装代码。它打破了空白。同样,代码在固定宽度上看起来更好。
(defun ! (n) (reduce #'* (loop for i from 2 below (+ n 1) collect i)))
回答
通用Lisp版本:
* (! 42) 1405006117752879898543142606244511569936384000000000
似乎相当快。
function fac { seq | paste -sd* | bc; } $ fac 42 1405006117752879898543142606244511569936384000000000 $
回答
没有什么比bash和bc快:
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 }
回答
Java脚本:使用"面试问题"计数位fnc的创造性方法。
(1 to: 24) inject: 1 into: [ :a :b | a * b ]
最多可以工作21个!然后Chrome切换为科学计数法。灵感得益于缺乏睡眠和Knuth等人的"具体数学"。
回答
1线小型通话
Dictionary >> fac: x ^self at: x ifAbsentPut: [ x * (self fac: x - 1) ]
回答
聊天,记录下来
在字典上定义方法
d := Dictionary new. d at: 0 put: 1. d fac: 24
用法
fac := [ :x | x = 0 ifTrue: [ 1 ] ifFalse: [ x * (fac value: x -1) ]]. Transcript show: (fac value: 24) "-> 620448401733239439360000"
回答
Smalltalk,使用闭包
factorial = lambda n: ((n <= 1) and 1) or factorial(n-1) * n
NB在Squeak中不起作用,需要完全关闭。
回答
Python:
功能,递归一线使用短路布尔评估。
factorial := method(n, if (list(0, 1) contains(n), 1, n * factorial(n - 1) ) )
回答
在艾欧(Io):
#!/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); } }
回答
哦fork()是Perl中的另一个示例
这将利用多个核心CPU……虽然可能不是最有效的方式。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 open语句使用fork克隆该进程,并打开一个从子进程到父进程的管道。一次将数字2相乘的工作被分解为一个生命周期很短的树。当然,这个例子有点愚蠢。关键是,如果我们实际上要进行更困难的计算,则此示例说明了一种并行划分工作的方法。
: FACT 1 SWAP 1 + 1 DO I * LOOP ;
回答
FORTH,迭代式1个衬里
~),1>{*}*
回答
echo 5 | ruby gs.rb fact.gs
- 〜将计算输入字符串(为整数)
)
增加数字,
是范围(4,变为[0 1 2 3])- " 1>"选择索引为1或者更大的值
- {*} *`将乘法折叠在列表上
- 程序终止时,将打印堆栈内容。
跑步:
proc factorial(n); return 1 */ {1..n}; end factorial;
回答
塞特
... Haskell和Python从那里借来了他们的列表理解力。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
seq -s'*' 42 | bc
内置的" INTEGER"类型是任意精度的,因此它适用于任何正数" n"。
回答
- NIX外壳
Linux版本:
jot -s'*' 42 | bc
BSD版本:
class Integer def fact return 1 if self.zero? (1..self).to_a.inject(:*) end end
回答
另一个红宝石。
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 !)
如果符号支持to_proc,则此方法有效。
回答
阿格达2号
它是Agda2,使用非常好的Agda2语法。
f[n_ /; n < 2] := 1 f[n_] := (f[n] = n*f[n - 1])
回答
>>>>,----------[>>>>,----------]>>>>++<<<<<<<<[>++++++[<---- -->-]<-<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>>>+<<<-<[-]]>[-] >>]>[-<<<<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]>>]>>>>[-[>+<-]+>>> >]<<<<[<<<<]<<<<[<<<<]>>>>>[>>>[>>>>]>>>>[>>>>]<<<<[[>>>>+<< <<-]<<<<]>>>>+<<<<<<<[<<<<]>>>>-[>>>[>>>>]>>>>[>>>>]<<<<[>>> +<<<-]>>>[<<<+>>+>-]<-[>>+<<[-]]<<[<<<<]>>>>[>[>+<-]>[<<+>+> -]<<[>>>+<<<-]>>>[<<<+>>+>-]<->+++++++++[-<[-[>>>>+<<<<-]]>> >>[<<<<+>>>>-]<<<]<[>>+<<<<[-]>>[<<+>>-]]>>]<<<<[<<<<]<<<[<< <<]>>>>-]>>>>]>>>[>[-]>>>]<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[- ]]>[-<<-<<<<[>>+<<-]>>[<<+>+>-]<->+<[>-<[-]]>]<<[<<<<]<<<<-[ >>+<<-]>>[<<+>+>-]+<[>-<[-]]>[-<<++++++++++<<<<-[>>+<<-]>>[< <+>+>-]+<[>-<[-]]>]<<[<<<<]>>>>[[>>+<<-]>>[<<+>+>-]<->+<[>>> >+<<<-<[-]]>[-]>>]>]>>>[>>>>]<<<<[>+++++++[<+++++++>-]<--.<< <<]++++++++++.
Mathematica支持n!本机,但是这显示了如何动态进行定义。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。当我们执行f [2]时,此代码将创建一个定义f [2] = 2,该定义随后将与硬编码一样执行;不需要内部数据结构;我们只需要使用语言自己的函数定义机制即可。
回答
接受非负整数后跟换行作为输入,并输出对应的阶乘后跟换行。
>++++++++++>>>+>+[>>>+[-[<<<<<[+<<<<<]>>[[-]>[<<+>+>-]<[>+<- ]<[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>+<-[>[-]>>>>+>+< <<<<<-[>+<-]]]]]]]]]]]>[<+>-]+>>>>>]<<<<<[<<<<<]>>>>>>>[>>>> >]++[-<<<<<]>>>>>>-]+>>>>>]<[>++<-]<<<<[<[>+<-]<<<<]>>[->[-] ++++++[<++++++++>-]>>>>]<<<<<[<[>+>+<<-]>.<<<<<]>.>>>>]
与先前发布的brainf * ck答案不同,它不会溢出任何内存位置。 (该实现将n!放在单个内存位置,有效地将其限制为标准bf规则下n小于6. )此程序将输出n!。对于任何n值,仅受时间和内存(或者bf实现)限制。例如,在我的计算机上使用Urban Muller的编译器,计算1000需要12秒!考虑到程序只能向左/向右移动和递增/递减一个,我认为这很好。
信不信由你,这是我编写的第一个BF程序。它花了大约10个小时,大部分时间都花在了调试上。不幸的是,我后来发现Daniel B Cristofani写了一个阶乘生成器,该乘数生成器仅输出越来越大的阶乘,而从未终止:
(defun factorial (n) (if (<= n 1) 1 (* n (factorial (1- n)))))
他的课程短得多,但实际上是一名职业bf高尔夫球手。
回答
Common Lisp,因为还没有人承诺:
fact[n_] := Times @@ Range[n]
回答
fact(N) N F,I S F=1 F I=2:1:N S F=F*I QUIT F
这是" Apply [Times,Range [n]]"的语法糖。我认为这是最好的方法,当然不算内置的n!
。请注意,这会自动使用bignums。
回答
在MUMPS中:
fact(N) N F,I S F=1 F I=2:1:N S F=F_"*"_I QUIT @F
或者,如果我们喜欢间接访问:
# 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; } }
回答
Pers,小数:
##代码##我相信我因不使用'*'运算符而获得加分...