【发布时间】:2017-05-16 01:20:10
【问题描述】:
我找到了这个功能:
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs[target].append(pegs[start].pop())
print '%i -> %i: %s' % (start, target, pegs)
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
Trying to implement recursive Tower of Hanoi algorithm with arrays 在 StackOverflow 上。
现在我需要对其进行修改,以便每次迭代都生成 pegs 变量,而不是打印 start, target, pegs。
例如,我希望这个输出来自新函数(打印得很漂亮):
>>> list( hanoi([[120, 90, 60, 30], [], []]) )
[ [[120, 90, 60], [30], []],
[[120, 90], [30], [60]],
[[120, 90], [], [60, 30]],
[[120], [90], [60, 30]],
[[120, 30], [90], [60]],
[[120, 30], [90, 60], []],
[[120], [90, 60, 30], []],
[[], [90, 60, 30], [120]],
[[], [90, 60], [120, 30]],
[[60], [90], [120, 30]],
[[60, 30], [90], [120]],
[[60, 30], [], [120, 90]],
[[60], [30], [120, 90]],
[[], [30], [120, 90, 60]],
[[], [], [120, 90, 60, 30]],
]
这是我尝试修改它的方式:
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs[target].append(pegs[start].pop())
yield pegs
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
但是,(由于图形目的,输入的钉子数字有点大):
>>> pegs = [[120, 90, 60, 30], [], []]
>>> print(list(hanoi(pegs, 0, 2, 4)))
[]
输出只是一个空列表。
试图通过[:] 复制列表没有帮助,我很困惑,也许print 总是可以打印出来,但是yield 在深度递归级别中“卡住”了,所以它是产生了较少的深度递归,而不是outside。同样使用带有append 的列表也不起作用:
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
out = []
if n == 1:
pegs = pegs[:]
pegs[target].append(pegs[start].pop())
out.append( pegs )
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
return out
我也尝试过听从Python: using a recursive algorithm as a generator的建议
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs = pegs[:]
pegs[target].append(pegs[start].pop())
yield pegs
else:
aux = 3 - start - target # start + target + aux = 3
for i in hanoi(pegs, start, aux, n-1): yield i
for i in hanoi(pegs, start, target, 1): yield i
for i in hanoi(pegs, aux, target, n-1): yield i
通过从嵌套的for 循环产生,但它失败了。
我如何编写这样的生成器(我需要用于图形目的)?
生成器会这样使用:
pegs = [[120, 90, 60, 30], [], []]
positions = hanoi(pegs, 0, 2, 4)
for position in positions:
screen.fill((255, 255, 255))
print(index, peg_history[index])
for i, pegs in enumerate(position):
display_pegs(pegs, 100 + 180*i, 300, screen)
pygame.display.update()
time.sleep(0.5)
【问题讨论】:
标签: python recursion generator towers-of-hanoi