Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <string>
- #include <iostream>
- #include <stdexcept>
- #include <vector>
- using namespace std;
- class Tower {
- public:
- // конструктор и метод SetDisks нужны, чтобы правильно создать башни
- Tower(int disks_num) {
- FillTower(disks_num);
- }
- int GetDisksNum() const {
- return disks_.size();
- }
- void SetDisks(int disks_num) {
- FillTower(disks_num);
- }
- // добавляем диск на верх собственной башни
- // обратите внимание на исключение, которое выбрасывается этим методом
- void AddToTop(int disk) {
- int top_disk_num = disks_.size() - 1;
- if (0 != disks_.size() && disk >= disks_[top_disk_num]) {
- throw invalid_argument("Unable to place larger on top of a smaller");
- } else {
- disks_.push_back(disk);
- // допишите этот метод и используйте его в вашем решении
- }
- }
- int FetchFromTop() {
- return disks_.back();
- }
- int RemoveFromTop () {
- if(disks_.empty()) throw invalid_argument("No more disks left on this tower");
- int ret = disks_.back();
- disks_.pop_back();
- return ret;
- }
- void MoveDisk (Tower& from, Tower& to) {
- int disk = from.FetchFromTop();
- i++;
- try {
- to.AddToTop(disk);
- from.RemoveFromTop();
- } catch (...) {
- try {
- disk = to.FetchFromTop();
- from.AddToTop(disk);
- to.RemoveFromTop();
- } catch (...) {
- return;
- }
- }
- }
- // disks_num - количество перемещаемых дисков
- // destination - конечная башня для перемещения
- // buffer - башня, которую нужно использовать в качестве буфера для дисков
- void MoveDisksEven(int disks_num, Tower& destination, Tower& buffer) {
- if (destination.GetDisksNum() == disks_num) return;
- MoveDisk(*this, buffer);
- MoveDisk(*this, destination);
- MoveDisk(buffer, destination);
- MoveDisksEven(disks_num, destination, buffer);
- return;
- }
- void MoveDisksOdd(int disks_num, Tower& destination, Tower& buffer) {
- if (destination.GetDisksNum() == disks_num) return;
- MoveDisk(*this, destination);
- if (destination.GetDisksNum() == disks_num) return;
- MoveDisk(*this, buffer);
- if (destination.GetDisksNum() == disks_num) return;
- MoveDisk(buffer, destination);
- MoveDisksOdd(disks_num, destination, buffer);
- return;
- }
- void MoveDisks(int disks_num, Tower& destination, Tower& buffer) {
- if (destination.GetDisksNum() == disks_num) return;
- bool if_even = (disks_num % 2) == 0;
- if (if_even)
- MoveDisk(*this, buffer);
- else
- MoveDisk(*this, destination);
- if (destination.GetDisksNum() == disks_num) return;
- if (if_even)
- MoveDisk(*this, destination);
- else
- MoveDisk(*this, buffer);
- if (destination.GetDisksNum() == disks_num) return;
- MoveDisk(buffer, destination);
- MoveDisks(disks_num, destination, buffer);
- return;
- }
- string PrintTower() {
- string ret;
- for (int disk : disks_) {
- ret += to_string(disk) + " "s;
- }
- return ret;
- }
- // вы можете дописывать необходимые для вашего решения методы
- int64_t i = 0;
- private:
- vector<int> disks_;
- // используем приватный метод FillTower, чтобы избежать дубликации кода
- void FillTower(int disks_num) {
- for (int i = disks_num; i > 0; i--) {
- disks_.push_back(i);
- }
- }
- };
- void SolveHanoi(vector<Tower>& towers) {
- int disks_num = towers[0].GetDisksNum();
- // запускаем рекурсию
- // просим переложить все диски на последнюю башню
- // с использованием средней башни как буфера
- towers[0].MoveDisks(disks_num, towers[2], towers[1]);
- }
- void PrintTowers(vector<Tower>& towers) {
- int i = 0;
- for (Tower tower : towers) {
- cout << "Tower "s << ++i << ": "s << tower.PrintTower() << endl;
- }
- cout << endl;
- }
- int main() {
- int towers_num = 3;
- int disks_num = 21;
- int d_in = 0;
- cout << "Enter amount of disks (0 - 16):";
- cin >> d_in;
- if (d_in > 0) disks_num = d_in;
- cout << "Total number of disks is "s << disks_num << ", expected number of moves="s << pow(2, disks_num) - 1 << endl;
- vector<Tower> towers;
- // добавим в вектор три пустые башни
- for (int i = 0; i < towers_num; ++i) {
- towers.push_back(0);
- }
- // добавим на первую башню три кольца
- PrintTowers(towers);
- towers[0].SetDisks(disks_num);
- PrintTowers(towers);
- SolveHanoi(towers);
- PrintTowers(towers);
- cout << towers[0].i << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment