Wieże Hanoi

Michał Leśniewski, Warszawa 2006r. - 28 Liceum

 

„Wieże Hanoi” to bardzo stara łamigłówka matematyczna, która powstała na podstawie azjatyckiej legendy:

 

„W wielkiej świątyni Benares w Hanoi, pod kopułą, która zaznacza środek świata, znajduje się płytka z brązu, na której umocowane są trzy diamentowe igły, wysokie na łokieć i cienkie jak talia osy. Na jednej z tych igieł, w momencie stworzenia świata, Bóg umieścił 64 krążki ze szczerego złota. Największy z nich leży na płytce z brązu, a pozostałe jeden na drugim, idąc malejąco od największego do najmniejszego. Jest to wieża Brahma. Bez przerwy we dnie i w nocy kapłani przekładają krążki z jednej diamentowej igły na drugą, przestrzegając niewzruszonych praw Brahma. Prawa te chcą, aby kapłan na służbie brał tylko jeden krążek na raz i aby umieszczał go na jednej z igieł w ten sposób, by nigdy nie znalazł się pod nim krążek mniejszy. Wówczas, gdy 64 krążki zostaną przełożone z igły, na której umieścił je Bóg w momencie stworzenia świata, na jedną z dwóch pozostałych igieł, wieża, świątynia, bramini rozsypią się w proch i w jednym oka mgnieniu nastąpi koniec świata.”

 

Przełożenie 64 krążków zgodnie ze wskazaną zasadą, trwałoby całe wieki, dlatego też rozwiązując łamigłówkę przyjmujemy, że wieża ma najwyżej kilkanaście krążków.

 

 

Rozwiązanie

 

Po kilku próbach rozwiązania tej łamigłówki, każdy zapewne zauważy, że istnieje jedna zasada, pozwalająca rozwiązać łamigłówkę dla dowolnej ilości krążków. Po jej opanowaniu każdy bez najmniejszego problemu poradzi sobie nawet z bardzo wysoką wieżą. Dzięki odnalezieniu tej zasady można ułożyć algorytm oparty na rekurencji, który automatycznie rozwiąże każdą wieżę.

 

Oto zasada przełożenia i krążków z wieży a na b wykorzystując wieżę c:

 

1)    Jeżeli i = 1, to przełóż tylko jeden krążek i zakończ.

2)    Przekładamy (i – 1) krążków z a na c (wykorzystując tę samą zasadę od początku)

3)    Przekładamy 1 krążek z a na b

4)    Przekładamy (i – 1) krążków przełożonych wcześniej na c na b (wykorzystując tę samą zasadę od początku)

 

 

 

Algorytm

 

Załóżmy, że przełóż(a, b) to procedura,  która przekłada jeden krążek z wierzchołka wieży a na wierzchołek wieży b.

Oto uproszczona procedura hanoi(a, b, c, i), która przekłada i krążków z wieży a na wieżę b wykorzystując wieżę c.

 

void hanoi(int a, int b, int c, int i)

{

  // Warunek zakończenia rekurencji (do przełożenia mamy tylko 1 krążek)

  if (i == 1) przełóż(a, b);

  // W innym przypadku:

  else

  {

      // REKURENCJA! przełóż (i – 1) krążków z wieży źródłowej na pomocniczą

      hanoi(i - 1, a, c, b);

      // Przełóż jeden krążek z wieży źródłowej na docelową

      przełóż(a, b);

      // REKURENCJA! Przełóż (i – 1) krążków z wieży tymczasowej na docelową

      hanoi(i - 1, c, b, a);

  }

}

 

Demonstracja