diff --git a/2024/days/day-22/README.md b/2024/days/day-22/README.md new file mode 100644 index 0000000..8cf7782 --- /dev/null +++ b/2024/days/day-22/README.md @@ -0,0 +1,28 @@ +# Benchmark + +``` +Platform: darwin arm64 +CPU: Apple M3 Pro 11 Cores +Memory: 18.00 GB +``` + +## Sample 1 + +| part | time (~) | μs | +| ---- | -------- | ------------------- | +| 1 | 0.49ms | 0.49287499999999973 | +| 2 | 4.43ms | 4.432334000000001 | + +## Sample 2 + +| part | time (~) | μs | +| ---- | -------- | -------------------- | +| 1 | 0.02ms | 0.024167000000002048 | +| 2 | 3.28ms | 3.280583 | + +## Answer + +| part | time (~) | μs | +| ---- | -------- | ----------------- | +| 1 | 8.46ms | 8.462292000000001 | +| 2 | 692.41ms | 692.41475 | diff --git a/2024/days/day-22/in.sample.1.txt b/2024/days/day-22/in.sample.1.txt new file mode 100644 index 0000000..07b41ba --- /dev/null +++ b/2024/days/day-22/in.sample.1.txt @@ -0,0 +1,4 @@ +1 +10 +100 +2024 diff --git a/2024/days/day-22/in.sample.2.txt b/2024/days/day-22/in.sample.2.txt new file mode 100644 index 0000000..201df76 --- /dev/null +++ b/2024/days/day-22/in.sample.2.txt @@ -0,0 +1,4 @@ +1 +2 +3 +2024 diff --git a/2024/days/day-22/main.js b/2024/days/day-22/main.js new file mode 100644 index 0000000..d3bb17c --- /dev/null +++ b/2024/days/day-22/main.js @@ -0,0 +1,75 @@ +const fs = require('fs'); + +function parse(source) { + return source.trim().split('\n').map(Number); +} + +const N = 2000; + +function gen(seed) { + const offset = 16777215; + seed ^= (seed << 6) & offset; + seed ^= (seed >> 5) & offset; + seed ^= (seed << 11) & offset; + return seed; +} + +function genNth(seed, n) { + while (n--) { + seed = gen(seed); + } + return seed; +} + +const next = (seed) => { + const newSeed = gen(seed); + return { + seed: newSeed, + price: newSeed % 10, + change: (newSeed % 10) - (seed % 10), + }; +}; + +function genSequences(seed, N) { + const m = new Map(); + + const window = new Array(4).fill(null); + for (let i = 0; i < window.length; ++i) { + window[i] = next(window[i - 1]?.seed ?? seed); + } + + for (let i = 4; i < N - 1; ++i) { + const hash = window.map(({ change }) => change).join(','); + const prev = window.at(-1); + m.set(hash, Math.max(m.get(hash) ?? 0, prev.price)); + window.push(next(prev.seed)); + window.shift(); + } + + return m; +} + +function getMaxBananas(seeds, N) { + const m = new Map(); + let max = 0; + seeds.forEach((seed) => + genSequences(seed, N) + .entries() + .forEach(([hash, value]) => { + const sum = (m.get(hash) ?? 0) + value; + max = Math.max(sum, max); + m.set(hash, sum); + }) + ); + return max; +} + +function part1(data) { + return Number(data.reduce((sum, seed) => sum + genNth(seed, N), 0)); +} + +function part2(data) { + return getMaxBananas(data, N); +} + +module.exports = { parse, part1, part2 };