const fs = require('fs/promises'); const tailVisited = {'0~0': true}; const rope = [[0,0], [0,0], [0,0], [0,0], [0,0], [0,0], [0,0], [0,0], [0,0], [0,0]]; const keypress = async () => { process.stdin.setRawMode(true) return new Promise(resolve => process.stdin.once('data', data => { const byteArray = [...data] if (byteArray.length > 0 && byteArray[0] === 3) { console.log('^C') process.exit(1) } process.stdin.setRawMode(false) resolve() })) } const moveRope = (direction) => { const lastSpot = [rope[0][0], rope[0][1]]; switch (direction) { case "R": rope[0][0] += 1; break; case "L": rope[0][0] -= 1; break; case "U": rope[0][1] -= 1; break; case "D": rope[0][1] += 1; break; } for(let i = 1; i < rope.length; ++i) { rope[i] = moveSeg(rope[i], i) } } const moveSeg = ([x, y], i) => { if(i === rope.length) return; const seg = rope[i - 1]; //console.log("uhh: ", rope, " ", i, " ", seg); const [lx, ly] = seg; V= rope[i - 1]; if(lx === x) { if(ly === y + 2) { return [x, y + 1]; } if(ly === y - 2) { return[x, y - 1]; } } if(ly === y) { if(lx === x + 2) { return [x + 1, y]; } if(lx === x - 2) { return rope[i] = [x - 1, y]; } } if(Math.max(Math.abs(x - lx), Math.abs(y - ly)) > 1) { const xDiff = lx - x; const yDiff = ly - y; if(xDiff === 0 || yDiff === 0) { console.log([x, y, lx, ly]) console.log("ROPE: ", rope); } return [x + xDiff/Math.abs(xDiff), y + yDiff/Math.abs(yDiff)]; } return [x, y]; } const printGraph = () => { console.log("\n"); console.log(rope); console.log("\n"); for(let y = -15; y <= 15; y++) { const row = ["·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·", "·"].map((spot, i) => { const x = i - 15; const [hx, hy] = rope[0]; const [tx, ty] = rope[9]; let ch = "·"; if(!(y % 5) && !(x % 5)) { ch = "▪"; } if(y === 0 && x === 0) { ch = "0"; } if(y === ty && x === tx) { ch = "T"; } rope.slice(0, -1).reverse().forEach(([a, b], j) => { if(a === x && b === y) { ch = j+1; } }); if(y === hy && x === hx) { ch = "H"; } return ch; }); console.log(row.join("")); } console.log("\n\n"); }; (async () => { const input = await fs.readFile("./input.txt", 'utf8'); const lines = input.split("\n").map(t => t.split(" ")); //printGraph(); for (const [direction, times] of lines) { for(let i = 0; i < times; ++i) { //await keypress(); console.log("Moving ", direction); moveRope(direction); //printGraph(); tailVisited[`${rope[9][0]}~${rope[9][1]}`] = true; } } console.log(tailVisited); console.log(Object.values(tailVisited).length); })();