Skip to content

Instantly share code, notes, and snippets.

@mikusp
Created November 10, 2013 21:04
Show Gist options
  • Save mikusp/7403933 to your computer and use it in GitHub Desktop.
Save mikusp/7403933 to your computer and use it in GitHub Desktop.
Frame-Stewart algorithm C++11 implementation
#include <iostream>
#include <tuple>
#include <stack>
#include <vector>
std::stack<int> to132(std::stack<int> s) {
int first = s.top();
s.pop();
int second = s.top();
s.pop();
int third = s.top();
s.pop();
s.push(second);
s.push(third);
s.push(first);
return s;
}
std::stack<int> to12(std::stack<int> s) {
int first = s.top();
s.pop();
int second = s.top();
s.pop();
s.pop();
s.push(second);
s.push(first);
return s;
}
std::stack<int> to321(std::stack<int> s) {
int first = s.top();
s.pop();
int second = s.top();
s.pop();
int third = s.top();
s.pop();
s.push(first);
s.push(second);
s.push(third);
return s;
}
constexpr int kparam(int t, int size) {
return (size <= 3) ? t - 1 : t / 2;
}
template<int T, int SIZE>
class Hanoi {
private:
std::stack<int> pegs;
public:
Hanoi(std::stack<int> v) : pegs(v) {}
std::vector<std::tuple<int, int>> toString() {
const int k = kparam(T, SIZE);
Hanoi<k, SIZE> l{to132(pegs)};
auto left = l.toString();
Hanoi<T - k, SIZE - 1> c{to12(pegs)};
auto center = c.toString();
Hanoi<k, SIZE> r{to321(pegs)};
auto right = r.toString();
left.insert(left.end(), center.begin(), center.end());
left.insert(left.end(), right.begin(), right.end());
return left;
}
};
template<int SIZE>
class Hanoi<0, SIZE> {
private:
std::stack<int> pegs;
public:
Hanoi(std::stack<int> v) : pegs(v) {}
std::vector<std::tuple<int, int>> toString() {
std::vector<std::tuple<int, int>> res{};
return res;
}
};
template <int SIZE>
class Hanoi<1, SIZE> {
private:
std::stack<int> pegs;
public:
Hanoi(std::stack<int> v) : pegs(v) {}
std::vector<std::tuple<int, int>> toString() {
std::vector<std::tuple<int, int>> res{};
auto first = pegs.top();
pegs.pop();
auto second = pegs.top();
pegs.pop();
res.push_back(std::make_tuple(first, second));
return res;
}
};
int main() {
std::stack<int> p;
p.push(5);
p.push(4);
p.push(3);
p.push(2);
p.push(1);
Hanoi<6,5> hanoi{p};
auto res = hanoi.toString();
for (auto r : res) {
std::cout << std::get<0>(r) << ", " << std::get<1>(r) << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment