day 14
This commit is contained in:
parent
88dfa7677a
commit
0045c63046
85
2022/14/part1.js
Normal file
85
2022/14/part1.js
Normal file
@ -0,0 +1,85 @@
|
||||
import * as R from "remeda";
|
||||
import Victor from '@a-robu/victor';
|
||||
|
||||
import { readFile } from "../05/part1.js";
|
||||
|
||||
export const V = (...args) => new Victor(...args);
|
||||
const parseLine = line => line.match(/[\d,]+/g).map( x => eval(`[${x}]`) );
|
||||
|
||||
const readInput = (...args) =>
|
||||
R.pipe(
|
||||
readFile(...args),
|
||||
(lines) => lines.split("\n"),
|
||||
R.compact, // remove last line
|
||||
R.map( parseLine )
|
||||
);
|
||||
|
||||
export const puzzleInput = readInput(import.meta.url, "input");
|
||||
export const sample = readInput(import.meta.url, "sample");
|
||||
|
||||
|
||||
export function genCave(rocks) {
|
||||
const cave = {};
|
||||
for( const rock of rocks ) {
|
||||
const points = rock.map( Victor.fromArray );
|
||||
let from = points.shift();
|
||||
|
||||
while( points.length ) {
|
||||
/** @type Victor */
|
||||
const to = points.shift();
|
||||
const direction = to.clone().subtract(from).normalize();
|
||||
|
||||
R.times(to.clone().subtract(from).length()+1, () => {
|
||||
if(!cave[from.y]) cave[from.y] = {};
|
||||
cave[from.y][from.x] = '#';
|
||||
from.add(direction);
|
||||
});
|
||||
|
||||
from = to;
|
||||
}
|
||||
}
|
||||
return cave;
|
||||
|
||||
}
|
||||
|
||||
function pourSand(cave){
|
||||
cave = R.clone(cave);
|
||||
|
||||
let sand = 0;
|
||||
|
||||
/** @type Victor */
|
||||
let current;
|
||||
|
||||
const maxDepth = R.pipe(
|
||||
cave,
|
||||
R.keys,
|
||||
R.map( x => parseInt(x) ),
|
||||
R.maxBy( R.identity ),
|
||||
);
|
||||
|
||||
console.log({ maxDepth });
|
||||
|
||||
while(true) {
|
||||
if(!current) current = V(500,0);
|
||||
if( current.y > maxDepth ) return sand;
|
||||
|
||||
const next = [ [0,1],[-1,1],[1,1] ].map( args => V(...args) ).map(
|
||||
v => v.add(current)
|
||||
).find( v => ! (cave[v.y] && cave[v.y][v.x]) );
|
||||
if( next ) {
|
||||
current = next;
|
||||
}
|
||||
else {
|
||||
if( ! cave[current.y] ) cave[current.y] = {};
|
||||
cave[current.y][current.x] = 'o';
|
||||
sand++;
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default R.createPipe(
|
||||
genCave,
|
||||
pourSand,
|
||||
)
|
52
2022/14/part2.js
Normal file
52
2022/14/part2.js
Normal file
@ -0,0 +1,52 @@
|
||||
import * as R from "remeda";
|
||||
import { genCave, V } from './part1.js';
|
||||
|
||||
function pourSand(cave){
|
||||
cave = R.clone(cave);
|
||||
|
||||
let sand = 0;
|
||||
|
||||
/** @type Victor */
|
||||
let current;
|
||||
|
||||
const maxDepth = R.pipe(
|
||||
cave,
|
||||
R.keys,
|
||||
R.map( x => parseInt(x) ),
|
||||
R.maxBy( R.identity ),
|
||||
) + 1;
|
||||
|
||||
while(true) {
|
||||
if(!current) current = V(500,0);
|
||||
|
||||
if( current.y === maxDepth ) {
|
||||
if( ! cave[current.y] ) cave[current.y] = {};
|
||||
cave[current.y][current.x] = 'o';
|
||||
sand++;
|
||||
current = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
const next = [ [0,1],[-1,1],[1,1] ].map( args => V(...args) ).map(
|
||||
v => v.add(current)
|
||||
).find( v => ! (cave[v.y] && cave[v.y][v.x]) );
|
||||
|
||||
if( next ) {
|
||||
current = next;
|
||||
}
|
||||
else {
|
||||
if( current.y === 0 ) return 1+sand;
|
||||
|
||||
if( ! cave[current.y] ) cave[current.y] = {};
|
||||
cave[current.y][current.x] = 'o';
|
||||
sand++;
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default R.createPipe(
|
||||
genCave,
|
||||
pourSand,
|
||||
)
|
2
2022/14/sample
Normal file
2
2022/14/sample
Normal file
@ -0,0 +1,2 @@
|
||||
498,4 -> 498,6 -> 496,6
|
||||
503,4 -> 502,4 -> 502,9 -> 494,9
|
34
2022/14/test.js
Normal file
34
2022/14/test.js
Normal file
@ -0,0 +1,34 @@
|
||||
import { test, expect, describe } from "vitest";
|
||||
|
||||
import { expectSolution } from "../01/main.js";
|
||||
import part1, { genCave, sample, puzzleInput } from "./part1.js";
|
||||
import part2 from "./part2.js";
|
||||
|
||||
describe("part 1", () => {
|
||||
test("readInput", () => {
|
||||
expect(sample).toEqual([
|
||||
[[498,4], [498,6], [496,6]],
|
||||
[[503,4 ], [ 502,4 ], [ 502,9 ], [ 494,9]],
|
||||
])
|
||||
});
|
||||
test( 'genCave', () => {
|
||||
expect( genCave(sample) ).toMatchObject({
|
||||
4: { 498: '#' }
|
||||
});
|
||||
} )
|
||||
test("sample", () => {
|
||||
expect(part1(sample)).toEqual(24);
|
||||
});
|
||||
test("solution", () => {
|
||||
expectSolution(part1(puzzleInput)).toEqual(832);
|
||||
});
|
||||
});
|
||||
|
||||
describe.only("part 2", () => {
|
||||
test("sample", () => {
|
||||
expect(part2(sample)).toEqual(93);
|
||||
});
|
||||
test("solution", () => {
|
||||
expectSolution(part2(puzzleInput)).toEqual(27601);
|
||||
});
|
||||
});
|
@ -19,5 +19,8 @@
|
||||
"remeda": "^1.3.0",
|
||||
"vite": "^4.0.1",
|
||||
"vitest": "0.25.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitest/ui": "^0.25.8"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user