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'; } }