1: // Example 6.3: Bee Breeding
    2: 
    3: // Find the path from A to the lowest-numbered cell in A's ring, the path
    4: // from B to the lowest-numbered cell in B's ring, and the path between
    5: // those two lowest-numbered cells.  Sum them and then cancel out opposing
    6: // directions (e.g., N+S=0 and N+SE=NE, etc.)  What remains is the shorted
    7: // path.
    8: 
    9: #include <iostream.h>
   10: 
   11: #define ABS(n) (((n)>=0)?(n):(-(n)))
   12: #define MIN(a,b) (((a)>(b))?(b):(a))
   13: 
   14: #define OPP(a,b) \
   15:   if (d[a] && d[b]) { \
   16:     int m = MIN(d[a], d[b]); d[a]-=m; d[b]-=m; flag=1; \
   17:   }
   18: #define ADJ(a,b,c) \
   19:   if (d[a] && d[b]) { \
   20:     int m = MIN(d[a], d[b]); d[a]-=m; d[b]-=m; d[c]+=m; flag=1; \
   21:   }
   22: 
   23: int which_row(int a) {
   24:   int c = 1;
   25:   int this_row = 6;
   26:   int cur = 0;
   27:   while (a > c) {
   28:     cur++;
   29:     c += this_row;
   30:     this_row += 6;
   31:   }
   32:   return cur;
   33: }
   34: 
   35: int row_start(int r) {
   36:   int i, c=2, tr=6;
   37:   if (r == 0) return 1;
   38:   for (i=1; i<r; i++) {
   39:     c += tr;
   40:     tr += 6;
   41:   }
   42:   return c;
   43: }
   44: 
   45: void do_row_dist(int a, int ra, int d[6]) {
   46:   int rsa = row_start(ra);
   47:   int n;
   48:   for (n=0; n<ra-1; n++) if (rsa == a) return; else { rsa++; d[4]++; }
   49:   for (n=0; n<ra; n++)   if (rsa == a) return; else { rsa++; d[5]++; }
   50:   for (n=0; n<ra; n++)   if (rsa == a) return; else { rsa++; d[0]++; }
   51:   for (n=0; n<ra; n++)   if (rsa == a) return; else { rsa++; d[1]++; }
   52:   for (n=0; n<ra; n++)   if (rsa == a) return; else { rsa++; d[2]++; }
   53:   for (n=0; n<ra; n++)   if (rsa == a) return; else { rsa++; d[3]++; }
   54: }
   55: 
   56: int do_distance(int a, int b) {
   57:   int d[6] = { 0, 0, 0, 0, 0, 0 };
   58:   int ra = which_row(a);
   59:   int rb = which_row(b);
   60:   do_row_dist(a, ra, d);
   61:   do_row_dist(b, rb, d);
   62:   if (ra == 0) {
   63:     d[2] += ABS(ra-rb)-1;
   64:     d[3]++;
   65:   }
   66:   else
   67:     d[2] += ABS(ra-rb);
   68:   int flag=1;
   69:   while (flag) {
   70:     flag = 0;
   71:     ADJ(0, 2, 1);
   72:     OPP(0, 3);
   73:     ADJ(0, 4, 5);
   74:     ADJ(1, 3, 2);
   75:     OPP(1, 4);
   76:     ADJ(1, 5, 0);
   77:     ADJ(2, 4, 3);
   78:     OPP(2, 5);
   79:     ADJ(3, 5, 4);
   80:   }
   81:   return d[0] + d[1] + d[2] + d[3] + d[4] + d[5] + d[6];
   82: }
   83: 
   84: int main() {
   85:   int a, b;
   86:   while (cin >> a >> b && a && b) {
   87:     cout << "The distance between cells " << a << " and " << b << " is " <<
   88:       do_distance(a, b) << endl;
   89:   }
   90:   return 0;
   91: }