漢諾塔游戲著瓶,是個佷益智的游戲,其中也蘊含了一些數學的知識材原,故事的背景甚至蘊含了一些古人對宇宙的思考余蟹。今天我們來聊下這個游戲威酒,僅僅從游戲的方法和策略的總結上對這個游戲進行一下解剖:
游戲簡介
`由來與傳說:`
法國數學家`愛德華·盧卡斯`曾編寫過一個印度的古老傳說:在世界中心貝拿勒斯
(在印度北部)的圣廟里,一塊黃銅板上插著三根寶石針尤仍。印度教的主神`梵天`
在創(chuàng)造世界的時候宰啦,在其中一根針上從下到上地穿好了由大到小的64片金片绑莺,這
就是所謂的漢諾塔纺裁。不論白天黑夜欺缘,總有一個僧侶在按照下面的法則移動這些金
片:一次只移動一片谚殊,不管在哪根針上嫩絮,小片必須在大片上面剿干。僧侶們預言置尔,當所
有的金片都從梵天穿好的那根針上移到另外一根針上時榜轿,世界就將在一聲霹靂中消
滅甸私,而`梵塔`颠蕴、`廟宇`和`眾生`也都將同歸于盡。
不管這個傳說的可信度有多大外冀,如果考慮一下把64片金片雪隧,由一根針上移到另一
根針上藕畔,并且始終保持上小下大的順序注服。這需要多少次移動呢?這里需要遞歸的方
法辜御。假設有n片擒权,移動次數是f(n).顯然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1笛厦。
此后不難證明f(n)=2^n-1纳鼎。n=64時,
假如每秒鐘一次裳凸,共需多長時間呢?一個平年365天有31536000 秒逗宁,閏年366天有
31622400秒,平均每年31556952秒梦湘,計算一下:
18446744073709551615秒
這表明移完這些金片需要5845.54億年以上,而地球存在至今不過45億年倦逐,太陽系
的預期壽命據說也就是數百億年。真的過了5845.54億年抒巢,不說太陽系和銀河系凤优,
至少地球上的一切生命悦陋,連同梵塔、廟宇等筑辨,都早已經灰飛煙滅俺驶。
游戲的目的
很多人最初接觸到這個益智游戲,都是直接用5個以上圓盤開始游戲的楚昭,但是又不太清楚具體的移動規(guī)律栖袋,導致玩兒了半天也沒有將所有圓盤成功移動到C柱子上,甚至玩過以后就得出了一個結論抚太,這游戲太沒意思了塘幅。。尿贫。
實際上這種益智類的游戲电媳,往往都是具有一定的方法和規(guī)律可循的,因為這類游戲的目的就是讓人開發(fā)思維庆亡,啟迪智慧匾乓。通常這類游戲或者玩具是最適合給孩子玩的。
既然這個游戲有益智的作用又谋,我們就應該掌握玩這種游戲的方法或者至少我們應該學會教孩子如何玩這個游戲拼缝,才能讓這個益智游戲開發(fā)孩子的思維啟迪孩子的智慧啊彰亥!
游戲的策略
在這一部分咧七,我們要分為兩點去講:1. 推導和歸納;2. Python代碼的實現(xiàn)剩愧。
1. 推導和歸納
說到歸納和總結猪叙,我們可以參照數學上的歸納方法娇斩。
舉個例子:
` 1 = 1 `
` 1×2 = 2 `
` 1×2×3 = 6 `
` 1×2×3×4 = 24 `
` 1×2×3×4×5 = 120 `
` ... `
` 1×2×3×...×(n-1)×n = f(n) `
上面的歸納的是一個函數仁卷,也就是階乘穴翩,表達式為:
f(n) = n! = n * (n-1) * ... * 1
= n * (n-1)!
歸納之后便形成了一個比較抽象、但是很容易記住的方法——公式锦积。
通過歸納和演繹芒帕,用一些簡單的、易操作的數字和步驟進行推演丰介,形成適用于更廣范圍的通行公式背蟆。
-
我們來看一下漢諾塔如何推演
要求:將圓盤從 <起點
A柱子>借助<緩沖
B柱子>移動到<終點
C柱子>
分析:為了更好的解釋說明操作步驟,我們講圓盤從小到大依次取名為1哮幢、2带膀、3、4橙垢、5...
步驟:當A柱子上有1個圓盤時
A-->C表示將1移到C:1-->C
:圓盤為奇數時垛叨,第一步指向終點C柱
當A柱子上有2個圓盤時
①A-->B表示將1移到B:1-->B
:圓盤為偶數時,第一步指向緩沖B柱
②A-->C表示將2移到C:2-->C
:最下面的圓盤柜某,移動到終點C柱
③B-->C表示將1移到C:1-->C
:緩沖柱上的圓盤嗽元,移動到終點C柱
當A柱子上有3個圓盤時
①A-->C表示將1移到C:1-->C
:圓盤為奇數時,第一步指向終點C柱
①A-->B表示將2移到B:2-->B
:將2號圓盤移到緩沖B柱
①C-->B表示將1移到B:1-->B
:將1號圓盤移到緩沖B柱
②A-->C表示將3移到C:3-->C
:最下面的圓盤喂击,移到到終點C柱
③B-->A表示將1移到A:1-->A
:將1號圓盤移到起點A柱
③B-->C表示將2移到C:2-->C
:將2號圓盤移到終點C柱
③A-->C表示將1移到C:1-->C
:將1號圓盤移到終點C柱
-
根據上面寫的3個推演步驟剂癌,我們進行歸納如下:
- 整個移動過程(排除只有一個圓盤的特殊情況),可以分為三個階段翰绊,用①②③表示媳板。
- ①階段悬襟,把
n-1
個圓盤移到緩沖B柱
;
②階段,把第n
個圓盤移到終點C柱
胧华;
③階段,把n-1
個圓盤移到終點C柱
彻秆。 - 其中柬泽,第②階段,是在最中間的
一步
框喳,第①階段和第③階段的移動步數是一樣多的课幕。 - 第一步的移動方向,根據圓盤的個數不同而定
奇數個圓盤五垮,第一步一定是移到終點C柱
偶數個圓盤乍惊,第一步一定是移到緩沖B柱
別小瞧這個方向的定位,以后每次移動1放仗、2圓盤時润绎,都是按照這個方向定位的。 - 我們把移動圓盤的過程分為
n
輪,每一輪都要移動1莉撇、2呢蛤、1和另一個圓盤;
并且每一輪移動1棍郎、2其障、1
圓盤的時候,都是按照固定的規(guī)律去移動的涂佃。
我們會以1励翼、2圓盤
同時所在的柱子為視角做定位,判斷移動的方向辜荠。下面有一個圖汽抚,上面詳細寫了具體的移動順序和方法:
- 要想明白具體是如何做的,只用眼睛看是很難理解的伯病,當你跟著我寫的步驟操作幾次之后殊橙,你一定會豁然開朗,原來移動起來是這么簡單~
2. Python代碼的實現(xiàn)
當然了用文字狱从,或者截圖去描述這個過程膨蛮,無論如何都算不上簡單明了。Python語言中季研,用函數將這個游戲的移動方法敞葛,定義成了一個遞歸函數
,寫法竟然非常的簡單:
# 請編寫 `move(n, a, b, c)`函數与涡,它接收參數 n惹谐,表示3個柱子A、B驼卖、C中
# 第1個柱子A的盤子數量氨肌,然后打印出把所有盤子從A借助B移動到C的方法
# -*- coding: utf-8 -*-
def move(n, a, b, c):
if n == 1:
print(a, '-->', c)
# 下面else的部分是需補全的代碼,也就是移動方法
else:
move(n-1,a,c,b) # 思考一下為什么要這樣寫?
move(1,a,b,c) # 想一下,這是哪個階段酌畜?
move(n-1,b,a,c) # 你知道怎囚,這最后的一步,是什么意思嗎桥胞?
# 有3個圓盤時
move(3, 'A', 'B', 'C')
# 換行
print('\n')
# 有4個圓盤時
move(4, 'A', 'B', 'C')
# 這是有3個圓盤時的【期待輸出結果】:
# A --> C
# A --> B
# C --> B
# A --> C
# B --> A
# B --> C
# A --> C
你可以復制一下這段代碼恳守,去驗證一下結果是不是和你自己移動的結果一樣!