Wieża Hanoi
Treść zadania
Na słupku A leży N krążków o różnych średnicach: na dole największy, a każdy kolejny jest mniejszy od poprzedniego. Słupki B i C są puste. Należy przenieść wszystkie krążki na słupek B, korzystając ze słupka C jako pomocniczego. Obowiązują zasady:
- w jednym ruchu przenosimy dokładnie jeden krążek — górny krążek z jednego słupka na inny,
- nie wolno położyć większego krążka na mniejszym.
Napisz rekurencyjną funkcję hanoi(n, skad, dokad, pomocniczy), która wypisuje ruchy przenoszące n krążków ze słupka skad na słupek dokad. Program wczytuje N i wypisuje najkrótszą sekwencję ruchów (ma ona $2^N - 1$ ruchów i jest wyznaczona jednoznacznie).
Dane wejściowe
Jedna liczba naturalna N.
Dane wyjściowe
$2^N - 1$ linii — kolejne ruchy w formacie X -> Y, gdzie X to słupek, z którego zdejmujemy krążek, a Y to słupek, na który go kładziemy.
Ograniczenia
1 ≤ N ≤ 10
Uwagi
- Aby przenieść
nkrążków ze słupkaskadnadokad: przenieśn-1górnych krążków na słupekpomocniczy, przenieś największy krążek nadokad, a na koniec przenieśn-1krążków ze słupkapomocniczynadokad. Przypadek bazowy: jeden krążek (albo zero krążków — wtedy nic nie robimy).
Przykład
3
A -> B A -> C B -> C A -> B C -> A C -> B A -> B
Potrzebujesz teorii?
Zasady obowiązujące w rozdziale 15
Poniższe zadania uczą rekurencji: funkcja rozwiązuje problem, wywołując samą siebie dla mniejszych danych, aż dojdzie do przypadku bazowego, w którym odpowiedź jest znana od razu (np. $0! = 1$).
Konwencje wspólne:
- Każde zadanie to osobny program: czyta standardowe wejście i wypisuje wynik na standardowe wyjście. Program wczytuje dane, wywołuje funkcję opisaną w treści i wypisuje wynik (gotowy szkielet znajdziesz w sekcji „Kod startowy”).
- Rozwiązanie musi być rekurencyjne. Właściwe obliczenia wykonuje funkcja, która wywołuje samą siebie. Nie używaj w niej pętli
foraniwhile, ani gotowych narzędzi, które wykonają całą pracę za Ciebie (np.sum(),pow(), operatora**,math.factorial(),list.index()). Sprawdzarka porównuje tylko wynik, ale celem zadań jest ćwiczenie rekurencji. - Każda funkcja rekurencyjna potrzebuje przypadku bazowego (kiedy przestajemy się wywoływać) i kroku rekurencyjnego (wywołania dla mniejszego problemu). Bez przypadku bazowego program przerwie działanie błędem
RecursionError. - Python ogranicza głębokość rekurencji (domyślnie do około 1000 zagnieżdżonych wywołań), dlatego dane w zadaniach są małe.
- Liczby naturalne liczymy od zera: $0, 1, 2, \dots$
- Program nie wypisuje komunikatów typu „Podaj liczbę:”.
Zadanie pochodzi z otwartego zbioru Nauka-Programowania (z rozwiązaniami wzorcowymi). Zgłoś błąd w treści lub testach.
Przywrócono Twój zapisany kod.
Python uruchomi się w przeglądarce przy pierwszym teście.
Kod zapisuje się automatycznie w tej przeglądarce. Tab wstawia wcięcie; aby opuścić edytor klawiaturą, naciśnij Esc, a potem Tab.
Testy
Program dostaje „Wejście” przez input() i musi wypisać „Oczekiwane wyjście”. Liczby porównywane są z tolerancją 0,01, a tekst podany w input("…") nie jest sprawdzany.
Test 1
Nie uruchomiono1
A -> B
Test 2
Nie uruchomiono2
A -> C A -> B C -> B
Test 3
Nie uruchomiono4
A -> C A -> B C -> B A -> C B -> A B -> C A -> C A -> B C -> B C -> A B -> A C -> B A -> C A -> B C -> B
Test 4
Nie uruchomiono5
A -> B A -> C B -> C A -> B C -> A C -> B A -> B A -> C B -> C B -> A C -> A B -> C A -> B A -> C B -> C A -> B C -> A C -> B A -> B C -> A B -> C B -> A C -> A C -> B A -> B A -> C B -> C A -> B C -> A C -> B A -> B