Skip to content

Instantly share code, notes, and snippets.

@liyu1981
Created October 29, 2013 13:23
Show Gist options
  • Save liyu1981/7214561 to your computer and use it in GitHub Desktop.
Save liyu1981/7214561 to your computer and use it in GitHub Desktop.
hano implementation
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
void moveout(struct peg* p, int no1);
void move(struct peg* p, int dst_pos);
int k;
int n;
vector<string> movement;
struct peg
{
int i;
int pos;
struct peg* upper;
};
struct peg* pegs;
vector<struct peg*>* pans;
int* dst;
void
move(struct peg* p, int dst_pos)
{
printf("will move peg %d %d => %d, upper %x\n", p->i, p->pos, dst_pos, p->upper);
for (int i=0; i<k; ++i) cout << pans[i].size() << " "; cout << endl;
if (p->pos == dst_pos)
return;
char tmp[16] = {0};
struct peg* dp = pans[dst_pos].size() == 0 ? 0 : pans[dst_pos].back();
if ((p->upper == 0 && dp == 0) || (p->upper == 0 && dp->i > p->i)) {
cout << "case 1" << endl;
int old_pos = p->pos;
pans[p->pos].pop_back();
p->pos = dst_pos;
pans[dst_pos].push_back(p);
if (dp != 0) dp->upper = p;
sprintf(tmp, "%d %d", old_pos+1, dst_pos+1);
movement.push_back(tmp);
}
else if (p->upper == 0 && dp->i < p->i) {
cout << "case 2" << endl;
struct peg* v = pans[dst_pos].back();
moveout(v, dst_pos);
move(p, dst_pos);
}
else if (p->upper !=0) {
cout << "case 3" << endl;
moveout(p->upper, dst_pos);
p->upper = 0;
move(p, dst_pos);
}
}
void
moveout(struct peg* p, int no1)
{
printf("will moveout peg %d %d <> %d\n", p->i, p->pos, no1);
for (int i=0; i<k; ++i) cout << pans[i].size() << " "; cout << endl;
int min = -1;
int mini = 0;
for (int i=0; i<k; ++i) {
vector<struct peg*>& pan = pans[i];
if (i == no1 || i == p->pos)
continue;
if (pan.size() == 0 || pan.back()->i > p->i) {
if (min == -1) {
min = pan.size();
mini = i;
}
else if (pan.size() < min) {
min = pan.size();
mini = i;
}
}
}
move(p, mini);
}
int
main(int argc, char* argv[])
{
scanf("%d %d", &n, &k);
pegs = new struct peg[n];
pans = new vector<struct peg*>[k];
dst = new int[n];
for (int i=0; i<n; ++i) {
pegs[i].i = i;
cin >> pegs[i].pos;
pegs[i].pos -= 1;
pegs[i].upper = 0;
}
for (int i=0; i<n; ++i) {
cin >> dst[i];
dst[i] -= 1;
}
for (int i=0; i<k; ++i) {
vector<struct peg*>& pan = pans[i];
for (int j=n-1; j>=0; --j)
if (pegs[j].pos == i) {
printf("will add %d to pan %d\n", pegs[j].i, i);
pan.push_back(&pegs[j]);
}
printf("pan %d now %d items\n", i, pan.size());
if (pan.size() >= 2) {
for (int j=0; j<pan.size()-1; j--) {
printf("will link peg %d to %d\n", pan[j]->i, pan[j+1]->i);
pan[j]->upper = pan[j+1];
}
}
}
for (int i=0; i<k; ++i) cout << pans[i].size() << " "; cout << endl;
for (int i=n-1; i>=0; --i)
move(&pegs[i], dst[i]);
cout << movement.size() << endl;
for (vector<string>::iterator it = movement.begin();
it != movement.end();
++it)
cout << *it << endl;
}
@liyu1981
Copy link
Author

There are K pegs. Each peg can hold discs in decreasing order of radius when looked from bottom to top of the peg. There are N discs which have radius 1 to N; Given the initial configuration of the pegs and the final configuration of the pegs, output the moves required to transform from the initial to final configuration. You are required to do the transformations in minimal number of moves.

A move consists of picking the topmost disc of any one of the pegs and placing it on top of anyother peg.
At anypoint of time, the decreasing radius property of all the pegs must be maintained.

Constraints:
1<= N<=8
3<= K<=5

Input Format:
N K
2nd line contains N integers.
Each integer in the second line is in the range 1 to K where the i-th integer denotes the peg to which disc of radius i is present in the initial configuration.
3rd line denotes the final configuration in a format similar to the initial configuration.

Output Format:
The first line contains M - The minimal number of moves required to complete the transformation.
The following M lines describe a move, by a peg number to pick from and a peg number to place on.
If there are more than one solutions, it's sufficient to output any one of them. You can assume, there is always a solution with less than 7 moves and the initial confirguration will not be same as the final one.

Sample Input #00:

     2 3
     1 1
     2 2

Sample Output #00:

      3
      1 3
      1 2
      3 2

Sample Input #01:

      6 4
      4 2 4 3 1 1
      1 1 1 1 1 1

Sample Output #01:

      5
      3 1
      4 3
      4 1
      2 1
      3 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment