斯卡拉:110
type B=BigInt
def r(a:B,b:B,f:(B,B)=>B):B=if(b>1)f(a,r(a,b-1,f))else a
def h(a:B,b:B)=r(a,b,r(_,_,r(_,_,(_+_))))
松散:
type B=BigInt
def recursive (a:B, b:B, f:(B,B)=>B): B =
if (b>1) f (a, recursive (a, b-1, f))
else a
recursive (2, 3, recursive (_, _, recursive (_, _, (_ + _))))
说明:
type B=BigInt
def p (a:B, b:B):B = a+b
def m (a:B, b:B):B = if (b>1) p (a, m (a, b-1)) else a
def h (a:B, b:B):B = if (b>1) m (a, h (a, b-1)) else a
def t (a:B, b:B):B = if (b>1) h (a, t (a, b-1)) else a
加号,mul,high(:= pow),四边形都以相同的方式工作。可以将公共模式提取为递归方法,该方法需要两个BigInts和一个基本函数:
def r (a:B, b:B, f:(B,B)=>B):B =
if (b>1) f(a, r(a, b-1, f)) else a
r (4, 3, r (_,_, r(_,_, (_+_))))
下划线是按此顺序调用的内容的占位符,例如加号plus(a,b)=(a + b); 因此(+)是一个接受两个参数并将其相加(a + b)的函数。
不幸的是,我在堆栈大小方面遇到了问题。它适用于4的较小值(例如:2),或者如果我将深度减小一级:
def h(a:B,b:B)=r(a,b,r(_,_,(_*_))) // size -7, penalty + 5
def h(a:B,b:B)=r(a,b,r(_,_,r(_,_,(_+_))))
原始代码为112个字符,如果有效,得分为107。也许我知道如何增加堆栈。
扩展的算法可以转换为尾递归调用:
type B=BigInt
def p(a:B,b:B):B=a+b
import annotation._
@tailrec
def m(a:B,b:B,c:B=0):B=if(b>0)m(a,b-1,p(a,c))else c
@tailrec
def h(a:B,b:B,c:B=1):B=if(b>0)h(a,b-1,m(a,c))else c
@tailrec
def t(a:B,b:B,c:B=1):B=if(b>0)t(a,b-1,h(a,c))else c
tailrecursive调用的时间比原始方法长,但在长版本中并未引发stackoverflow-但是,它在合理的时间内没有产生结果。t(2,4)很好,但是5分钟后我已经停止了t(3,3)。但是,它非常优雅,不是吗?
// 124 = 119-5 bonus
type B=BigInt
def r(a:B,b:B,c:B,f:(B,B)=>B):B=if(b>0)r(a,b-1,f(a,c),f)else c
def t(a:B,b:B)=r(a,b,1,r(_,_,1,r(_,_,0,(_+_))))
现在与上面相同:使用臭味乘法(我们甚至在拒绝5的红利的同时获利,因为我们节省了7个字符:win = 4个字符:)
// 115 without bonus
type B=BigInt
def r(a:B,b:B,c:B,f:(B,B)=>B):B=if(b>0)r(a,b-1,f(a,c),f)else c
def t(a:B,b:B)=r(a,b,1,r(_,_,1,(_*_)))
调用:
timed ("t(4,3)")(t(4,3))
t(4,3): 1
scala> t(4,3)
res89: B = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
运行时间:1ms。
*
中,在某些情况下是乘法,但它也是简单的循环运算符:{block}N*
等效于C-stylefor(i=0;i<N;i++){block}
。棘手的情况是字符串/数组乘法('a'3*
给出'aaa'
),但是鉴于4***3
元素数组将溢出RAM ,这不太可能成为问题。