Skip to content

Instantly share code, notes, and snippets.

@evilj0e
Last active December 3, 2017 19:24
Show Gist options
  • Save evilj0e/2a2f5f830d6cc80167eda8deb7a4b760 to your computer and use it in GitHub Desktop.
Save evilj0e/2a2f5f830d6cc80167eda8deb7a4b760 to your computer and use it in GitHub Desktop.
function spiral (searchable) {
var ring = 0;
var extreme = 0;
for (var i = 1, j = 0; i <= Infinity; i += 2, j++) {
if (i * i > searchable) {
ring = j;
extreme = i;
break;
}
}
var maxOnLevel = extreme * extreme;
var difference = maxOnLevel - searchable;
var position = (difference % (extreme - 1) - ((extreme - 1) / 2));
return ring + Math.abs(position);
}
console.log(spiral(1));
console.log(spiral(12));
console.log(spiral(23));
console.log(spiral(1024));
console.log(spiral(277678));
/*
147 142 133 122 59
304 5 4 2 57
330 10 1 1 54
351 11 23 25 26
362 747 806---> ...
*/
function Spiral (searchable) {
this.searchable = searchable;
this.items = [...Array(searchable + 1).keys()].splice(2, searchable);
this.reducer = this.reducer.bind(this);
return this;
}
Spiral.prototype.second = function () {
const { result } = this.items
.reduce(this.reducer, {
x: 0,
y: 0,
sideLength: 1,
direction: 'RIGHT_SIDE',
directionCount: 0,
matrix: { '0,0': 1 }
});
return result;
}
Spiral.prototype.reducer = function({ x, y, direction, sideLength, directionCount, matrix, result }, _) {
const nextStep = this.makeStep(x, y, direction);
x = nextStep.x;
y = nextStep.y;
if (!result) {
matrix[[x, y]] = this.calculateCurrentValue(x, y, matrix);
if (matrix[[x, y]] > this.searchable) {
result = matrix[[x, y]];
}
}
if (directionCount === 4) {
directionCount = 0;
sideLength++;
}
if (this.needChangeDirection(direction, x, y, sideLength)) {
direction = this.getNextDirection(direction);
directionCount++;
}
return {
x,
y,
direction,
sideLength,
directionCount,
matrix,
result
};
}
Spiral.prototype.makeStep = function (x, y, direction) {
switch (direction) {
case 'RIGHT_SIDE':
return {
x: ++x,
y: y
};
case 'LEFT_SIDE':
return {
x: --x,
y: y
};
case 'UP_SIDE':
return {
x: x,
y: --y
};
case 'DOWN_SIDE':
return {
x: x,
y: ++y
};
}
}
Spiral.prototype.needChangeDirection = function (direction, x, y, sideLength) {
const isHorizontal = ('RIGHT_SIDE' === direction || 'LEFT_SIDE' === direction);
const isHorizontalEnded = Math.abs(x) >= sideLength;
const isVertical = ('UP_SIDE' === direction || 'DOWN_SIDE' === direction);
const isVerticalEnded = Math.abs(y) >= sideLength;
return (isHorizontal && isHorizontalEnded) || (isVertical && isVerticalEnded);
}
Spiral.prototype.getNextDirection = function (direction) {
return {
'RIGHT_SIDE': 'UP_SIDE',
'UP_SIDE': 'LEFT_SIDE',
'LEFT_SIDE': 'DOWN_SIDE',
'DOWN_SIDE': 'RIGHT_SIDE'
}[direction];
}
Spiral.prototype.calculateCurrentValue = function (x, y, matrix) {
const getItem = function (x, y) {
return matrix[[x, y]] || 0;
};
return (
getItem(x - 1, y - 1) + getItem(x - 1, y) + getItem(x - 1, y + 1) +
getItem(x, y - 1) + getItem(x, y) + getItem(x, y + 1) +
getItem(x + 1, y - 1) + getItem(x + 1, y) + getItem(x + 1, y + 1)
)
}
console.log(new Spiral(277678).second())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment