const fs = require('fs'); const input = fs.readFileSync(__dirname + '/input.txt', 'utf8'); interface Coord { x: number, y: number, }; const [mapStr, movementsStr] = input.split("\n\n"); const map: Array> = mapStr.split("\n").map((row: string) => row.split('')); const movements = movementsStr.split("\n").join(''); const width = map[0].length; const height = map.length; const robotIndex = mapStr.indexOf('@'); let robotPos = { x: robotIndex % (width + 1), y: Math.floor(robotIndex / height) }; map[robotPos.y][robotPos.x] = '.'; function nextCoord(pos: Coord, dir: '^'|'>'|'<'|'v'): Coord|null { const newCoord = { "^": { x: pos.x, y: pos.y - 1 }, ">": { x: pos.x + 1, y: pos.y }, "v": { x: pos.x, y: pos.y + 1 }, "<": { x: pos.x - 1, y: pos.y }, }[dir]; if (newCoord.x < 0 || newCoord.x >= width || newCoord.y < 0 || newCoord.y > height) { return null; } return newCoord; } function printMap() { const mapClone = map.slice().map((row: Array) => row.slice()); mapClone[robotPos.y][robotPos.x] = '@'; console.log(mapClone.map((row: Array) => row.join('')).join("\n")); } printMap(); for (let i = 0; i < movements.length; i++) { const direction = movements[i]; const nextRobotPosition = nextCoord(robotPos, direction); if (!nextRobotPosition) { continue; } let value = map[nextRobotPosition.y][nextRobotPosition.x]; if (value === '#') { continue; } let boxes = []; let boxPos = {...nextRobotPosition}; while (value === 'O') { boxes.push(boxPos); const nextBoxCoord = nextCoord(boxPos, direction); if (!nextBoxCoord) { break; } boxPos = nextBoxCoord; value = map[boxPos.y][boxPos.x]; } if (boxes.length && value !== '#') { boxes.reverse().forEach((pos) => { map[pos.y][pos.x] = '.'; const newPos = nextCoord(pos, direction)!; map[newPos.y][newPos.x] = 'O'; }) } else if (boxes.length) { continue; } robotPos = nextRobotPosition; printMap(); } let sum = 0; map.forEach((row, y) => { row.forEach((val, x) => { if (val === 'O') { sum += ((y * 100) + x); } }); }); console.log(sum);