成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用 Go 語言實(shí)現(xiàn)漢諾塔(Hanota)算法

開發(fā) 后端
我最近重溫了一下《猩球崛起》這部電影。在電影中,凱撒就玩了河內(nèi)塔游戲。你還有印象嗎?其實(shí)獨(dú)自一人玩一些游戲是好難的??(譯者不知作者為何這么說??,難道是無聊嘛???),今天我們就用 Golang 來實(shí)現(xiàn)一下漢諾塔游戲。

游戲起源

相傳最早發(fā)明這個(gè)問題的人是法國數(shù)學(xué)家愛德華·盧卡斯(Edouard Lucas)。

在世界中心的貝拿勒斯(印度北部)圣殿中,有三根寶石針插入了一個(gè)黃銅盤中。在印度教主神梵天(Brahma)創(chuàng)世時(shí),將其中一根針上從下到上裝配了 64 個(gè)金片,這也就是所謂的漢諾塔。

無論白天黑夜,總會(huì)有一位僧人按照接下來的規(guī)則移動(dòng)這些金片:一次只移動(dòng)一片,無論在哪根針上,小片必須在大片之上。

比丘們預(yù)言,當(dāng)所有的金片從梵天所的裝配寶石針上移到另一個(gè)寶石針上時(shí),世界將在雷霆中毀滅,梵天塔、寺廟和眾生也將滅亡。

這個(gè)傳說有很多變種,雖不知道是誰創(chuàng)作的,但其留下的數(shù)學(xué)問題非常經(jīng)典。

遺留下來的數(shù)學(xué)知識(shí):金片數(shù)量與移動(dòng)步數(shù)的關(guān)系是 2?–1

 1 個(gè)金片需要的步數(shù)是 2 的 1 次方減 1

 2 個(gè)金片需要的步數(shù)是 2 的 2 次方減 1

 3 個(gè)金片需要的步數(shù)是 2 的 3 次方減 1

  …

 n 個(gè)金片需要的步數(shù)是 2 的 n 次方減 1

如果傳說屬實(shí),修士們需要2??-1步移動(dòng)才能完成這個(gè)任務(wù);假設(shè)他們每秒移動(dòng)一片黃金,則需要 5849 億年才能完成。整個(gè)宇宙只有 137 億年,宇宙毀滅還為時(shí)尚早。。。

游戲規(guī)則分析

假設(shè)這個(gè)游戲中有 3 個(gè)柱子,即 A、B 和 C。需要移動(dòng)的是珠子,其中一個(gè)柱子上已經(jīng)有 N 個(gè)有序的珠子,最大的在底部,珠子按順序越來越小。另外 2 個(gè)是空柱子。

基本條件:

  • 一次只能移動(dòng)一顆珠子
  • 小珠子一定要在大珠子上面

初始狀態(tài)如下圖所示:

最終目標(biāo)是將柱子上的所有珠子移到另一根柱子上。如下所示:

游戲?qū)崿F(xiàn)思路

  1. 放空你的大腦,先想想最簡單粗暴的解決邏輯:將珠子視為一個(gè)整體。
  2. 若要滿足大珠子在下面的基本條件,一定要把 A 上最大的珠子清空,再把這個(gè)最大的珠子放在 C 柱上。(假設(shè)珠子數(shù)量為 N)
  3. 如果要將其移動(dòng)到 C 柱,首先要實(shí)現(xiàn)的必須是把 N-1 個(gè)珠子全部移到 B 柱上,

     這樣才能把第 N 個(gè)珠子(也就是最大的珠子)移到 C 柱上。

  1. 把 N-1 珠子移到 B 柱子上,因?yàn)榇笾榈脑谙拢≈樵谏希赃@ N-1 個(gè)珠子在 B 柱上是有序的。
  2. 最后,將這 N-1 個(gè)珠子從 B 柱移動(dòng)到 C 柱,完成最終目標(biāo)。

實(shí)現(xiàn)第一步:將 A 上的 N-1 個(gè)珠子移動(dòng)到 B。

為什么先把 N-1 移到 B 上?因?yàn)槟愕淖罱K實(shí)現(xiàn)是將所有的珠子從 A 移到 C,并且順序不能改變。只能大的在下,小的在上。

那么必須先將最大的珠子移到 C,否則條件不成立。要將最大的珠子從 A 移到 C,必須騰出 A 上最大的珠子,也就是必須把最大珠子上面的所有珠子全部移走。

而你只有 3 根柱子,C 上不能有其他珠子,否則不符合條件,因此這 N-1 顆珠子只能放在 B 上,并且它們會(huì)依舊井然有序。

第二步將 A 上的第 N 個(gè)珠子(最大的珠子)移動(dòng)到 C。

這很簡單,只需一步將最大的珠子從 A 移動(dòng)到 C。如下所示。

第三步將 B 上的 N-1 個(gè)珠子移動(dòng)到 C。

提示:要實(shí)現(xiàn)將 N-1 個(gè)珠子移動(dòng)到 C,是不是先找到其中最大的珠子,然后先移動(dòng)最大的珠子?所以這里的話實(shí)際上變成了重復(fù)第一步和第二步,從這 N-1 個(gè)珠子中找出最大的一個(gè),移到 C,然后重復(fù)下去。

第三步其實(shí)相當(dāng)于改變了要求。假設(shè) K = N - 1。

這時(shí) B 柱有 K 個(gè)珠子,A 柱是空的,C 柱有最大的珠子,所以 B 柱有 K 個(gè)珠子就相當(dāng)于它是空的。

第一步將 B 上的 K-1 個(gè)珠子移動(dòng)到 A。

第二步將 B 上的第 K 個(gè)珠子移動(dòng)到 C。

第三步將 A 上的 K-1 個(gè)珠子移動(dòng)到 C

如下所示。

首先找到剩余的珠子中最大的一個(gè)(在該演示中是 4 號(hào))。然后移動(dòng)它。

循環(huán)重復(fù)以上步驟,直到只剩下最后一顆(最小的)珠子,直接移動(dòng)到 C,游戲結(jié)束。

輔助柱

什么是輔助柱?假設(shè)您現(xiàn)在擁有要在 A 上被移動(dòng)的所有珠子,同時(shí)目標(biāo)是將其移動(dòng)到 C,那么 B 是這 N-1 個(gè)珠子的輔助柱。因?yàn)樗麄冎荒軙簳r(shí)留在這里,否則不符合游戲規(guī)則。

這里需要先找到輔助支柱,先別想怎么實(shí)現(xiàn),先理清邏輯。

要實(shí)現(xiàn)從 A 到 B 的移動(dòng),那么 C 就是輔助柱。

要實(shí)現(xiàn)從 A 到 C 的移動(dòng),那么 B 是輔助支柱。

要實(shí)現(xiàn)從 B 到 C 的移動(dòng),那么 A 就是輔助柱。

Golang 實(shí)現(xiàn)

從上面的分析可以看出,這其實(shí)是一個(gè)循環(huán)重復(fù)的操作,和遞歸很像,并且都可以用遞歸來實(shí)現(xiàn)。

要使用遞歸,有兩個(gè)必要條件

  1. 求遞歸公式
  2. 找到退出條件

在這個(gè)游戲中,退出條件是在只有一顆珠子的情況下直接移動(dòng)到C柱。

那么遞歸公式是什么呢?根據(jù)以上邏輯分析,可以分解為三個(gè)步驟:

  •  第一步,將 {這 N-1 個(gè)珠子} 從A移動(dòng)到B
  • 第二步,將 {第 N 個(gè)珠子} 從A移動(dòng)到C
  • 第三步,將 {其余 N-1 個(gè)珠子} 從 B 移到 C

以下是用 Golang 實(shí)現(xiàn)的偽代碼

package main
import "fmt"
// Record the number of game steps
var count int = 0
func main() {
beadNum := 5 // This is the initial number of beads
fmt.Printf("This is a Hannukah game with %d beads \n\r", beadNum)
hanoi(beadNum, "A", "B", "C")
fmt.Printf("Game over: %d steps spent in total \n\r", count)
}
// Hannukah game
func hanoi(beadNum int, pillarA string, pillarB string, pillarC string) {
if beadNum == 1 {
// If there is only one bead, move from A to C, game over
move(beadNum, pillarA, pillarC)
} else {
// Step 2: move all the plates above N (that is, N-1 judgments) from A to B. At this time, C is the transfer station
hanoi(beadNum-1, pillarA, pillarC, pillarB)
// Step 2: move the Nth plate from A to C
move(beadNum, pillarA, pillarC)
// Step 3: move the remaining n-1 disks on B from B to C. At this time, A is the transfer station
hanoi(beadNum-1, pillarB, pillarA, pillarC)
}
}
// Move the beads
func move(beadNum int, pillarFrom string, pillarTo string) {
count += 1
fmt.Printf("Step %d: bead of %d from %s move to %s \n\r", count, beadNum, pillarFrom, pillarTo)
}

感謝您閱讀本文,如果您認(rèn)為文章寫得好,請關(guān)注我。

責(zé)任編輯:龐桂玉 來源: 馬哥Linux運(yùn)維
相關(guān)推薦

2022-11-01 18:29:25

Go語言排序算法

2023-05-08 07:55:05

快速排序Go 語言

2020-08-12 08:56:30

代碼凱撒密碼函數(shù)

2022-05-19 14:14:26

go語言限流算法

2023-08-02 08:48:11

C#碟片算法

2023-07-31 08:01:13

二叉搜索測試

2024-08-29 13:23:04

WindowsGo語言

2014-12-26 09:52:08

Go

2012-03-13 10:40:58

Google Go

2009-01-10 23:38:16

程序員考試筆記

2021-07-12 15:50:55

Go 語言netstat命令

2012-08-06 08:50:05

Go語言

2024-06-06 09:47:56

2023-03-27 00:20:48

2021-07-26 09:47:38

Go語言C++

2014-04-04 11:14:18

JavaScriptStack遞歸

2021-03-01 21:59:25

編程語言GoCX

2021-03-01 18:35:18

Go語言虛擬機(jī)

2017-11-16 15:25:54

Go語言算法代碼

2022-07-20 09:52:44

Go語言短信驗(yàn)證碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美成人a∨高清免费观看 色999日韩 | 午夜精品久久久久久久星辰影院 | 成人久久一区 | 欧美性生活一区二区三区 | 午夜免费观看体验区 | 成人免费看电影 | 欧美一区二区在线免费观看 | 在线免费观看欧美 | 免费二区| 日韩在线免费视频 | 在线久草| 亚洲高清三级 | 91精品一区| 欧洲精品在线观看 | 一区二区福利视频 | 国产一区亚洲二区三区 | 日韩人体在线 | 亚洲精品久久久久久久久久久久久 | 狠狠综合久久av一区二区老牛 | 亚洲日韩第一页 | 色婷婷精品国产一区二区三区 | aaaa日韩| 久久国产成人 | 亚洲国产成人精品久久 | 午夜精品久久久久久不卡欧美一级 | 欧美久久久久久 | 免费国产视频在线观看 | 欧美三级三级三级爽爽爽 | 91免费入口 | 91精品国产91久久久久久吃药 | 亚洲视频www| 精品九九九 | 日韩欧美精品一区 | 国产精品永久免费观看 | 毛片av免费看 | 操网站| 古装三级在线播放 | 波多野结衣一二三区 | 超碰伊人| 中文字幕日韩欧美 | 国内精品久久精品 |