所以我有以下Ruby脚本:
def f( a , b , c )
if b < 0
p = q = 1
if c[ 0 ] < 0
while p != 0
if p == c.length
p = 0
return a + 1
elsif c[ p ] < 0
p += 1
else
c[ p ] -= 1
c[ p - 1 ] = a
p = 0
return f( a , b , c )
end
end
else
c[ 0 ] -= 1
return f( a , a , c )
end
else
return f( f( a , -1 , c ) , b-1 , c )
end
end
#Why do the below two return different numbers?
f( 2 , 0 , [ 0 , -1 ] )
f( f( 2 , -1 , [ 0 , -1 ] ) , -1 , [ 0 , -1 ] )
他们应该回归同样的事情。由于第一个参数的第二个参数大于或等于零,我们应该让它运行到最后else
的情况并返回f(f(2,-1,[0,1]),-1,[0,1])
,但是当我运行这两个时,它们不会返回相同的结果
根据以上链接,我们有
f(2,0,[0,-1]) = 7
f(f(2,-1,[0,-1]),-1,[0,-1]) = 14
我无法弄清楚我在这里做错了什么。 (如果你能解决这个问题,也要感谢)
对于长度为4的数组c
,该函数应如下所示:
一些示例说明了这应该如何工作:
f(3,1,[2,3])
= f(f(3,-1,[2,3]),0,[2,3])
= f(f(3,3,[1,3]),0,[2,3])
= f(f(f(3,-1,[1,3]),2,[1,3]),0,[2,3])
= f(f(f(3,3,[0,3]),2,[1,3]),0,[2,3])
= f(f(f(f(3,-1,[0,3]),2,[0,3]),2,[1,3]),0,[2,3])
= f(f(f(f(3,3,[-1,3]),2,[0,3]),2,[1,3]),0,[2,3])
= f(f(f(f(f(3,-1,[-1,3]),2,[-1,3]),2,[0,3]),2,[1,3]),0,[2,3])
= f(f(f(f(f(3,-1,[3,2]),2,[-1,3]),2,[0,3]),2,[1,3]),0,[2,3])
= f(f(f(f(f(3,3,[2,2]),2,[-1,3]),2,[0,3]),2,[1,3]),0,[2,3])
现在我要诚实地告诉你,f(3,1,[2,3])
比你通常处理的任何事情要大得多。事实上,我正在制作的节目几乎总会返回stack level too deep
,因为我正在经历的筹码数量绝对是精神错乱。我应该在具有无限资源等的理论计算机上运行它,并且我正在尝试重新创建一个没有@符号的FAIL版本。
对此的一般解释:
如果是b>-1
,那么我们在第一个参数中进行b+1
函数的嵌套:
f(a,3,c) = f(f(f(f(a,-1,c),-1,c),-1,c),-1,c)
如果b=-1
是c0=-1
的第一个元素,则用第一个参数替换第二个参数。
f(a,-1,[c0, c1, ...]) = f(a,a,[c0 - 1, c1, ...])
否则,如果第二个元素是-1
,则用第一个参数替换第一个元素,否则,如果第三个元素是-1
,则用第一个参数替换第二个元素等。
如果第二个参数和数组的所有元素都是-1
,那么我们有
f(a,-1,c) = a + 1
更直观地说,我们有:(不是真正的平等)
f(a,-1,[-1,-1,-1, ...]) = addition
f(a,-1,[ 0,-1,-1, ...]) = repeated addition = multiplication
f(a,-1,[ 1,-1,-1, ...]) = repeated multiplication = exponentiation
f(a,-1,[ 2,-1,-1, ...]) = repeated exponentiation = tetration
...
f(a,-1,[-1, 0,-1, ...]) = Ackermann function (it climbs up the previous functions)
f(a,-1,[ 0, 0,-1, ...]) = repeated Ackermann functions
f(a,-1,[ 1, 0,-1, ...]) = repeated previous function nested into itself
f(a,-1,[ 2, 0,-1, ...]) = repeated previous function nested into itself
...
f(a,-1,[-1, 1,-1, ...]) = some function that climbs up through the list of previous functions
...
f(a,-1,[-1,-1, 0, ...]) = some function that climbs through functions of the form f(a,-1,[-1, k,-1, ...])
f(a,-1,[ 0,-1, 0, ...]) = repeated nesting of the previous function
f(a,-1,[-1, 0, 0, ...]) = some function that climbs through function of the form f(a,-1,[ k,-1, 0, ...])
f(a,-1,[ 0,-1, 1, ...]) = some function that climbs through functions of the form f(a,-1,[ 0, k, 0, ...])
我希望你能得到一般的想法。
答案 0 :(得分:2)
这是因为你在函数调用中修改了数组c
的元素。当函数返回时, c
是修改过的,而不是原始的。新的 c
会在后续的函数调用中使用,从而导致您获得的行为。
以下是对 f(2,0,[0,-1])
评估方式的解释:
函数调用不满足条件 b < 0
,因此它将转到上一个else
语句并执行f( f(a ,-1 ,c), b-1, c)
内部通话为f(a,-1,c)
,即f(2, -1, [0,-1])
。这将返回值 6
。此外,在此评估期间,它会将 c
修改为[-1,-1]
。
外部通话现在为f(6,b-1,c)
,即f(6, -1,
[-1,-1]
)
。请注意,c
不再 [0,-1]
了。这将评估为 7
。
因此,等效调用应为: f(f(2,-1,[0,-1]),-1,[-1,-1])
,这将产生相同的结果 7
。