Yanick Champoux 2022-12-12 12:33:12 -05:00
parent 668776ef42
commit 1e2b8decfb
6 changed files with 214 additions and 0 deletions

41
2022/12/input Normal file
View File

@ -0,0 +1,41 @@
abcccccccccccccccccccccccccccccccaaaaaaaaaaaaaaaaccaaaaaaaaccccccccccccccccccccccccccccccccccccaaaaaa
abcccccccccccccccccccccccccccccccaaaaaaaaaaaaaaaaaccaaaaaaccccccccccccccccccccccccccccccccccccccaaaaa
abcccccccccccccccccccccccccccccccccaaaaaaaacccaaaaccaaaaaaccccccccccccccccccccaaaccccccccccccccccaaaa
abcccccccccccccccccccccccccccccccccccaaaaaaaccaaccccaaaaaaccccccccccccccccccccaaaccccccccccccccccaaaa
abcccccccccccccccccccccccccccccaaacccaaaaaaaacccccccaaccaaccccccccccccccccccccaaaccccccccccccccccaaac
abcccccccccccccccccccccccccccccaaaaaaaaacaaaacccccccccccccccaccaaccccccccccccciiaaccaaaccccccccccaacc
abccccccccaaccccccccccccccccccaaaaaaaaaaccaaacccccccccccccccaaaaaccccccccacaiiiiijjaaaacccccccccccccc
abacccaaccaacccccccccccccccccaaaaaaaaaaccccacccccaaaaccccccccaaaaacccccccaaiiiiijjjjaaaccccccaacccccc
abacccaaaaaacccccccccccccccccaaaaaaaaccccccccccccaaaacccccccaaaaaacccccccaiiiioojjjjjacccaaaaaacccccc
abcccccaaaaaaacccccccccccccccccaaaaaaccccaaccccccaaaacccccccaaaaccccccccciiinnoooojjjjcccaaaaaaaccccc
abccccccaaaaaccccccccccccccccccaaaaaacccaaaaccccccaaacccccccccaaaccccccchiinnnooooojjjjcccaaaaaaacccc
abcccccaaaaacccccccccccccccccccaacccccccaaaaccccccccccccccccccccccccccchhiinnnuuoooojjjjkcaaaaaaacccc
abccccaaacaaccccccccccccccccccccccccccccaaaaccccccccccccccccccaaacccchhhhhnnntuuuoooojjkkkkaaaacccccc
abccccccccaacccccccccccccccccccccccccccccccccccccccccccccccccccaacchhhhhhnnnnttuuuuoookkkkkkkaacccccc
abcccccccccccccccccccaacaaccccccccccccccccccccccccccccccccccaacaahhhhhhnnnnntttxuuuoopppppkkkkacccccc
abcccccccccccccccccccaaaaacccccccccaccccccccccccccccccccccccaaaaahhhhmnnnnntttxxxuuupppppppkkkccccccc
abccccccccccccccccccccaaaaacccccaaaacccccccccccccccccccccccccaaaghhhmmmmttttttxxxxuuuuuupppkkkccccccc
abcccccccccccccccccccaaaaaaaccccaaaaaaccccccccccccccccccccccccaagggmmmmtttttttxxxxuuuuuuvppkkkccccccc
abcccccccccccccccccccaaaaaaaaaaacaaaaacccccccccccccccccccccccaaagggmmmttttxxxxxxxyyyyyvvvppkkkccccccc
abccccccccccccccccccccaaaaaaaaaaaaaaaccccccccccccccccccccaacaaaagggmmmtttxxxxxxxyyyyyyvvppplllccccccc
SbcccccccccccccccccccaaaaaaaaaacaccaaccccccccccccccccccccaaaaaccgggmmmsssxxxxEzzzyyyyvvvpplllcccccccc
abcccccccccccccccccccccaaaaaaccccccccccccccaacaaccccccccaaaaaccccgggmmmsssxxxxyyyyyvvvvqqplllcccccccc
abccccccccccccccccccccccaaaaaacccccccccccccaaaacccccccccaaaaaacccgggmmmmsssswwyyyyyvvvqqqlllccccccccc
abcccccccccccccccccccccaaaaaaaccccccccccccaaaaacccccccccccaaaaccccgggmmmmsswwyyyyyyyvvqqllllccccccccc
abcccccccccccccccccccccaaaccaaacccccccccccaaaaaaccccccccccaccccccccgggooosswwwywwyyyvvqqlllcccccccccc
abccccccccccccccccccccccacccccccccccccccccacaaaacccccccccccccccccccfffooosswwwwwwwwvvvqqqllcccccccccc
abccccccccccccccccccccccccccccccccccccccccccaacccccccccccccccccccccfffooosswwwwwrwwvvvqqqllcccccccccc
abccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccffooossswwwrrrwvvvqqqmmcccccccccc
abccccaaacccccccccccccccccccccccccccccccccccccccccccccccccccccccccccffooosssrrrrrrrrqqqqmmmcccccccccc
abccccaaacaacccccaaccccaaaacccccccccccccccccccccccccccccccccccccccccffooossrrrrrnrrrqqqqmmmcccaaacccc
abcccccaaaaaccaaaaacccaaaaacccccccccccccccccccccccccccccccccccccccccfffoooorrnnnnnnmqqmmmmmcccaaacccc
abccaaaaaaaacccaaaaaccaaaaaaccccccccccccccccccccccccccccccccccccccccfffooonnnnnnnnnmmmmmmmcccaaaccccc
abcccaaaaacccccaaaaaccaaaaaaccccccaacccccccccccccccccccccccccccccccccfffoonnnnneddnmmmmmmccccaaaccccc
abccccaaaaacccaaaaacccaaaaaacccccaaaaaaccccccccccccccccccccaaccccccccffeeeeeeeeeddddddddccccaaaaccccc
abccccaacaaacccccaacccccaacccccccaaaaaaaccccccccccccccccaaaaaccccccccceeeeeeeeeedddddddddccaccaaccccc
abccccaacccccccccccccccccccccccccaaaaaaaccaaaccccccccccccaaaaaccccccccceeeeeeeeaaaaddddddcccccccccccc
abcccccccccccaaccccccccccccccccccccccaaaaaaaaacccccccccccaaaaacccccccccccccaaaacaaaacccccccccccccccaa
abccccccccaacaaacccccccccccccccccccccaaaaaaaacccccccccccaaaaaccccccccccccccaaaccaaaaccccccccccccccaaa
abccccccccaaaaacccccccccccccccccccccacaaaaaaccccccccccccccaaacccccccccccccccaccccaaacccccccccccacaaaa
abcccccccccaaaaaaccccccccccccccccaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccacccccccccccaaaaaa
abcccccccaaaaaaaaccccccccccccccccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccccccccccccccccaaaaaa

94
2022/12/part1.js Normal file
View File

@ -0,0 +1,94 @@
import * as R from "remeda";
import Victor from "@a-robu/victor";
import { readFile } from "../05/part1.js";
const V = (x,y) => new Victor(x,y);
const readInput = (...args) =>
R.pipe(
readFile(...args),
(lines) => lines.split("\n"),
R.compact, // remove last line
R.map((line) => line.split("").map( c => c ==='S' ? '`' : c === 'E' ? '{' : c ))
);
export const puzzleInput = readInput(import.meta.url, "input");
export const sample = readInput(import.meta.url, "sample");
export const findStart = (topoMap) => {
let y;
let x = R.findIndex(topoMap, (row) => {
let z = row.indexOf("`");
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 [0,1].includes(
topoMap[next.x][next.y].charCodeAt(0) - baseline
)
}
}
function findShortestPath(topoMap) {
const initial = findStart(topoMap);
initial.steps = 0;
initial.beenThere = [];
const potentials = [ initial ];
let bestSoFar;
const oom = outOfMap(topoMap.length,topoMap[0].length );
let failsafe = 100000;
while( potentials.length > 0 ) {
// if(! failsafe--) return;
const pos = potentials.pop(); // depth-first
//console.log(pos.steps, bestSoFar);
if( bestSoFar && (bestSoFar <= pos.steps) ) continue;
if( topoMap[pos.x][pos.y] === '{' ) {
bestSoFar = pos.steps;
continue;
}
const next = directions.map(
d => d.clone().add(pos)
).filter( R.isNot(oom ))
.filter( isReachable(topoMap,pos) )
.filter( next => !pos.beenThere.includes( next.toArray().join(',') ) );
next.forEach( n => n.steps = pos.steps + 1 );
next.forEach( n => n.beenThere = [
...pos.beenThere, pos.toArray().join(',')
] );
potentials.push(...next);
}
return bestSoFar;
}
export default findShortestPath;

4
2022/12/part2.js Normal file
View File

@ -0,0 +1,4 @@
import * as R from "remeda";
export default () => {};

44
2022/12/puzzle.md Normal file
View File

@ -0,0 +1,44 @@
\--- Day 12: Hill Climbing Algorithm ---
----------
You try contacting the Elves using your handheld device, but the river you're following must be too low to get a decent signal.
You ask the device for a heightmap of the surrounding area (your puzzle input). The heightmap shows the local area from above broken into a grid; the elevation of each square of the grid is given by a single lowercase letter, where `a` is the lowest elevation, `b` is the next-lowest, and so on up to the highest elevation, `z`.
Also included on the heightmap are marks for your current position (`S`) and the location that should get the best signal (`E`). Your current position (`S`) has elevation `a`, and the location that should get the best signal (`E`) has elevation `z`.
You'd like to reach `E`, but to save energy, you should do it in *as few steps as possible*. During each step, you can move exactly one square up, down, left, or right. To avoid needing to get out your climbing gear, the elevation of the destination square can be *at most one higher* than the elevation of your current square; that is, if your current elevation is `m`, you could step to elevation `n`, but not to elevation `o`. (This also means that the elevation of the destination square can be much lower than the elevation of your current square.)
For example:
```
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi
```
Here, you start in the top-left corner; your goal is near the middle. You could start by moving down or right, but eventually you'll need to head toward the `e` at the bottom. From there, you can spiral around to the goal:
```
v..v<<<<
>v.vv<<^
.>vv>E^^
..v>>>^^
..>>>>>^
```
In the above diagram, the symbols indicate whether the path exits each square moving up (`^`), down (`v`), left (`<`), or right (`>`). The location that should get the best signal is still `E`, and `.` marks unvisited squares.
This path reaches the goal in `*31*` steps, the fewest possible.
*What is the fewest steps required to move from your current position to the location that should get the best signal?*
To begin, [get your puzzle input](12/input).
Answer:
You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=%22Hill+Climbing+Algorithm%22+%2D+Day+12+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F12&related=ericwastl&hashtags=AdventOfCode) [Mastodon](javascript:void(0);)] this puzzle.

5
2022/12/sample Normal file
View File

@ -0,0 +1,5 @@
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi

26
2022/12/test.js Normal file
View File

@ -0,0 +1,26 @@
import { test, expect, describe } from "vitest";
import { expectSolution } from "../01/main.js";
import part1, { findStart, sample, puzzleInput } from "./part1.js";
import part2 from "./part2.js";
describe("part 1", () => {
test( "findStart", () => {
expect( findStart(sample).toArray() ).toEqual(
[0,0]
)
});
test( "sample", async () => {
expect(part1(sample)).toEqual(31);
});
test.only("solution", () => {
expectSolution(part1(puzzleInput)).toEqual("TODO");
});
});
describe("part 2", () => {
test.todo("solution", () => {
expectSolution(part2(puzzleInput)).toEqual("TODO");
});
});