From 6481fb63cb25f4627743923101aae0e5321a9f45 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Mon, 4 Dec 2023 10:03:46 -0500 Subject: [PATCH 1/4] part 1 --- 2023/04/benchmark.js | 33 +++++++++++++++++++ 2023/04/benchmark.test.js | 13 ++++++++ 2023/04/example | 6 ++++ 2023/04/part1.js | 26 +++++++++++++++ 2023/04/part2.js | 5 +++ 2023/04/solutions.yml | 2 ++ 2023/04/test.js | 23 +++++++++++++ 2023/benchmark.json | 4 +-- 2023/preset/day/templates/js/benchmark.js | 33 +++++++++++++++++++ .../preset/day/templates/js/benchmark.test.js | 13 ++++++++ 2023/preset/day/templates/js/part1.js | 6 ++++ 2023/preset/day/templates/js/part2.js | 5 +++ 2023/preset/day/templates/js/test.js | 16 +++++++++ 13 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 2023/04/benchmark.js create mode 100644 2023/04/benchmark.test.js create mode 100644 2023/04/example create mode 100644 2023/04/part1.js create mode 100644 2023/04/part2.js create mode 100644 2023/04/solutions.yml create mode 100644 2023/04/test.js create mode 100644 2023/preset/day/templates/js/benchmark.js create mode 100644 2023/preset/day/templates/js/benchmark.test.js create mode 100644 2023/preset/day/templates/js/part1.js create mode 100644 2023/preset/day/templates/js/part2.js create mode 100644 2023/preset/day/templates/js/test.js diff --git a/2023/04/benchmark.js b/2023/04/benchmark.js new file mode 100644 index 0000000..5d7fe0c --- /dev/null +++ b/2023/04/benchmark.js @@ -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, + })); +}) diff --git a/2023/04/benchmark.test.js b/2023/04/benchmark.test.js new file mode 100644 index 0000000..4ec0bda --- /dev/null +++ b/2023/04/benchmark.test.js @@ -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]) +}); + diff --git a/2023/04/example b/2023/04/example new file mode 100644 index 0000000..9bdb874 --- /dev/null +++ b/2023/04/example @@ -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 diff --git a/2023/04/part1.js b/2023/04/part1.js new file mode 100644 index 0000000..9b97e40 --- /dev/null +++ b/2023/04/part1.js @@ -0,0 +1,26 @@ +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 function solution_1(input) { + return R.pipe( + input, + i => i.split("\n"), + R.compact, + R.map( + slice_and_dice + ), + R.sumBy(R.identity) + ) +} diff --git a/2023/04/part2.js b/2023/04/part2.js new file mode 100644 index 0000000..0eb2b95 --- /dev/null +++ b/2023/04/part2.js @@ -0,0 +1,5 @@ +import * as R from 'remeda'; + +import { } from './part1.js'; + +export function solution_2(input){} diff --git a/2023/04/solutions.yml b/2023/04/solutions.yml new file mode 100644 index 0000000..b3702b2 --- /dev/null +++ b/2023/04/solutions.yml @@ -0,0 +1,2 @@ +1: 23678 +2: TODO diff --git a/2023/04/test.js b/2023/04/test.js new file mode 100644 index 0000000..5500b5d --- /dev/null +++ b/2023/04/test.js @@ -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(input)).toBe(solutions['2']); +}) diff --git a/2023/benchmark.json b/2023/benchmark.json index 4d326db..5dcb558 100644 --- a/2023/benchmark.json +++ b/2023/benchmark.json @@ -6,5 +6,5 @@ {"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} {"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"} -{"year":"2023","day":"3","parsec":4.03940886699507,"language":"perl","part":2,"time":0.247560975609756,"timestamp":"2023-12-03T20:10:59"} +{"time":0.00837944664031621,"timestamp":"2023-12-03T20:10:46","persec":119.339622641509,"day":"3","year":"2023","part":1,"language":"perl"} +{"year":"2023","day":"3","persec":4.03940886699507,"language":"perl","part":2,"time":0.247560975609756,"timestamp":"2023-12-03T20:10:59"} diff --git a/2023/preset/day/templates/js/benchmark.js b/2023/preset/day/templates/js/benchmark.js new file mode 100644 index 0000000..5d7fe0c --- /dev/null +++ b/2023/preset/day/templates/js/benchmark.js @@ -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, + })); +}) diff --git a/2023/preset/day/templates/js/benchmark.test.js b/2023/preset/day/templates/js/benchmark.test.js new file mode 100644 index 0000000..4ec0bda --- /dev/null +++ b/2023/preset/day/templates/js/benchmark.test.js @@ -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]) +}); + diff --git a/2023/preset/day/templates/js/part1.js b/2023/preset/day/templates/js/part1.js new file mode 100644 index 0000000..2520ce0 --- /dev/null +++ b/2023/preset/day/templates/js/part1.js @@ -0,0 +1,6 @@ +import * as R from 'remeda'; + + +export function solution_1(input) { + +} diff --git a/2023/preset/day/templates/js/part2.js b/2023/preset/day/templates/js/part2.js new file mode 100644 index 0000000..0eb2b95 --- /dev/null +++ b/2023/preset/day/templates/js/part2.js @@ -0,0 +1,5 @@ +import * as R from 'remeda'; + +import { } from './part1.js'; + +export function solution_2(input){} diff --git a/2023/preset/day/templates/js/test.js b/2023/preset/day/templates/js/test.js new file mode 100644 index 0000000..5649d82 --- /dev/null +++ b/2023/preset/day/templates/js/test.js @@ -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']); +}) From bd3952e9bee012468b6138f61bdf8c11d04ad951 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Mon, 4 Dec 2023 12:19:52 -0500 Subject: [PATCH 2/4] part 2 --- 2023/04/benchmark.js | 57 +++++++++++++++++++++------------------ 2023/04/benchmark.test.js | 17 ++++++------ 2023/04/part1.js | 42 +++++++++++++++-------------- 2023/04/part2.js | 32 +++++++++++++++++++--- 2023/04/solutions.yml | 2 +- 2023/04/test.js | 38 +++++++++++++------------- 6 files changed, 110 insertions(+), 78 deletions(-) diff --git a/2023/04/benchmark.js b/2023/04/benchmark.js index 5d7fe0c..69b227e 100644 --- a/2023/04/benchmark.js +++ b/2023/04/benchmark.js @@ -1,33 +1,38 @@ -import fs from 'fs-extra'; -import { parse } from 'yaml'; -import { Bench } from 'tinybench'; -import assert from 'assert'; +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'; +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 input = fs.readFileSync("./input", { 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', () => { - assert.equal(solution_1(input),solutions[1]) -}) -.add( '2', () => { - assert.equal(solution_2(input),solutions[2]) -}); +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, - })); -}) +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, + }) + ); +}); diff --git a/2023/04/benchmark.test.js b/2023/04/benchmark.test.js index 4ec0bda..5fb0b6a 100644 --- a/2023/04/benchmark.test.js +++ b/2023/04/benchmark.test.js @@ -1,13 +1,12 @@ -import { bench, expect } from 'vitest'; -import { readFileSync } from 'fs-extra'; -import { parse } from 'yaml'; +import { bench, expect } from "vitest"; +import { readFileSync } from "fs-extra"; +import { parse } from "yaml"; -import { solution_1 } from './part1.js'; +import { solution_1 } from "./part1.js"; -const input = readFileSync('./input',{ encoding: 'utf8'}); -const solutions = parse( readFileSync('./solutions.yml',{encoding:'utf8'})); +const input = readFileSync("./input", { encoding: "utf8" }); +const solutions = parse(readFileSync("./solutions.yml", { encoding: "utf8" })); -bench( 'part 1', () => { - expect(solution_1(input)).toBe(solutions[1]) +bench("part 1", () => { + expect(solution_1(input)).toBe(solutions[1]); }); - diff --git a/2023/04/part1.js b/2023/04/part1.js index 9b97e40..5439f5b 100644 --- a/2023/04/part1.js +++ b/2023/04/part1.js @@ -1,26 +1,28 @@ -import * as R from 'remeda'; +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) + (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, - i => i.split("\n"), - R.compact, - R.map( - slice_and_dice - ), - R.sumBy(R.identity) - ) + return R.pipe( + input, + get_lines, + R.map(slice_and_dice), + R.sumBy(R.identity) + ); } diff --git a/2023/04/part2.js b/2023/04/part2.js index 0eb2b95..914fc35 100644 --- a/2023/04/part2.js +++ b/2023/04/part2.js @@ -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; +} diff --git a/2023/04/solutions.yml b/2023/04/solutions.yml index b3702b2..23a78b7 100644 --- a/2023/04/solutions.yml +++ b/2023/04/solutions.yml @@ -1,2 +1,2 @@ 1: 23678 -2: TODO +2: 15455663 diff --git a/2023/04/test.js b/2023/04/test.js index 5500b5d..27df077 100644 --- a/2023/04/test.js +++ b/2023/04/test.js @@ -1,23 +1,23 @@ -import { test, expect } from 'vitest'; -import { readFileSync } from 'fs-extra'; -import { parse } from 'yaml'; +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'; +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'})); +const input = readFileSync("./input", { encoding: "utf8" }); +const example = readFileSync("./example", { 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( -"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(input)).toBe(solutions['2']); -}) + 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"]); +}); From b7ef14ad6408336446f4a08bf7217aa3f8f33d14 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Mon, 4 Dec 2023 12:20:03 -0500 Subject: [PATCH 3/4] update benchmark --- 2023/benchmark.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/2023/benchmark.json b/2023/benchmark.json index 5dcb558..59a284c 100644 --- a/2023/benchmark.json +++ b/2023/benchmark.json @@ -8,3 +8,5 @@ {"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","persec":119.339622641509,"day":"3","year":"2023","part":1,"language":"perl"} {"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} From ef3f302a3d68c4543f974734c60dc299dd73b32c Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Mon, 4 Dec 2023 12:20:16 -0500 Subject: [PATCH 4/4] add js to the preset --- 2023/preset/day/preset.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/2023/preset/day/preset.ts b/2023/preset/day/preset.ts index 163677f..abdd037 100644 --- a/2023/preset/day/preset.ts +++ b/2023/preset/day/preset.ts @@ -1,13 +1,19 @@ export default definePreset({ name: 'day', options: { - perl: true, + perl: false, + js: false, }, handler: async(context) => { if( context.options.perl ) { await extractTemplates({ from: 'perl', whenConflict: 'skip' }) + } + if( context.options.js ) { + await extractTemplates({ + from: 'js', whenConflict: 'skip' + }) } // ... },