This commit is contained in:
Yanick Champoux 2023-12-04 12:19:52 -05:00
parent 6481fb63cb
commit bd3952e9be
6 changed files with 110 additions and 78 deletions

View File

@ -1,33 +1,38 @@
import fs from 'fs-extra'; import fs from "fs-extra";
import { parse } from 'yaml'; import { parse } from "yaml";
import { Bench } from 'tinybench'; import { Bench } from "tinybench";
import assert from 'assert'; import assert from "assert";
import { solution_1 } from './part1.js'; import { solution_1 } from "./part1.js";
import { solution_2 } from './part2.js'; import { solution_2 } from "./part2.js";
const input = fs.readFileSync('./input',{ encoding: 'utf8'}); const input = fs.readFileSync("./input", { encoding: "utf8" });
const solutions = parse( fs.readFileSync('./solutions.yml',{encoding:'utf8'})); const solutions = parse(
fs.readFileSync("./solutions.yml", { encoding: "utf8" })
);
const bench = new Bench({time: 10000}); const bench = new Bench({ time: 10000 });
bench.add( '1', () => { bench
assert.equal(solution_1(input),solutions[1]) .add("1", () => {
}) assert.equal(solution_1(input), solutions[1]);
.add( '2', () => { })
assert.equal(solution_2(input),solutions[2]) .add("2", () => {
}); assert.equal(solution_2(input), solutions[2]);
});
await bench.run(); await bench.run();
bench.tasks.forEach( ({result,name}) => { bench.tasks.forEach(({ result, name }) => {
console.log(JSON.stringify({ console.log(
day : 1, JSON.stringify({
year : 2023, day: 1,
language: 'javascript', year: 2023,
language: "javascript",
part: name, part: name,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
time: result.mean / 1000, time: result.mean / 1000,
persec: 1000 / result.mean, persec: 1000 / result.mean,
})); })
}) );
});

View File

@ -1,13 +1,12 @@
import { bench, expect } from 'vitest'; import { bench, expect } from "vitest";
import { readFileSync } from 'fs-extra'; import { readFileSync } from "fs-extra";
import { parse } from 'yaml'; import { parse } from "yaml";
import { solution_1 } from './part1.js'; import { solution_1 } from "./part1.js";
const input = readFileSync('./input',{ encoding: 'utf8'}); const input = readFileSync("./input", { encoding: "utf8" });
const solutions = parse( readFileSync('./solutions.yml',{encoding:'utf8'})); const solutions = parse(readFileSync("./solutions.yml", { encoding: "utf8" }));
bench( 'part 1', () => { bench("part 1", () => {
expect(solution_1(input)).toBe(solutions[1]) expect(solution_1(input)).toBe(solutions[1]);
}); });

View File

@ -1,26 +1,28 @@
import * as R from 'remeda'; import * as R from "remeda";
export const slice_and_dice = R.createPipe( export const slice_and_dice = R.createPipe(
(l) => l.replace(/Card \d+:/,'').split('|').map( (l) =>
segment => segment.split(' ').filter(R.identity) l
), .replace(/Card \d+:/, "")
([winning,mine]) => { .split("|")
.map((segment) => segment.split(" ").filter(R.identity)),
([winning, mine]) => {
let seen = {}; let seen = {};
winning.forEach( n => seen[n] = true ); winning.forEach((n) => (seen[n] = true));
let got = mine.filter( n => seen[n] ).length; let got = mine.filter((n) => seen[n]).length;
return got; return got;
}, },
(n) => n == 0 ? 0 : Math.pow(2,n-1) (n) => (n == 0 ? 0 : Math.pow(2, n - 1))
); );
export const get_lines = R.createPipe( (i) => i.split("\n"),
R.compact);
export function solution_1(input) { export function solution_1(input) {
return R.pipe( return R.pipe(
input, input,
i => i.split("\n"), get_lines,
R.compact, R.map(slice_and_dice),
R.map(
slice_and_dice
),
R.sumBy(R.identity) R.sumBy(R.identity)
) );
} }

View File

@ -1,5 +1,31 @@
import * as R from 'remeda'; import * as R from "remeda";
import { } from './part1.js'; import { get_lines } from "./part1.js";
export function solution_2(input){} export function solution_2(input) {
const cards = get_lines(input);
const cards_won = cards.map(()=>1);
let total_won = 0;
while( cards.length ) {
// console.log(cards_won);
let card = cards.shift();
const [ winning, mine ] = card
.replace(/Card \d+:/, "")
.split("|")
.map((segment) => segment.split(" ").filter(R.identity));
let seen = {};
winning.forEach((n) => (seen[n] = true));
let got = mine.filter((n) => seen[n]).length;
R.range(1,got+1).forEach( i => {
cards_won[i] = (cards_won[i] ?? 0 ) +cards_won[0];
});
total_won += cards_won.shift()??0;
}
return total_won;
}

View File

@ -1,2 +1,2 @@
1: 23678 1: 23678
2: TODO 2: 15455663

View File

@ -1,23 +1,23 @@
import { test, expect } from 'vitest'; import { test, expect } from "vitest";
import { readFileSync } from 'fs-extra'; import { readFileSync } from "fs-extra";
import { parse } from 'yaml'; import { parse } from "yaml";
import { solution_1, slice_and_dice } from './part1.js'; import { solution_1, slice_and_dice } from "./part1.js";
import { solution_2 } from './part2.js'; import { solution_2 } from "./part2.js";
const input = readFileSync('./input',{ encoding: 'utf8'}); const input = readFileSync("./input", { encoding: "utf8" });
const example = readFileSync('./example',{ encoding: 'utf8'}); const example = readFileSync("./example", { encoding: "utf8" });
const solutions = parse( readFileSync('./solutions.yml',{encoding:'utf8'})); const solutions = parse(readFileSync("./solutions.yml", { encoding: "utf8" }));
test( 'part 1', () => { test("part 1", () => {
expect(
slice_and_dice("Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53")
).toBe(8);
expect( slice_and_dice( expect(solution_1(example)).toBe(13);
"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53" expect(solution_1(input)).toBe(solutions["1"]);
)).toBe(8); });
test("part 2", () => {
expect( solution_1(example)).toBe(13); expect(solution_2(example)).toBe(30);
expect( solution_1(input)).toBe(solutions['1']); expect(solution_2(input)).toBe(solutions["2"]);
}) });
test( 'part 2', () => {
expect( solution_2(input)).toBe(solutions['2']);
})