Well, I came up with a pretty dumb solution that goes through the Cartesian coordinates and finds the coordinates and their distance in a rather brain-dead way. At least it seems to give the correct output:

Code:`//hive.cpp`

#include <iostream>

#include <cmath>

struct Coord

{

int x, y;

};

Coord coord_from_num(unsigned n)

{

const unsigned turn_count = 6;

Coord turns[turn_count] = {{-1, 0}, {0, -1}, {1, -1}, {1, 0}, {0, 1}, {-1, 1}};

unsigned level = 0;

unsigned level_start = 1;

unsigned level_end = 1;

//determine level on the spiral

while (n > level_end) {

level_start = level_end;

++level;

level_end += level * 6;

}

//find coordinates by moving along the spiral

Coord result = {0, level};

for (unsigned i = 0; i != turn_count; ++i) {

for (unsigned j = 0; j != level; ++j) {

if (level_start == n)

return result;

result.x += turns[i].x;

result.y += turns[i].y;

++level_start;

}

}

return result; // 1

}

int get_move(int a, int b)

{

//what should be added to a, to advance the value towards b

if (a < b) return 1;

else if (a > b) return -1;

return 0;

}

int get_distance(Coord start, const Coord& target)

{

//start advancing towards the target and count steps

//move both in x and y direction, unless increments are (1, 1) or (-1, -1)

int distance = 0;

while (!(start.x == target.x && start.y == target.y)) {

++distance;

int xInc = get_move(start.x, target.x);

int yInc = get_move(start.y, target.y);

start.x += xInc;

if (abs(xInc + yInc) != 2)

start.y += yInc;

}

return distance;

}

int main()

{

int a = 0, b = 0;

while (std::cin >> a >> b && a && b) {

Coord ac = coord_from_num(a);

Coord bc = coord_from_num(b);

std::cout << "The distance between cells " << a << " and " << b << " is "

<< get_distance(ac, bc) << '\n';

}

}