Merge branch '2023-04'
This commit is contained in:
commit
95e008b276
38
2023/04/benchmark.js
Normal file
38
2023/04/benchmark.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import fs from "fs-extra";
|
||||||
|
import { parse } from "yaml";
|
||||||
|
import { Bench } from "tinybench";
|
||||||
|
import assert from "assert";
|
||||||
|
|
||||||
|
import { solution_1 } from "./part1.js";
|
||||||
|
import { solution_2 } from "./part2.js";
|
||||||
|
|
||||||
|
const input = fs.readFileSync("./input", { encoding: "utf8" });
|
||||||
|
const solutions = parse(
|
||||||
|
fs.readFileSync("./solutions.yml", { encoding: "utf8" })
|
||||||
|
);
|
||||||
|
|
||||||
|
const bench = new Bench({ time: 10000 });
|
||||||
|
|
||||||
|
bench
|
||||||
|
.add("1", () => {
|
||||||
|
assert.equal(solution_1(input), solutions[1]);
|
||||||
|
})
|
||||||
|
.add("2", () => {
|
||||||
|
assert.equal(solution_2(input), solutions[2]);
|
||||||
|
});
|
||||||
|
|
||||||
|
await bench.run();
|
||||||
|
|
||||||
|
bench.tasks.forEach(({ result, name }) => {
|
||||||
|
console.log(
|
||||||
|
JSON.stringify({
|
||||||
|
day: 1,
|
||||||
|
year: 2023,
|
||||||
|
language: "javascript",
|
||||||
|
part: name,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
time: result.mean / 1000,
|
||||||
|
persec: 1000 / result.mean,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
12
2023/04/benchmark.test.js
Normal file
12
2023/04/benchmark.test.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { bench, expect } from "vitest";
|
||||||
|
import { readFileSync } from "fs-extra";
|
||||||
|
import { parse } from "yaml";
|
||||||
|
|
||||||
|
import { solution_1 } from "./part1.js";
|
||||||
|
|
||||||
|
const input = readFileSync("./input", { encoding: "utf8" });
|
||||||
|
const solutions = parse(readFileSync("./solutions.yml", { encoding: "utf8" }));
|
||||||
|
|
||||||
|
bench("part 1", () => {
|
||||||
|
expect(solution_1(input)).toBe(solutions[1]);
|
||||||
|
});
|
6
2023/04/example
Normal file
6
2023/04/example
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
|
||||||
|
Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
|
||||||
|
Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1
|
||||||
|
Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
|
||||||
|
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
|
||||||
|
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11
|
28
2023/04/part1.js
Normal file
28
2023/04/part1.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import * as R from "remeda";
|
||||||
|
|
||||||
|
export const slice_and_dice = R.createPipe(
|
||||||
|
(l) =>
|
||||||
|
l
|
||||||
|
.replace(/Card \d+:/, "")
|
||||||
|
.split("|")
|
||||||
|
.map((segment) => segment.split(" ").filter(R.identity)),
|
||||||
|
([winning, mine]) => {
|
||||||
|
let seen = {};
|
||||||
|
winning.forEach((n) => (seen[n] = true));
|
||||||
|
let got = mine.filter((n) => seen[n]).length;
|
||||||
|
return got;
|
||||||
|
},
|
||||||
|
(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) {
|
||||||
|
return R.pipe(
|
||||||
|
input,
|
||||||
|
get_lines,
|
||||||
|
R.map(slice_and_dice),
|
||||||
|
R.sumBy(R.identity)
|
||||||
|
);
|
||||||
|
}
|
31
2023/04/part2.js
Normal file
31
2023/04/part2.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import * as R from "remeda";
|
||||||
|
|
||||||
|
import { get_lines } from "./part1.js";
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
2
2023/04/solutions.yml
Normal file
2
2023/04/solutions.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1: 23678
|
||||||
|
2: 15455663
|
23
2023/04/test.js
Normal file
23
2023/04/test.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { test, expect } from "vitest";
|
||||||
|
import { readFileSync } from "fs-extra";
|
||||||
|
import { parse } from "yaml";
|
||||||
|
|
||||||
|
import { solution_1, slice_and_dice } from "./part1.js";
|
||||||
|
import { solution_2 } from "./part2.js";
|
||||||
|
|
||||||
|
const input = readFileSync("./input", { encoding: "utf8" });
|
||||||
|
const example = readFileSync("./example", { encoding: "utf8" });
|
||||||
|
const solutions = parse(readFileSync("./solutions.yml", { encoding: "utf8" }));
|
||||||
|
|
||||||
|
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(solution_1(example)).toBe(13);
|
||||||
|
expect(solution_1(input)).toBe(solutions["1"]);
|
||||||
|
});
|
||||||
|
test("part 2", () => {
|
||||||
|
expect(solution_2(example)).toBe(30);
|
||||||
|
expect(solution_2(input)).toBe(solutions["2"]);
|
||||||
|
});
|
@ -6,5 +6,7 @@
|
|||||||
{"language":"perl","timestamp":"2023-12-02T16:40:55","part":2,"day":"2","time":0.00338658146964856,"year":"2023","persec":295.283018867925}
|
{"language":"perl","timestamp":"2023-12-02T16:40:55","part":2,"day":"2","time":0.00338658146964856,"year":"2023","persec":295.283018867925}
|
||||||
{"timestamp":"2023-12-02T18:29:20","day":"2","part":1,"variant":"v2","year":"2023","time":0.00388473053892216,"language":"perl","persec":257.418111753372}
|
{"timestamp":"2023-12-02T18:29:20","day":"2","part":1,"variant":"v2","year":"2023","time":0.00388473053892216,"language":"perl","persec":257.418111753372}
|
||||||
{"day":"2","timestamp":"2023-12-02T18:29:32","part":2,"year":"2023","variant":"v2","persec":258.117195004803,"language":"perl","time":0.00387420915519166}
|
{"day":"2","timestamp":"2023-12-02T18:29:32","part":2,"year":"2023","variant":"v2","persec":258.117195004803,"language":"perl","time":0.00387420915519166}
|
||||||
{"time":0.00837944664031621,"timestamp":"2023-12-03T20:10:46","parsec":119.339622641509,"day":"3","year":"2023","part":1,"language":"perl"}
|
{"time":0.00837944664031621,"timestamp":"2023-12-03T20:10:46","persec":119.339622641509,"day":"3","year":"2023","part":1,"language":"perl"}
|
||||||
{"year":"2023","day":"3","parsec":4.03940886699507,"language":"perl","part":2,"time":0.247560975609756,"timestamp":"2023-12-03T20:10:59"}
|
{"year":"2023","day":"3","persec":4.03940886699507,"language":"perl","part":2,"time":0.247560975609756,"timestamp":"2023-12-03T20:10:59"}
|
||||||
|
{"day":4,"year":2023,"language":"javascript","part":"1","timestamp":"2023-12-04T15:22:09.048Z","time":0.0021685645699029317,"persec":461.13452828603647}
|
||||||
|
{"day":4,"year":2023,"language":"javascript","part":"2","timestamp":"2023-12-04T15:22:09.052Z","time":0.002291685911610818,"persec":436.3599719025647}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
export default definePreset({
|
export default definePreset({
|
||||||
name: 'day',
|
name: 'day',
|
||||||
options: {
|
options: {
|
||||||
perl: true,
|
perl: false,
|
||||||
|
js: false,
|
||||||
},
|
},
|
||||||
handler: async(context) => {
|
handler: async(context) => {
|
||||||
if( context.options.perl ) {
|
if( context.options.perl ) {
|
||||||
await extractTemplates({
|
await extractTemplates({
|
||||||
from: 'perl', whenConflict: 'skip'
|
from: 'perl', whenConflict: 'skip'
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
if( context.options.js ) {
|
||||||
|
await extractTemplates({
|
||||||
|
from: 'js', whenConflict: 'skip'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// ...
|
// ...
|
||||||
},
|
},
|
||||||
|
33
2023/preset/day/templates/js/benchmark.js
Normal file
33
2023/preset/day/templates/js/benchmark.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import fs from 'fs-extra';
|
||||||
|
import { parse } from 'yaml';
|
||||||
|
import { Bench } from 'tinybench';
|
||||||
|
import assert from 'assert';
|
||||||
|
|
||||||
|
import { solution_1 } from './part1.js';
|
||||||
|
import { solution_2 } from './part2.js';
|
||||||
|
|
||||||
|
const input = fs.readFileSync('./input',{ encoding: 'utf8'});
|
||||||
|
const solutions = parse( fs.readFileSync('./solutions.yml',{encoding:'utf8'}));
|
||||||
|
|
||||||
|
const bench = new Bench({time: 10000});
|
||||||
|
|
||||||
|
bench.add( '1', () => {
|
||||||
|
assert.equal(solution_1(input),solutions[1])
|
||||||
|
})
|
||||||
|
.add( '2', () => {
|
||||||
|
assert.equal(solution_2(input),solutions[2])
|
||||||
|
});
|
||||||
|
|
||||||
|
await bench.run();
|
||||||
|
|
||||||
|
bench.tasks.forEach( ({result,name}) => {
|
||||||
|
console.log(JSON.stringify({
|
||||||
|
day : 1,
|
||||||
|
year : 2023,
|
||||||
|
language: 'javascript',
|
||||||
|
part: name,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
time: result.mean / 1000,
|
||||||
|
persec: 1000 / result.mean,
|
||||||
|
}));
|
||||||
|
})
|
13
2023/preset/day/templates/js/benchmark.test.js
Normal file
13
2023/preset/day/templates/js/benchmark.test.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { bench, expect } from 'vitest';
|
||||||
|
import { readFileSync } from 'fs-extra';
|
||||||
|
import { parse } from 'yaml';
|
||||||
|
|
||||||
|
import { solution_1 } from './part1.js';
|
||||||
|
|
||||||
|
const input = readFileSync('./input',{ encoding: 'utf8'});
|
||||||
|
const solutions = parse( readFileSync('./solutions.yml',{encoding:'utf8'}));
|
||||||
|
|
||||||
|
bench( 'part 1', () => {
|
||||||
|
expect(solution_1(input)).toBe(solutions[1])
|
||||||
|
});
|
||||||
|
|
6
2023/preset/day/templates/js/part1.js
Normal file
6
2023/preset/day/templates/js/part1.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import * as R from 'remeda';
|
||||||
|
|
||||||
|
|
||||||
|
export function solution_1(input) {
|
||||||
|
|
||||||
|
}
|
5
2023/preset/day/templates/js/part2.js
Normal file
5
2023/preset/day/templates/js/part2.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import * as R from 'remeda';
|
||||||
|
|
||||||
|
import { } from './part1.js';
|
||||||
|
|
||||||
|
export function solution_2(input){}
|
16
2023/preset/day/templates/js/test.js
Normal file
16
2023/preset/day/templates/js/test.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { test, expect } from 'vitest';
|
||||||
|
import { readFileSync } from 'fs-extra';
|
||||||
|
import { parse } from 'yaml';
|
||||||
|
|
||||||
|
import { solution_1 } from './part1.js';
|
||||||
|
import { solution_2 } from './part2.js';
|
||||||
|
|
||||||
|
const input = readFileSync('./input',{ encoding: 'utf8'});
|
||||||
|
const solutions = parse( readFileSync('./solutions.yml',{encoding:'utf8'}));
|
||||||
|
|
||||||
|
test( 'part 1', () => {
|
||||||
|
expect( solution_1(input)).toBe(solutions['1']);
|
||||||
|
})
|
||||||
|
test( 'part 2', () => {
|
||||||
|
expect( solution_2(input)).toBe(solutions['2']);
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user