JSFiddle - React, Tailwind, and code Playground

by Balint Persics

JavaScript

function offsetX(n) {
	return Math.floor((((n % 4) / 2) + ((n % 4) % 2)) % 2);
}

function offsetY(n) {
	return Math.floor(1 - Math.floor((n % 4) / 2));
}

function lowerBound(n) {
  var lowerBound = (-8 + Math.sqrt(64 - 16 * (3 - n / 4) )) / 8;
  return Math.ceil(lowerBound);
}

function upperBound(n) {
  return Math.floor(Math.sqrt(n)  / 4);
}

function ringNumber(n) {
	return Math.min(Math.max(0, 	lowerBound(n)), upperBound(n));
}

function quadrantNumber(n, i) {
	return Math.floor((n / 4 - (4 * i * i)) / (2 * i + 1));
}

function quadrantOffset(n, i) {
	return  Math.floor(((n - (4 * i * i)) / 4) % (2 * i + 1));
}

function quadrant0(i, j) {
  return {
    x: 4 * i + 1,
    y: 4 * (i - j) + 1
  };
}

function quadrant1(i, j) {
  return {
    x: 4 * (i - j) + 1,
    y: - 4 * i - 3
  };
}

function quadrant2(i, j) {
  return {
    x: - 4 * i - 3,
    y: - 4 * (i - j) - 3
  };
}

function quadrant3(i, j) {
  return {
    x: - 4 * (i - j) - 3,
    y:  4 * i + 1
  };
}

var quadrantFunctions = [
	quadrant0,
  quadrant1,
  quadrant2,
  quadrant3
];

function cellCoordinate(n) {
 var i = ringNumber(n);
 console.log("i for " + n+ ':' + i);
 var q = quadrantNumber(n, i);
 console.log("q for " + n+ ':' + q);
 var j = quadrantOffset(n, i);
  console.log("j for " + n+ ':' + j);
 var islandCoord =   quadrantFunctions[q](i, j);
 var x_offset = offsetX(n);
 var y_offset = offsetY(n);
 return {
  x: islandCoord.x + x_offset,
  y: islandCoord.y + y_offset
 }
}

var cells = [1,12,13, 17, 18, 19, 20, 153];
var coordinates= cells.map(cellCoordinate);
console.log(coordinates);