Mostly functional approach [Advent of Code Day 3 First Half]
// I love ramda
const R = require('ramda');
// Find the XY distance based on a range and the target number
const getXY = ([min, max], number) => {
if ( R.contains(number)(R.range(min, max)) ) {
const dist = distanceRange(number);
const sector = ~~((number - min) / (max - min) * 4);
const sideLength = (max - min) / 4;
const sectorDistance = ~~((number - min));
return dist + Math.abs(sectorDistance % sideLength - (sideLength/2 - 1));
} else {
return false;
}
}
// Generate a spiral range
const spiralRange = n => n > 1 ? [2 + R.range(1, n).map(x => x * 8).reduce((a, b) => a + b), 2 + R.range(1, n + 1).map(x => x * 8).reduce((a, b) => a + b)] : [1, 2];
// find the appropriate range for the number
const findRange = n => R.last(R.range(1, ~~Math.sqrt(n)).map(spiralRange).filter(([min, max]) => min <= n))
// find the distance from 1 to that range
const distanceRange = n => R.range(1, ~~Math.sqrt(n)).map(spiralRange).filter(([min, max]) => min <= n).length;
// My number
const n = 368078;
// The appropriate range
const r = findRange(n);
// The result
getXY(r, n);
/*
/ Sector 1 /
65 64 63 62 61 60 59 58 57
S 66 37 36 35 34 33 32 31 56 S
e 67 38 17 16 15 14 13 30 55 e
c 68 39 18 5 4 3 [12]29 54 c
t 69 40 19 6 1---2--11 28 53 t => 2 + 1 => 3
o 70 41 20 7 8 9 10 27 52 o
r 71 42 21 22 23 24 25 26 51 r
72 43 44 45 46 47 48 49 50 0 /
2 73 74 75 76 77 78 79 80 81
/ Sector 3 /
*/
no comments