MySQLのこと。

MySQLのことについてまとめているブログ。他人に見せる用でもなく、自分の勉強備忘録。検索インデックスも外してるので、辿りついた方・・・ようこそ。そんな大した情報ないですよ?!たまにアルゴリズムの練習も

ハノイの塔にチャレンジする

問題

今回はハノイの塔にチャレンジする。この問題は再帰を実装できれば解くことができるとのこと。ハノイの塔については、下記の動画を参考にしました。

実装

ディスクは3枚の状態で、今回も可視化してイメージをつけてみた。ディスクの動かし方を確認しつつ、再帰のイメージを掴むため。

f:id:AZUMINO:20210201225358j:plain

これを実装するとこうなる。


def move(disk, src, sup, dest):
    if disk < 1:
        return

    move(disk-1, src = src, dest = sup, sup = dest)
    print(f'Disk {disk}: {src} → {dest}')
    move(disk-1, src = sup, dest = dest, sup = src)

if __name__ == '__main__':
    move(3, src='A', sup='B', dest='C')

Disk 1: A → C
Disk 2: A → B
Disk 1: C → B
Disk 3: A → C
Disk 1: B → A
Disk 2: B → C
Disk 1: A → C

まだまだイメージを実装できる力がないと実感。つまり、自分の理解がまだまだあやふやだからなんだろうな・・・。

実装2

もうちょっと図解してディスクの動きのイメージを持ってみる。左からディスクが2枚、3枚、4枚と増やしいるが、一番底のディスク以外をグループと考えると、AからCにディスクを移動させるのは全く動きが同じになる。また、ディスクが4枚のときの、底以外の動かし方は、ディスクが3枚のときの動かし方をすればよく、ディスクが3枚のときの、底以外の動かし方は、ディスクが2枚のときの動かし方をすればよいことになる。

f:id:AZUMINO:20210202190915j:plain

ということは、「底のディスク以外をAからBに移動」「底のディスクをAからCに移動」「底のディスク以外をBからCに移動」という手順になるようにすればディスクをうまいこと動かせる。また、再帰で呼び出す際に数字を上手に減らせば、最初の実装よりも簡素化できそう。


def move(disk, x, y):
    if disk > 1:
        move(disk - 1, x, 6 - x - y)
    print(f'Disk {disk} from {x} to {y}')
    if disk > 1:
        move(disk - 1, 6 - x - y, x)


if __name__ == '__main__':
    move(disk = 3, x = 1, y = 3)

Disk 1 from 1 to 3
Disk 2 from 1 to 2
Disk 1 from 3 to 1
Disk 3 from 1 to 3
Disk 1 from 2 to 3
Disk 2 from 2 to 1
Disk 1 from 3 to 2

この実装の再帰のイメージは下記の通り。

f:id:AZUMINO:20210202193328j:plain