#include <iostream>
#include <cstdlib>
#include <stack>

using namespace std;

class Torre : public stack<int> {
    private:
        char n;
    public:
        Torre(char u);
        int popt();
        char nombre() { return n; };
        ostream& Print(ostream& os);
};

ostream& operator << (ostream& os, Torre& T);

Torre::Torre(char u) : stack<int> ()
{
   n= u;
}

int Torre::popt()
{
   int u= top();
   pop();
   return u;
}

ostream& Torre::Print(ostream& os)
{
    Torre Q('q');
    while ( ! empty() )
       Q.push(popt());
    os << n << ": ";
    
    while ( ! Q.empty() )
      {
       int u= Q.popt();
       push(u);
       os << ' ' << u;
      }
    os << endl;
    return os;
}

ostream& operator << (ostream& os, Torre& T)
{
   return T.Print(os);
}

int Hanoi(int n, Torre& A, Torre& B, Torre& C)
{
   if (n>0)
      {
       Hanoi(n-1, A, C, B);
       cout << "mueva el disco " << n 
            << " desde la pila " << A.nombre()
            << " hasta la pila " << B.nombre() << endl;
       B.push(A.popt()); 
       cout << A << B << C  <<"---\n";
       Hanoi(n-1, C, B, A);
      }
}

int main(int nargs, char* args[])
{
   if (nargs < 2)
      {
       cerr << "se usa:\n\n" << args[0] << " num_discos\n";
       return EXIT_FAILURE;
      }
   int n;
   n= atoi(args[1]);
   Torre A('a'), B('b'), C('c');
   for (int k=n; k>0; k--)
      A.push(k);
   cout << A << B << C  <<"---\n";
   Hanoi(n, A, B, C);
   return EXIT_SUCCESS;
}
