用 ASCII 说明汉内塔
Illustrate Tower of Hanoi with ASCII
我熟悉河内塔的递归函数。
现在我需要可视化运动,用星号表示圆盘(我猜圆盘数 = 星号数是有道理的)。
有没有人有关于如何仅使用
逐步绘制圆盘运动的提示或示例
*
*** ***
***** ***** *
-------------------- ----------------------- ...
或类似?
这是我的教授提供的示例代码,我确实了解递归的工作原理。但是在 Python 的一次讲座之后,我必须说我对可视化任务有些不知所措。
def hanoi(n, p1, p2, p3):
if n==1:
print("move from %d to %d" %(p1, p3))
else:
hanoi(n-1, p1, p3, p2)
print("move from %d to %d " %(p1, p3))
hanoi(n-1, p2, p1, p3)
return
if __name__=='__main__':
j=int(input('Input the number of disk to be moved:\n'))
print('Number of disk to be move is %d \n'%j)
hanoi(j, 1, 2, 3)
不胜感激!
正如 Phi Lipp 提到的,您需要了解状态。
状态可以用多种方式表示,但最终目标是打印到屏幕上的 X 乘 Y 字符网格。
例如,如果我们想打印
*
***
*****
我们可以在代码中将其存储为 3x5 数组。
[
[' ', ' ', '*', ' ', ' '],
[' ', '*', '*', '*', ' '],
['*', '*', '*', '*', '*'],
]
然后你可以遍历它并打印它。
for row in state:
for character in row:
print(character, end='')
一个丑陋的捷径是
print('\n'.join(''.join(y) for y in x))
现在,如果您将其想象成电影,那么动画的每一帧都是这个 X 乘 Y 数组。每一帧也是代码中的打印语句之一。困难在于转换动作,例如"Move from 1 to 3",转化为状态表示。
如果我们使用 X x Y 数组作为状态,则很难从 space1 移动到 space2,因为字符数组不会告诉您任何有关 space1 中有多少个环以及环有多大的信息.这表明我们需要一个更好的状态。
这是非常开放的,但一个解决方案是,如果我们应用面向对象的编程,我们可以定义 Ring 和 Tower 对象,其中塔是环的集合。因此,一个动作在塔之间移动环,并且 Rings 和 Tower 对象的状态用于创建 X by Y 数组。
我会偷懒,将环表示为整数,塔是 3 deques 的数组。初始状态可能类似于
from collections import deque
towers = [deque([1,2,3]), deque(), deque()]
现在你需要一个从U塔移动到V塔的函数:
def move_ring(from, to):
top_ring = from.popleft()
to.append(top_right)
最后,您需要从 towers/rings 状态转到可打印的 X 乘 Y 数组。一次渲染每个塔会更容易,每个环都在:
def render_ring(ring):
result = '*' * ring # the character * repeated ring times.
return result.center(user_input) # add the spaces required
def render_tower(tower):
result = []
for ring in tower:
result.append(render_ring(ring))
return result
最后,我们要将这些塔组合成一个可打印的阵列。您可以为此使用 zip。
def render_final(塔):
tower_results = []
对于塔中塔:
tower_results.append(render_tower(塔))
结果 = []
对于 zip 中的 all_rows(结果):
result.append(''.join(all_rows))
return 结果
现在您应该可以打印出结果并查看动画的帧了。
这应该可以帮助您走上正轨。请将上面的代码视为伪代码,因为它没有经过测试。我也不建议使用整数和双端队列列表作为您的状态,因为这无助于代码清洁。
还有一件事,如果您打印出结果,它不会很漂亮,因为文本将被打印并向下滚动。但是,如果您使用内置的 curses 库,您可以获得漂亮的输出。
我熟悉河内塔的递归函数。
现在我需要可视化运动,用星号表示圆盘(我猜圆盘数 = 星号数是有道理的)。
有没有人有关于如何仅使用
逐步绘制圆盘运动的提示或示例 *
*** ***
***** ***** *
-------------------- ----------------------- ...
或类似?
这是我的教授提供的示例代码,我确实了解递归的工作原理。但是在 Python 的一次讲座之后,我必须说我对可视化任务有些不知所措。
def hanoi(n, p1, p2, p3):
if n==1:
print("move from %d to %d" %(p1, p3))
else:
hanoi(n-1, p1, p3, p2)
print("move from %d to %d " %(p1, p3))
hanoi(n-1, p2, p1, p3)
return
if __name__=='__main__':
j=int(input('Input the number of disk to be moved:\n'))
print('Number of disk to be move is %d \n'%j)
hanoi(j, 1, 2, 3)
不胜感激!
正如 Phi Lipp 提到的,您需要了解状态。
状态可以用多种方式表示,但最终目标是打印到屏幕上的 X 乘 Y 字符网格。
例如,如果我们想打印
*
***
*****
我们可以在代码中将其存储为 3x5 数组。
[
[' ', ' ', '*', ' ', ' '],
[' ', '*', '*', '*', ' '],
['*', '*', '*', '*', '*'],
]
然后你可以遍历它并打印它。
for row in state:
for character in row:
print(character, end='')
一个丑陋的捷径是
print('\n'.join(''.join(y) for y in x))
现在,如果您将其想象成电影,那么动画的每一帧都是这个 X 乘 Y 数组。每一帧也是代码中的打印语句之一。困难在于转换动作,例如"Move from 1 to 3",转化为状态表示。
如果我们使用 X x Y 数组作为状态,则很难从 space1 移动到 space2,因为字符数组不会告诉您任何有关 space1 中有多少个环以及环有多大的信息.这表明我们需要一个更好的状态。
这是非常开放的,但一个解决方案是,如果我们应用面向对象的编程,我们可以定义 Ring 和 Tower 对象,其中塔是环的集合。因此,一个动作在塔之间移动环,并且 Rings 和 Tower 对象的状态用于创建 X by Y 数组。
我会偷懒,将环表示为整数,塔是 3 deques 的数组。初始状态可能类似于
from collections import deque
towers = [deque([1,2,3]), deque(), deque()]
现在你需要一个从U塔移动到V塔的函数:
def move_ring(from, to):
top_ring = from.popleft()
to.append(top_right)
最后,您需要从 towers/rings 状态转到可打印的 X 乘 Y 数组。一次渲染每个塔会更容易,每个环都在:
def render_ring(ring):
result = '*' * ring # the character * repeated ring times.
return result.center(user_input) # add the spaces required
def render_tower(tower):
result = []
for ring in tower:
result.append(render_ring(ring))
return result
最后,我们要将这些塔组合成一个可打印的阵列。您可以为此使用 zip。
def render_final(塔): tower_results = [] 对于塔中塔: tower_results.append(render_tower(塔)) 结果 = [] 对于 zip 中的 all_rows(结果): result.append(''.join(all_rows)) return 结果
现在您应该可以打印出结果并查看动画的帧了。
这应该可以帮助您走上正轨。请将上面的代码视为伪代码,因为它没有经过测试。我也不建议使用整数和双端队列列表作为您的状态,因为这无助于代码清洁。
还有一件事,如果您打印出结果,它不会很漂亮,因为文本将被打印并向下滚动。但是,如果您使用内置的 curses 库,您可以获得漂亮的输出。