diff --git a/2024/src/2024/day20/day20.ts b/2024/src/2024/day20/day20.ts index 70005a4..33588f0 100644 --- a/2024/src/2024/day20/day20.ts +++ b/2024/src/2024/day20/day20.ts @@ -33,9 +33,10 @@ function countCheatsSavingAtLeast(grid: Grid, start: Coord, end: Coord, minCheat findCandidateCheats(grid).forEach(cheat => { const newGrid = new Map(grid); newGrid.set(cheat.serialize(), '.'); - const newLength = calcRacetrackLength(newGrid, start, end, length - minCheats); - if (newLength != -1) { - cheatMap.set(cheat.serialize(), length - newLength); + + const diff = calcLengthDiff(newGrid, cheat); + if (diff && diff >= minCheats) { + cheatMap.set(cheat.serialize(), diff); } }); @@ -53,6 +54,56 @@ type State = { curr: Coord, length: number } +type State2 = { + curr: Coord, + length: number, + path: string +} + +function calcLengthDiff(grid: Grid, cheat: Coord) { + let start: Coord; + let end: Coord; + const hNeighbors = getHorizontalNeighbors(cheat); + const vNeighbors = getVerticalNeighbors(cheat); + if (hNeighbors.every(n => grid.get(n.serialize()) === '.')) { + start = hNeighbors[0]; + end = hNeighbors[1]; + } else { + start = vNeighbors[0]; + end = vNeighbors[1]; + } + + let oneEndReached = false; + let firstPathLength = -1; + + const visited = new Set(); + const queue: State2[] = [{ curr: start, length: 0, path: start.serialize()}]; + while (queue.length > 0) { + const { curr, length, path } = queue.shift()!; + + const visitedKey = `${curr.serialize()}` + + if (curr.equals(end)) { + if (oneEndReached) { + return Math.abs(firstPathLength - length); + } + firstPathLength = length + oneEndReached = true; + continue; + } else { + if (visited.has(visitedKey)) + continue; + + visited.add(visitedKey); + } + const neighbors = getNeighborCoords(curr).filter(c => grid.get(c.serialize()) === '.' && !visited.has(c.serialize()))!; + neighbors.forEach(n => { + queue.push({ curr: n, length: length + 1, path: path + n.serialize() }); + }); + } + + console.log() +} function calcRacetrackLength(grid: Grid, start: Coord, end: Coord, maxLength?: number) { let curr = new Coord(start.x, start.y);