|
| 1 | +/** |
| 2 | + * Finds the block distance from the first repeated location. Uses maps |
| 3 | + * numbers to number set to remember locations. |
| 4 | + * |
| 5 | + * @param {string} instr |
| 6 | + * @returns {number} |
| 7 | + */ |
| 8 | +const blockDistance = (instr) => { |
| 9 | + let x = 0 |
| 10 | + let y = 0 |
| 11 | + let dir = 0 // 0: north, 1: east, 2: south, 3: west |
| 12 | + |
| 13 | + /** @type {Map<number, Set<number>>} */ |
| 14 | + const pastLocs = new Map() |
| 15 | + const splitIns = instr ? instr.split(', ') : [] |
| 16 | + |
| 17 | + for (const ins of splitIns) { |
| 18 | + const turn = ins[0] |
| 19 | + const dist = parseInt(ins.slice(1)) |
| 20 | + let prevX = x |
| 21 | + let prevY = y |
| 22 | + |
| 23 | + // Update direction based on turn. |
| 24 | + if (turn === 'L') dir = (dir + 3) % 4 |
| 25 | + else dir = (dir + 1) % 4 |
| 26 | + |
| 27 | + // Update distance based on direction. |
| 28 | + if (dir === 0) y += dist |
| 29 | + else if (dir === 1) x += dist |
| 30 | + else if (dir === 2) y -= dist |
| 31 | + else x -= dist |
| 32 | + |
| 33 | + // Remember all visited locations on the x axis. |
| 34 | + while (prevX !== x) { |
| 35 | + if (!pastLocs.has(prevX)) pastLocs.set(prevX, new Set([y])) |
| 36 | + else if (!pastLocs.get(prevX)?.has(y)) pastLocs.get(prevX)?.add(y) |
| 37 | + else return Math.abs(prevX) + Math.abs(y) |
| 38 | + |
| 39 | + if (prevX < x) prevX++ |
| 40 | + else prevX-- |
| 41 | + } |
| 42 | + |
| 43 | + // Remember all visited locations on the y axis. |
| 44 | + while (prevY !== y) { |
| 45 | + if (!pastLocs.has(x)) pastLocs.set(x, new Set([prevY])) |
| 46 | + else if (!pastLocs.get(x)?.has(prevY)) pastLocs.get(x)?.add(prevY) |
| 47 | + else return Math.abs(x) + Math.abs(prevY) |
| 48 | + |
| 49 | + if (prevY < y) prevY++ |
| 50 | + else prevY-- |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + throw new Error('No location was visited more than once') |
| 55 | +} |
| 56 | + |
| 57 | +module.exports = { |
| 58 | + fun: blockDistance, |
| 59 | + id: 'number-map-set' |
| 60 | +} |
0 commit comments