Wskazówka:
Zadanie możemy rozwiązać, śledząc działanie funkcji „krok po kroku”, pamiętając przy tym o całej hierarchii wywołań rekurencyjnych. Przedstawimy nieco inne rozwiązanie, korzystające z drzewa wywołań rekurencyjnych, które utworzyliśmy, rozwiązując zadanie 1. Tworząc drzewo, stosowaliśmy zasadę, że wywołania funkcji wieże wykonywane w trakcie działania wieże(i, x, y, z) są wypisywane pod wywołaniem wieże(i, x, y, z), w kolejności od lewej do prawej, zgodnie kolejnością ich wykonań w trakcie działania wieże(i, x, y, z). Na przykład wywołanie wieże(2, A, C, B) jest wykonywane przed wieże(2, C, B, A) w trakcie wieże(3, A, B, C), co odpowiada ich kolejności „od lewej do prawej” w naszym drzewie.

Z powyższej obserwacji i treści funkcji wynika, że dla każdego węzła naszego drzewa najpierw wypisywane będą ruchy z jego „lewego poddrzewa”, potem ruch „wypisz x => y”, a następnie ruchy z jego „prawego poddrzewa”. Na przykład dla wieże(2, C, B, A) mamy ciąg ruchów:
C => A; C => B; A => B,
gdzie podkreślony ruch C => B jest wynikiem instrukcji „wypisz x => y” wykonanej w wieże(2, C, B, A), a pozostałe ruchy są wynikiem wywołań rekurencyjnych.

Stosując powyższą obserwację, widzimy, że ciąg ruchów wygenerowany przez wieże(3, A, B, C) to:
A => B; A => C; B => C; A => B; C => A; C => B; A => B,
gdzie podkreślony ruch A => B jest wynikiem instrukcji „wypisz x => y” wykonanej w wieże(3, A, B, C), ruchy na lewo od podkreślonego A => B to efekt działania wieże(2, A, C, B), a ruchy na prawo od podkreślonego A => B to efekt działania wieże(2, C, B, A).
Powrót do pytań