fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <stdexcept>
  4. #include <utility>
  5.  
  6. class EndOfTheWorldAsWeKnowIt { };
  7.  
  8. class Disk
  9. {
  10. unsigned diameter;
  11. void brahma_check() const
  12. {
  13. if (diameter == 0)
  14. throw std::logic_error("Brahma ist zornig! "
  15. "Du hast die heiligen Regeln verletzt, "
  16. "als du eine nicht existierende Scheibe nahmst."
  17. );
  18. }
  19. public:
  20. Disk(unsigned diameter = 0) : diameter(diameter) { }
  21. Disk(Disk &&other): diameter(other.diameter)
  22. {
  23. other.brahma_check();
  24. other.diameter = 0;
  25. }
  26. Disk(const Disk&) = delete;
  27. void operator=(const Disk&) = delete;
  28. unsigned get_diameter() const { brahma_check(); return diameter; }
  29.  
  30. friend std::ostream& operator<<(std::ostream &out, Disk const& disk)
  31. {
  32. return out << "|\t" << disk.diameter << "\t|";
  33. }
  34. };
  35.  
  36. class Tower
  37. {
  38. std::vector<Disk> disks;
  39. public:
  40. void add_disk(Disk &&disk)
  41. {
  42. if (!disks.empty() && disks.back().get_diameter() < disk.get_diameter() )
  43. throw std::logic_error("Brahma ist zornig! "
  44. "Du hast die heiligen Regeln verletzt, "
  45. "als du eine große Scheibe auf eine kleine legtest."
  46. );
  47.  
  48.  
  49. disks.push_back(std::move(disk));
  50. }
  51. Disk remove_top()
  52. {
  53. if (disks.empty())
  54. throw std::logic_error("Brahma ist zornig! "
  55. "Du hast die heiligen Regeln verletzt, "
  56. "als du eine Scheibe von einem leeren Turm nahmst."
  57. );
  58.  
  59. Disk disk = std::move(disks.back());
  60. disks.pop_back();
  61. return std::move(disk);
  62. }
  63. bool empty() const { return disks.empty(); }
  64. Tower() = default;
  65. Tower(const Tower&) = delete;
  66. void operator=(const Tower&) = delete;
  67.  
  68. friend std::ostream& operator<<(std::ostream &out, Tower const& tower)
  69. {
  70. for(auto const& disk: tower.disks)
  71. out << disk;
  72. return out;
  73. }
  74. };
  75.  
  76. template <unsigned num_disks> class Temple
  77. {
  78. Tower towers[3];
  79. public:
  80. Temple()
  81. {
  82. for(unsigned i = num_disks; i != 0; --i)
  83. towers[0].add_disk(Disk(i));
  84. }
  85. void move(unsigned from, unsigned to)
  86. {
  87. towers[to].add_disk(towers[from].remove_top());
  88. }
  89. void show_to_brahma() const
  90. {
  91. if (towers[0].empty() && (towers[1].empty() || towers[2].empty()))
  92. throw EndOfTheWorldAsWeKnowIt();
  93. else
  94. throw std::logic_error("Brahma ist zornig! "
  95. "Du hast die heiligen Regeln verletzt, "
  96. "als du ihm eine unvollstandige Lösung zeigtest."
  97. );
  98. }
  99.  
  100. friend std::ostream& operator<<(std::ostream &out, Temple<num_disks> const& temple)
  101. {
  102. return out << "----------------------------------------------------------\n"
  103. << temple.towers[0] << '\n'
  104. << temple.towers[1] << '\n'
  105. << temple.towers[2] << '\n'
  106. << "----------------------------------------------------------\n";
  107. }
  108. };
  109.  
  110. class Monk
  111. {
  112. unsigned rank;
  113. static unsigned other_tower(unsigned t1, unsigned t2)
  114. {
  115. if (t1 == 0 && t2 == 1) return 2;
  116. if (t1 == 1 && t2 == 0) return 2;
  117. if (t1 == 2 && t2 == 1) return 0;
  118. if (t1 == 1 && t2 == 2) return 0;
  119. if (t1 == 2 && t2 == 0) return 1;
  120. if (t1 == 0 && t2 == 2) return 1;
  121. throw std::logic_error("Brahma ist zornig! "
  122. "Du hast die heiligen Regeln verletzt, "
  123. "als du totalen Unsinn programmiert hast."
  124. );
  125. }
  126. public:
  127. Monk(unsigned rank): rank(rank) { }
  128. template <typename Temple> void solve_puzzle(Temple &temple, unsigned from, unsigned to)
  129. {
  130. if (rank > 1)
  131. {
  132. // Ask subordinate to move all the top disks:
  133. Monk minor_monk(rank - 1);
  134. unsigned other = other_tower(from, to);
  135. minor_monk.solve_puzzle(temple, from, other);
  136. // Move the last piece
  137. temple.move(from, to);
  138. // Proudly draw the result:
  139. std::cout << temple;
  140. // Ask subordinate to move all the rest:
  141. minor_monk.solve_puzzle(temple, other, to);
  142. }
  143. else
  144. {
  145. // This task is simple, even for the lowliest monk:
  146. temple.move(from, to);
  147. // Proudly draw the result:
  148. std::cout << temple;
  149. }
  150. }
  151. };
  152.  
  153. int main()
  154. {
  155. const unsigned num_disks = 5;
  156. Temple<num_disks> temple;
  157. try
  158. {
  159. std::cout << temple;
  160. Monk abbot(num_disks);
  161. abbot.solve_puzzle(temple, 0, 1);
  162. temple.show_to_brahma();
  163. }
  164. catch (EndOfTheWorldAsWeKnowIt)
  165. {
  166. std::cout << "Brahma ist zufrieden. Das Universum hat seinen Zweck "
  167. "erfüllt und kann nun neu erschaffen werden. Einen schönen Tag noch!\n";
  168. }
  169. }
  170.  
Success #stdin #stdout 0s 3436KB
stdin
Standard input is empty
stdout
----------------------------------------------------------
|	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!