From 88dfa7677a69a71de1be8fee8a49a0765dd34306 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Wed, 14 Dec 2022 09:25:59 -0500 Subject: [PATCH] changes to day 12 --- 2022/12/part1.js | 8 ++-- 2022/12/part2.js | 88 +++++++++++++++++++++++++++++++++++- 2022/12/test.js | 13 ++++-- _templates/day/new/part1.ejs | 8 ++-- _templates/package.json | 3 ++ package.json | 4 +- 6 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 _templates/package.json diff --git a/2022/12/part1.js b/2022/12/part1.js index de69c3c..7940bdb 100644 --- a/2022/12/part1.js +++ b/2022/12/part1.js @@ -10,7 +10,7 @@ const readInput = (...args) => readFile(...args), (lines) => lines.split("\n"), R.compact, // remove last line - R.map((line) => line.split("").map( c => c ==='S' ? '`' : c === 'E' ? '{' : c )) + R.map( l => l.split('') ), ); export const puzzleInput = readInput(import.meta.url, "input"); @@ -19,7 +19,7 @@ export const sample = readInput(import.meta.url, "sample"); export const findStart = (topoMap) => { let y; let x = R.findIndex(topoMap, (row) => { - let z = row.indexOf("`"); + let z = row.indexOf("S"); if (z === -1) return false; y = z; return true; @@ -30,7 +30,7 @@ export const findStart = (topoMap) => { export const findEnd = (topoMap) => { let y; let x = R.findIndex(topoMap, (row) => { - let z = row.indexOf("{"); + let z = row.indexOf("E"); if (z === -1) return false; y = z; return true; @@ -62,6 +62,8 @@ function findShortestPath(topoMap) { initial.steps = 0; const final = findEnd(topoMap); + topoMap = topoMap.map( line => line.map( c => c.replace( 'S', 'a' ).replace('E','z') ) ); + const potentials = [ initial ]; const beenThere = topoMap.map( diff --git a/2022/12/part2.js b/2022/12/part2.js index 10fc179..25129ee 100644 --- a/2022/12/part2.js +++ b/2022/12/part2.js @@ -1,4 +1,90 @@ import * as R from "remeda"; +import Victor from "@a-robu/victor"; +import { readFile } from "../05/part1.js"; -export default () => {}; +const V = (x,y) => new Victor(x,y); + +export const findAs = (topoMap) => { + const locations = []; + + topoMap.forEach( (line,x) => line.forEach( (v,y) => { + if( v === 'a' ) locations.push( [x,y] ) + } ) ); + + return locations; +}; + +export const findEnd = (topoMap) => { + let y; + let x = R.findIndex(topoMap, (row) => { + let z = row.indexOf("E"); + if (z === -1) return false; + y = z; + return true; + }); + return V(x,y); +}; + +const directions = [ [0,1], [0,-1],[1,0],[-1,0] ].map( + d => V(...d) +); + +const outOfMap = (maxX,maxY) => (loc) => { + if( Math.min( loc.x, loc.y ) < 0 ) return true; + if( loc.x >= maxX ) return true; + if( loc.y >= maxY ) return true; + return false; +} + +const isReachable = (topoMap,pos) => { + const baseline = topoMap[pos.x][pos.y].charCodeAt(0); + + return (next) => { +return baseline - topoMap[next.x][next.y].charCodeAt(0) <= 1; + } +} + +function findShortestPath(topoMap) { + const final = findEnd(topoMap); + final.steps = 0; + + topoMap = topoMap.map( line => line.map( c => c.replace( 'S', 'a' ).replace('E','z') ) ); + + const initial = findAs(topoMap); + + const potentials = [ final ]; + + const beenThere = topoMap.map( + line => line.map( () => 9999 ) + ); + + const oom = outOfMap(topoMap.length,topoMap[0].length ); + + let failsafe = 10; //topoMap.length*topoMap[0].length ; + while( potentials.length > 0 ) { + // if(! failsafe--) return; + const pos = potentials.shift(); // depth-first + + if( beenThere[pos.x][pos.y] <= pos.steps ) continue; + beenThere[pos.x][pos.y] = pos.steps; + + const next = directions.map( + d => d.clone().add(pos) + ).filter( R.isNot(oom )) + .filter( isReachable(topoMap,pos) ); + + next.forEach( n => n.steps = pos.steps + 1 ); + + potentials.push(...next); + } + + return R.pipe( + initial, + R.map(([x,y]) => beenThere[x][y]), + R.minBy( R.identity ) + ) + +} + +export default findShortestPath; diff --git a/2022/12/test.js b/2022/12/test.js index a8602c1..8be46ee 100644 --- a/2022/12/test.js +++ b/2022/12/test.js @@ -8,18 +8,21 @@ describe("part 1", () => { test("findStart", () => { expect(findStart(sample).toArray()).toEqual([0, 0]); }); - test.only("sample", () => { + test("sample", () => { expect(part1(sample)).toEqual(31); }); - test.only("solution",() => { + test("solution",() => { const r = part1(puzzleInput); expect(r).toBeLessThan(9999); expectSolution(r).toEqual(361); }); }); -describe("part 2", () => { - test.todo("solution", () => { - expectSolution(part2(puzzleInput)).toEqual("TODO"); +describe.only("part 2", () => { + test("sample", () => { + expect(part2(sample)).toEqual(29); + }); + test("solution", () => { + expectSolution(part2(puzzleInput)).toEqual(354); }); }); diff --git a/_templates/day/new/part1.ejs b/_templates/day/new/part1.ejs index 33430d6..8a664ec 100644 --- a/_templates/day/new/part1.ejs +++ b/_templates/day/new/part1.ejs @@ -6,9 +6,11 @@ import * as R from "remeda"; import { readFile } from "../05/part1.js"; const readInput = (...args) => - readFile(...args) - .split("\n") - .filter((x) => x); + R.pipe( + readFile(...args), + (lines) => lines.split("\n"), + R.compact, // remove last line + ); export const puzzleInput = readInput(import.meta.url, "input"); export const sample = readInput(import.meta.url, "sample"); diff --git a/_templates/package.json b/_templates/package.json new file mode 100644 index 0000000..1cd945a --- /dev/null +++ b/_templates/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/package.json b/package.json index 232dcb9..368555b 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "type": "module", "name": "2022", "version": "1.0.0", "description": "", @@ -16,6 +17,7 @@ "memoizerific": "^1.11.3", "prettier": "^2.8.0", "remeda": "^1.3.0", - "vitest": "^0.25.3" + "vite": "^4.0.1", + "vitest": "0.25.7" } }