From eb983643f60216f6dc003d6b2ae02c461460523d Mon Sep 17 00:00:00 2001 From: Alex | Kronox Date: Sun, 17 Dec 2023 17:53:02 +0100 Subject: [PATCH] more efficient 2023-17 --- 2023/17/task.ts | 148 ++++++++++++------------------------------------ 1 file changed, 35 insertions(+), 113 deletions(-) diff --git a/2023/17/task.ts b/2023/17/task.ts index c729e73..d42d790 100644 --- a/2023/17/task.ts +++ b/2023/17/task.ts @@ -1,135 +1,57 @@ export async function taskOne(input: string[]): Promise { - const graph = input.map(i => i.split("")).map(r => r.map(c => parseInt(c))) - const g = algo1(graph) - let min = Infinity - for (let d of Dirs) { - for (let i = 0; i <=3; i++) { - if (g[g.length-1][g[0].length-1][d][i as DirLen1] < min) { - min = g[g.length-1][g[0].length-1][d][i as DirLen1] - } - } - } - console.log(min) + task(input, 0, 3) } export async function taskTwo(input: string[]): Promise { + task(input, 4, 10) +} + +function task(input: string[], minStraightLen: number, maxStraightLen: number) { const graph = input.map(i => i.split("")).map(r => r.map(c => parseInt(c))) - const g = algo2(graph) + const g = algo(graph, minStraightLen, maxStraightLen) let min = Infinity - for (let d of Dirs) { - for (let i = 4; i <=10; i++) { - if (g[g.length-1][g[0].length-1][d][i as DirLen1] < min) { - min = g[g.length-1][g[0].length-1][d][i as DirLen1] - } - } + for (let d of (['X','Y'] as Dir[])) { + if (g[g.length-1][g[0].length-1][d] < min) + min = g[g.length-1][g[0].length-1][d] } console.log(min) } +type Dir = 'X'|'Y' -type Dir = 'X+'|'X-'|'Y+'|'Y-' -const Dirs : Dir[] = ['X+', 'X-', 'Y+', 'Y-'] -type DirLen1 = 0|1|2|3 - - -const EMPTY_LENS = {0:Infinity, 1:Infinity, 2:Infinity,3:Infinity} -const NULL_LENS = {0:0, 1:Infinity, 2:Infinity, 3:Infinity} - -interface Step1 { +interface Step { x: number y: number d: Dir - l: DirLen1 } - -function algo1(g: number[][]) { - const d: Record>[][] = Array.from({length: g.length}, ()=> Array.from({length:g.length}, () =>{return{'X+':{...EMPTY_LENS},'X-':{...EMPTY_LENS},'Y-':{...EMPTY_LENS},'Y+':{...EMPTY_LENS}}})) - d[0][0] = {'X+':{...NULL_LENS},'X-':{...NULL_LENS},'Y-':{...NULL_LENS},'Y+':{...NULL_LENS}} - const Qu: Step1[] = [{x:0,y:0,d:'X+',l:0}] +function algo(g: number[][], minStraightLen: number, maxStraightLen: number) { + const d: Record[][] = Array.from({length: g.length}, ()=> Array.from({length:g.length}, () =>{return{'X':Infinity,'Y':Infinity}})) + d[0][0] = {'X':0,'Y':0} + const Qu: Step[] = [{x:0,y:0,d:'X'},{x:0,y:0,d:'Y'}] while (Qu.length > 0) { - const q = Qu.shift() as Step1 - for (const dir of Dirs) { - if (q.d == dir && q.l >= 3) continue - if (opp[dir] == q.d) continue - const nX = q.x+dirX[dir] - const nY = q.y+dirY[dir] - if (nX < 0 || nY < 0 || nX >= g.length || nY >= g[0].length) continue - const temp = d[q.x][q.y][q.d][q.l] + g[nX][nY] - const nextLen = (q.d == dir ? q.l+1 : 1) as DirLen1 - if (temp < d[nX][nY][dir][nextLen]) { - d[nX][nY][dir][nextLen] = temp - Qu.push({ - x: nX, - y:nY, - d: dir, - l: nextLen - }) + const q = Qu.shift() as Step + for (const dir of [1,-1]) { + let nX = q.x + let nY = q.y + let temp = d[q.x][q.y][q.d] + const di = q.d == 'X' ? 'Y':'X' + for (let i = 1; i <= maxStraightLen; i++) { + if (di == 'X') nX += dir + if (di == 'Y') nY += dir + if (nX < 0 || nY < 0 || nX >= g.length || nY >= g[0].length) break + temp += g[nX][nY] + if (i < minStraightLen) continue + if(temp < d[nX][nY][di]) { + d[nX][nY][di] = temp + Qu.push({ + x: nX, + y:nY, + d: di + }) + } } } } return d } - -type DirLen2 = 0|1|2|3|4|5|6|7|8|9|10 -interface Step2 { - x: number - y: number - d: Dir - l: DirLen2 -} - -function getInifinite2() { - const r: Record = {} - for (let i = 0; i <= 10; i++) { - r[i] = Infinity - } - return r as Record -} -function getStart2() { - const r = getInifinite2() - r[0] = 0; - return r -} - -function algo2(g: number[][]) { - const d: Record>[][] = Array.from({length: g.length}, ()=> Array.from({length:g.length}, () =>{return{'X+':getInifinite2(),'X-':getInifinite2(),'Y-':getInifinite2(),'Y+':getInifinite2()}})) - d[0][0] = {'X+':getStart2(),'X-':getStart2(),'Y-':getStart2(),'Y+':getStart2()} - const Qu: Step2[] = [{x:0,y:0,d:'X+',l:0},{x:0,y:0,d:'Y+',l:0},{x:0,y:0,d:'X-',l:0},{x:0,y:0,d:'Y-',l:0}] - while (Qu.length > 0) { - const q = Qu.shift() as Step2 - for (const dir of Dirs) { - if (q.d == dir && q.l >= 10) continue - if (q.d != dir && q.l < 4) continue - if (opp[dir] == q.d) continue - const nX = q.x+dirX[dir] - const nY = q.y+dirY[dir] - if (nX < 0 || nY < 0 || nX >= g.length || nY >= g[0].length) continue - const temp = d[q.x][q.y][q.d][q.l] + g[nX][nY] - const nextLen = (q.d == dir ? q.l+1 : 1) as DirLen2 - if (temp < d[nX][nY][dir][nextLen]) { - d[nX][nY][dir][nextLen] = temp - Qu.push({ - x: nX, - y:nY, - d: dir, - l: nextLen - }) - } - } - } - return d -} - -const dirX = { - 'X+': 1, 'X-': -1, 'Y+': 0, 'Y-':0 -} - -const dirY = { - 'X+': 0, 'X-': 0, 'Y+': 1, 'Y-':-1 -} - -const opp = { - 'X+': 'X-', 'X-': 'X+', 'Y+': 'Y-', 'Y-':'Y+' -} -