#include <iostream> #include <vector> #include <stdexcept> #include <utility> class EndOfTheWorldAsWeKnowIt { }; class Disk { unsigned diameter; void brahma_check() const { if (diameter == 0) throw std::logic_error("Brahma ist zornig! " "Du hast die heiligen Regeln verletzt, " "als du eine nicht existierende Scheibe nahmst." ); } public: Disk(unsigned diameter = 0) : diameter(diameter) { } Disk(Disk &&other): diameter(other.diameter) { other.brahma_check(); other.diameter = 0; } Disk(const Disk&) = delete; void operator=(const Disk&) = delete; unsigned get_diameter() const { brahma_check(); return diameter; } friend std::ostream& operator<<(std::ostream &out, Disk const& disk) { return out << "|\t" << disk.diameter << "\t|"; } }; class Tower { std::vector<Disk> disks; public: void add_disk(Disk &&disk) { if (!disks.empty() && disks.back().get_diameter() < disk.get_diameter() ) throw std::logic_error("Brahma ist zornig! " "Du hast die heiligen Regeln verletzt, " "als du eine große Scheibe auf eine kleine legtest." ); disks.push_back(std::move(disk)); } Disk remove_top() { if (disks.empty()) throw std::logic_error("Brahma ist zornig! " "Du hast die heiligen Regeln verletzt, " "als du eine Scheibe von einem leeren Turm nahmst." ); Disk disk = std::move(disks.back()); disks.pop_back(); return std::move(disk); } bool empty() const { return disks.empty(); } Tower() = default; Tower(const Tower&) = delete; void operator=(const Tower&) = delete; friend std::ostream& operator<<(std::ostream &out, Tower const& tower) { for(auto const& disk: tower.disks) out << disk; return out; } }; template <unsigned num_disks> class Temple { Tower towers[3]; public: Temple() { for(unsigned i = num_disks; i != 0; --i) towers[0].add_disk(Disk(i)); } void move(unsigned from, unsigned to) { towers[to].add_disk(towers[from].remove_top()); } void show_to_brahma() const { if (towers[0].empty() && (towers[1].empty() || towers[2].empty())) throw EndOfTheWorldAsWeKnowIt(); else throw std::logic_error("Brahma ist zornig! " "Du hast die heiligen Regeln verletzt, " "als du ihm eine unvollstandige Lösung zeigtest." ); } friend std::ostream& operator<<(std::ostream &out, Temple<num_disks> const& temple) { return out << "----------------------------------------------------------\n" << temple.towers[0] << '\n' << temple.towers[1] << '\n' << temple.towers[2] << '\n' << "----------------------------------------------------------\n"; } }; class Monk { unsigned rank; static unsigned other_tower(unsigned t1, unsigned t2) { if (t1 == 0 && t2 == 1) return 2; if (t1 == 1 && t2 == 0) return 2; if (t1 == 2 && t2 == 1) return 0; if (t1 == 1 && t2 == 2) return 0; if (t1 == 2 && t2 == 0) return 1; if (t1 == 0 && t2 == 2) return 1; throw std::logic_error("Brahma ist zornig! " "Du hast die heiligen Regeln verletzt, " "als du totalen Unsinn programmiert hast." ); } public: Monk(unsigned rank): rank(rank) { } template <typename Temple> void solve_puzzle(Temple &temple, unsigned from, unsigned to) { if (rank > 1) { // Ask subordinate to move all the top disks: Monk minor_monk(rank - 1); unsigned other = other_tower(from, to); minor_monk.solve_puzzle(temple, from, other); // Move the last piece temple.move(from, to); // Proudly draw the result: std::cout << temple; // Ask subordinate to move all the rest: minor_monk.solve_puzzle(temple, other, to); } else { // This task is simple, even for the lowliest monk: temple.move(from, to); // Proudly draw the result: std::cout << temple; } } }; int main() { const unsigned num_disks = 5; Temple<num_disks> temple; try { std::cout << temple; Monk abbot(num_disks); abbot.solve_puzzle(temple, 0, 1); temple.show_to_brahma(); } catch (EndOfTheWorldAsWeKnowIt) { std::cout << "Brahma ist zufrieden. Das Universum hat seinen Zweck " "erfüllt und kann nun neu erschaffen werden. Einen schönen Tag noch!\n"; } }
Standard input is empty
---------------------------------------------------------- | 5 || 4 || 3 || 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 3 || 2 | | 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 3 | | 1 | | 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 3 | | 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 | | 3 | | 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 1 | | 3 | | 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 1 | | 3 || 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 | | 3 || 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 | | 3 || 2 || 1 | | 4 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 | | 3 || 2 | | 4 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 2 | | 3 | | 4 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 2 || 1 | | 3 | | 4 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 2 || 1 | | 4 || 3 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 2 | | 1 | | 4 || 3 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 | | 1 | | 4 || 3 || 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 | | 4 || 3 || 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 | | 4 || 3 || 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 1 | | 5 | | 4 || 3 || 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 1 | | 5 || 2 | | 4 || 3 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 2 || 1 | | 4 || 3 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 | | 5 || 2 || 1 | | 4 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 | | 5 || 2 | | 4 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 || 2 | | 5 | | 4 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 || 2 || 1 | | 5 | | 4 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 || 2 || 1 | | 5 || 4 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 || 2 | | 5 || 4 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 | | 5 || 4 || 1 | | 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 3 | | 5 || 4 | | 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 3 | | 2 || 1 | ---------------------------------------------------------- ---------------------------------------------------------- | 1 | | 5 || 4 || 3 | | 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 1 | | 5 || 4 || 3 || 2 | ---------------------------------------------------------- ---------------------------------------------------------- | 5 || 4 || 3 || 2 || 1 | ---------------------------------------------------------- Brahma ist zufrieden. Das Universum hat seinen Zweck erfüllt und kann nun neu erschaffen werden. Einen schönen Tag noch!