Skip to content

Commit 9f6dac0

Browse files
committedDec 22, 2024
✨ Add 2024 day 22 solutions
1 parent 8a26cee commit 9f6dac0

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed
 

‎2024/22/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Pretty fun! I went through an enjoyable process of optimizing my part 2 approach by leaps and bounds.

‎2024/22/index.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { expect, test } from 'bun:test'
2+
import { getPart1Answer, getPart2Answer, part1Examples, part2Examples } from '.'
3+
import { logAnswer } from '@scripts/log'
4+
5+
const inputText = await Bun.file(`${import.meta.dir}/input.txt`).text()
6+
7+
test('solutions', () => {
8+
console.log(' 🌟 Part 1 answer:', getAndLogAnswer(1))
9+
part1Examples.forEach(([i, a]) => expect(`${getPart1Answer(i, true)}`).toBe(`${a}`))
10+
console.log('🌟🌟 Part 2 answer:', getAndLogAnswer(2))
11+
part2Examples.forEach(([i, a]) => expect(`${getPart2Answer(i, true)}`).toBe(`${a}`))
12+
expect(1).toBe(1) // Ensures that console logs always run
13+
})
14+
15+
function getAndLogAnswer(part: 1 | 2) {
16+
console.time(`P${part}`)
17+
const answer = `${(part === 1 ? getPart1Answer : getPart2Answer)(inputText)}`
18+
console.timeEnd(`P${part}`)
19+
logAnswer(import.meta.dir, part, answer)
20+
return answer
21+
}

‎2024/22/index.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const parseInput = (input: string) =>
2+
input
3+
.trim()
4+
.split('\n')
5+
.map((v) => +v)
6+
7+
const mix = (input: number, secret: number): number => (input ^ secret) >>> 0
8+
const prune = (secret: number): number => secret % 16777216
9+
10+
const getNextSecret = (input: number): number => {
11+
const stepOne = prune(mix(input * 64, input))
12+
const stepTwo = prune(mix(stepOne / 32, stepOne))
13+
const stepThree = prune(mix(stepTwo * 2048, stepTwo))
14+
return stepThree
15+
}
16+
17+
export const getPart1Answer: Answer = (input, example = false) => {
18+
const parsed = parseInput(input)
19+
let sum = 0
20+
for (const secret of parsed) {
21+
let result = secret
22+
for (let i = 0; i < 2000; i++) {
23+
result = getNextSecret(result)
24+
}
25+
sum += result
26+
}
27+
return sum
28+
}
29+
30+
export const part1Examples: Example[] = [
31+
[
32+
`1
33+
10
34+
100
35+
2024`,
36+
'37327623',
37+
],
38+
]
39+
40+
export const getPart2Answer: Answer = (input, example = false) => {
41+
const parsed = parseInput(input)
42+
const summedSequencePriceMap: Map<string, number> = new Map()
43+
let bestSum = 0
44+
for (const secret of parsed) {
45+
const diffList: number[] = []
46+
const thisListSequences: Set<string> = new Set()
47+
let result = secret
48+
for (let i = 0; i < 2000; i++) {
49+
const nextSecret = getNextSecret(result)
50+
const price = nextSecret % 10
51+
const diff = price - (result % 10)
52+
if (price > 0 && i >= 3) {
53+
const sequenceKey = `${diffList.at(-3)!},${diffList.at(-2)!},${diffList.at(-1)!},${diff}`
54+
if (!thisListSequences.has(sequenceKey)) {
55+
thisListSequences.add(sequenceKey)
56+
const existingSum = summedSequencePriceMap.get(sequenceKey) || 0
57+
const newSum = existingSum + price
58+
if (newSum > bestSum) bestSum = newSum
59+
summedSequencePriceMap.set(sequenceKey, newSum)
60+
}
61+
}
62+
diffList.push(diff)
63+
result = nextSecret
64+
}
65+
}
66+
return bestSum
67+
}
68+
69+
export const part2Examples: Example[] = [
70+
[
71+
`1
72+
2
73+
3
74+
2024`,
75+
'23',
76+
],
77+
]

‎README.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ The test runner will then begin, in watch mode. Copy your puzzle input into `inp
1212

1313
Answers will be logged to `answers.log` in the day folder, for your own reference. Duplicate answers will be ignored.
1414

15+
## TODO
16+
17+
Allow appending a,b,c to day
18+
1519
_Repo structure inspired by [itswil's template](https://github.com/itswil/advent-of-code/)_

0 commit comments

Comments
 (0)
Please sign in to comment.