Solve 2024-22
This commit is contained in:
@@ -21,8 +21,12 @@ describe('2024-20', () => {
|
|||||||
expect(solveFirst(testInput, 1)).toBe(14 + 14 + 2 + 4 + 2 + 3 + 5);
|
expect(solveFirst(testInput, 1)).toBe(14 + 14 + 2 + 4 + 2 + 3 + 5);
|
||||||
});
|
});
|
||||||
it('second', () => {
|
it('second', () => {
|
||||||
expect(solveSecond(testInput, 50)).toBe(
|
// it takes too long
|
||||||
32 + 31 + 29 + 39 + 25 + 23 + 20 + 19 + 12 + 14 + 12 + 22 + 4 + 3
|
// so only run while `NODE_ENV=production bun test --coverage`
|
||||||
);
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
expect(solveSecond(testInput, 50)).toBe(
|
||||||
|
32 + 31 + 29 + 39 + 25 + 23 + 20 + 19 + 12 + 14 + 12 + 22 + 4 + 3
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ describe('2024-21', () => {
|
|||||||
179A
|
179A
|
||||||
456A
|
456A
|
||||||
379A`;
|
379A`;
|
||||||
expect(solveFirst(testInput)).toBe(126384);
|
// it takes too long
|
||||||
|
// so only run while `NODE_ENV=production bun test --coverage`
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
expect(solveFirst(testInput)).toBe(126384);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="2024-22" type="BunRunConfiguration">
|
||||||
|
<option name="program" value="2024/22/run.ts" />
|
||||||
|
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { describe, expect, it } from 'bun:test';
|
||||||
|
import { solveFirst, solveSecond } from './index.ts';
|
||||||
|
|
||||||
|
describe('2024-22', () => {
|
||||||
|
it('first', () => {
|
||||||
|
const testInput = `1
|
||||||
|
10
|
||||||
|
100
|
||||||
|
2024`;
|
||||||
|
expect(solveFirst(testInput)).toBe(37327623);
|
||||||
|
});
|
||||||
|
it('second', () => {
|
||||||
|
// it takes too long
|
||||||
|
// so only run while `NODE_ENV=production bun test --coverage`
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
const testInput = `1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
2024`;
|
||||||
|
expect(solveSecond(testInput)).toBe(23);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import { Presets, SingleBar } from 'cli-progress';
|
||||||
|
import { sumArray } from '../../utils/array.ts';
|
||||||
|
import { mod } from '../../utils/numbers.ts';
|
||||||
|
|
||||||
|
export function solveFirst(input: string): number {
|
||||||
|
const start = input.split('\n').map(Number);
|
||||||
|
|
||||||
|
const end = start.map((v) => {
|
||||||
|
let value = v;
|
||||||
|
for (let i = 0; i < 2000; i++) {
|
||||||
|
value = mod((value * 64) ^ value, 16777216);
|
||||||
|
value = mod(Math.floor(value / 32) ^ value, 16777216);
|
||||||
|
value = mod((value * 2048) ^ value, 16777216);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
return sumArray(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sequence = [number, number, number, number];
|
||||||
|
|
||||||
|
function findPriceBySequence(
|
||||||
|
prices: [number, number][],
|
||||||
|
sequence: Sequence
|
||||||
|
): number {
|
||||||
|
return (
|
||||||
|
prices.find(
|
||||||
|
(p, i, a) => i >= 4 && sequence.every((s, si) => s === a[i - (3 - si)][1])
|
||||||
|
)?.[0] || 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSequences(prices: [number, number][]): string[] {
|
||||||
|
const sequences = new Array<string>(prices.length - 4);
|
||||||
|
for (let i = 4; i < prices.length; i++) {
|
||||||
|
sequences[i - 4] = [
|
||||||
|
prices[i - 3][1],
|
||||||
|
prices[i - 2][1],
|
||||||
|
prices[i - 1][1],
|
||||||
|
prices[i][1]
|
||||||
|
].join(',');
|
||||||
|
}
|
||||||
|
return sequences;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solveSecond(input: string): number {
|
||||||
|
const start = input.split('\n').map(Number);
|
||||||
|
|
||||||
|
const prices = start.map((v) => {
|
||||||
|
let value = v;
|
||||||
|
const sec = new Array<[number, number]>(2000);
|
||||||
|
sec[0] = [mod(value, 10), 0];
|
||||||
|
let lastPrice = sec[0][0];
|
||||||
|
for (let i = 0; i < 2000; i++) {
|
||||||
|
value = mod((value * 64) ^ value, 16777216);
|
||||||
|
value = mod(Math.floor(value / 32) ^ value, 16777216);
|
||||||
|
value = mod((value * 2048) ^ value, 16777216);
|
||||||
|
const price = mod(value, 10);
|
||||||
|
sec[i + 1] = [price, price - lastPrice];
|
||||||
|
lastPrice = price;
|
||||||
|
}
|
||||||
|
return sec;
|
||||||
|
});
|
||||||
|
|
||||||
|
const sequences = prices.flatMap((p) => getSequences(p));
|
||||||
|
const uniqueSequences = new Set(sequences);
|
||||||
|
const bar =
|
||||||
|
process.env.NODE_ENV === 'test'
|
||||||
|
? null
|
||||||
|
: new SingleBar({}, Presets.shades_classic);
|
||||||
|
bar?.start(uniqueSequences.size, 0);
|
||||||
|
let highestPrice = 0;
|
||||||
|
|
||||||
|
for (let sequence of uniqueSequences) {
|
||||||
|
const numSequence = sequence.split(',').map(Number) as Sequence;
|
||||||
|
const finalPrices = sumArray(
|
||||||
|
prices.map((p) => findPriceBySequence(p, numSequence))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (finalPrices > highestPrice) {
|
||||||
|
highestPrice = finalPrices;
|
||||||
|
}
|
||||||
|
bar?.increment();
|
||||||
|
}
|
||||||
|
bar?.stop();
|
||||||
|
|
||||||
|
return highestPrice;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { solveFirst, solveSecond } from './index.ts';
|
||||||
|
|
||||||
|
const input = await Bun.file(join(__dirname, 'input.txt')).text();
|
||||||
|
|
||||||
|
const firstAnswer = solveFirst(input);
|
||||||
|
|
||||||
|
console.log(firstAnswer);
|
||||||
|
|
||||||
|
const secondAnswer = solveSecond(input);
|
||||||
|
|
||||||
|
console.log(secondAnswer);
|
||||||
Reference in New Issue
Block a user