From 2dc097383cf973cbf61a2b4e0ea0eaacd8126a6e Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 18 Dec 2024 23:21:58 +0000 Subject: [PATCH] Try with branch caching again --- 2024/16/index.ts | 5 --- 2024/18/index.ts | 105 ++++++++++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/2024/16/index.ts b/2024/16/index.ts index 526ef1e..5c4a04e 100644 --- a/2024/16/index.ts +++ b/2024/16/index.ts @@ -106,8 +106,6 @@ for (let y = 1; y < height - 1; y++) { let fastest: number|null = null; -const scoreCache: { [key: string]: [number, Coord, Dir] } = {}; - const branchCache: { [key: string]: number } = {}; const scores: Array<[number, Array]> = []; @@ -125,9 +123,6 @@ function getScoresAfterPosition(pos: Coord, dir: Dir, currentScore = 0, path: Ar } else { branchCache[cacheKey] = currentScore; } - if (lastBranch) { - scoreCache[`${lastBranch[1].x},${lastBranch[1].y}`] = [currentScore - lastBranch[0], pos, dir]; - } lastBranch = [currentScore, pos]; } [dir, nextDir(dir), prevDir(dir)].forEach((newDir, i) => { diff --git a/2024/18/index.ts b/2024/18/index.ts index 2b208ba..69d75cf 100644 --- a/2024/18/index.ts +++ b/2024/18/index.ts @@ -58,9 +58,27 @@ function prevDir(dir: Dir): Dir { return directions[i]; } -function printMap() { +function isBranch(pos: Coord, dir: Dir): boolean { + const leftDir = prevDir(dir); + const rightDir = nextDir(dir); + const next = nextCoord(pos, dir); + const left = nextCoord(pos, leftDir); + const right = nextCoord(pos, rightDir); + const nextChar = get(next); + const leftChar = get(left); + const rightChar = get(right); + return nextChar === '.' && leftChar === '.' + || nextChar === '.' && rightChar === '.' + || leftChar === '.' && rightChar === '.'; +} + +function printMap(path: Array = []) { const mapClone = map.slice().map((row: Array) => row.slice()); + path.forEach(({ x, y }) => { + mapClone[y][x] = 'O'; + }); console.log(mapClone.map((row: Array) => row.join('')).join("\n")); + console.log("\n"); } function nextCoord(pos: Coord, direction: Dir): Coord { @@ -93,7 +111,6 @@ function fillDeadEnd(pos: Coord): void { }; } printMap(); -console.log("\n"); for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { @@ -110,39 +127,51 @@ for (let y = 0; y < height; y++) { printMap(); -//let fastest: number|null = null; -// -//const scoreCache: { [key: string]: [number, Coord, Dir] } = {}; -// -//const branchCache: { [key: string]: number } = {}; -// -//const scores: Array = []; -// -//function getScoresAfterPosition(pos: Coord, dir: Dir, path: Array = []): void { -// if (fastest !== null && path.length >= fastest) { -// return; -// } -// [dir, nextDir(dir), prevDir(dir)].forEach((newDir, i) => { -// const next = nextCoord(pos, newDir); -// const nextStr = `${next.x},${next.y}`; -// if (!path.includes(nextStr)) { -// if (next.x === width - 1 && next.y === height - 1) { -// if (fastest === null || path.length < fastest) { -// fastest = path.length; -// } -// scores.push(path.length); -// return; -// } else if (next.x >= 0 && next. x < width && next.y >= 0 && next.y < height && get(next) === '.') { -// getScoresAfterPosition(next, newDir, [...path, nextStr]); -// } -// } -// }); -// -// return; -//} -// -//getScoresAfterPosition({ x: 0, y: 0 }, Dir.Up, ['0,0']); -// -//console.log(scores); -//const fastestScore = Math.min(...scores); -// +let fastest: number|null = null; + +const scoreCache: { [key: string]: [number, Coord, Dir] } = {}; + +const branchCache: { [key: string]: number } = {}; + +const scores: Array> = []; + +function getScoresAfterPosition(pos: Coord, dir: Dir, path: Array = [], lastBranch: [number, Coord]|null = null): void { + if (fastest !== null && path.length >= fastest) { + return; + } + const branch = isBranch(pos, dir); + if (branch) { + const cacheKey = `${pos.x},${pos.y},${dir}`; + const cache = branchCache[cacheKey]; + if (cache && cache < path.length) { + return; + } else { + branchCache[cacheKey] = path.length; + } + lastBranch = [path.length, pos]; + } + [dir, nextDir(dir), prevDir(dir)].forEach((newDir, i) => { + const next = nextCoord(pos, newDir); + if (!path.find(({ x, y }) => next.x === x && next.y === y)) { + if (next.x === width - 1 && next.y === height - 1) { + if (fastest === null || path.length < fastest) { + fastest = path.length; + } + scores.push(path); + return; + } else if (next.x >= 0 && next. x < width && next.y >= 0 && next.y < height && get(next) === '.') { + getScoresAfterPosition(next, newDir, [...path, next], lastBranch); + } + } + }); + + return; +} + +getScoresAfterPosition({ x: 0, y: 0 }, Dir.Up, [{ x: 0, y: 0 }]); + +console.log(scores); +const fastestScore = Math.min(...scores.map((p) => p.length)); +const fastestPath = scores.find((p) => p.length === fastestScore); +printMap(fastestPath); +console.log(fastestScore);