Skip to content

Commit

Permalink
Advent of code 2024: day 22 (#543)
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli authored Jan 4, 2025
1 parent ea9892e commit 7df5770
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 0 deletions.
46 changes: 46 additions & 0 deletions examples/aoc2024/day22/part1.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import "stdlib/io.jou"
import "stdlib/str.jou"


def xor(a: long, b: long) -> long:
assert a >= 0
assert b >= 0

result = 0L
power_of_two = 1L

while a != 0 or b != 0:
if a % 2 != b % 2:
result += power_of_two
a /= 2
b /= 2
power_of_two *= 2

return result


def next_num(n: long) -> long:
n = xor(n, n * 64) % 16777216
n = xor(n, n / 32) % 16777216
n = xor(n, n * 2048) % 16777216
return n


def main() -> int:
f = fopen("sampleinput1.txt", "r")
assert f != NULL

result = 0L

line: byte[100]
while fgets(line, sizeof(line) as int, f) != NULL:
n = atoll(line)
k = 2000
while k --> 0:
n = next_num(n)
result += n

printf("%lld\n", result) # Output: 37327623

fclose(f)
return 0
103 changes: 103 additions & 0 deletions examples/aoc2024/day22/part2.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import "stdlib/io.jou"
import "stdlib/str.jou"
import "stdlib/mem.jou"


def xor(a: long, b: long) -> long:
assert a >= 0
assert b >= 0

result = 0L
power_of_two = 1L

while a != 0 or b != 0:
if a % 2 != b % 2:
result += power_of_two
a /= 2
b /= 2
power_of_two *= 2

return result


def next_num(n: long) -> long:
n = xor(n, n * 64) % 16777216
n = xor(n, n / 32) % 16777216
n = xor(n, n * 2048) % 16777216
return n


# Return value is always less than 20*20*20*20
def diffseq_to_int(diffseq: int[4]) -> int:
diffseq[0] += 10
diffseq[1] += 10
diffseq[2] += 10
diffseq[3] += 10
return ((diffseq[0] * 20 + diffseq[1]) * 20 + diffseq[2]) * 20 + diffseq[3]


class Buyer:
seed: long
diffseq_to_bananas: byte*

def init_from_seed(self) -> None:
last_digits: int[2000]
deltas: int[2000]

state = self->seed
for i = 0; i < 2000; i++:
old = (state % 10) as int
state = next_num(state)
new = (state % 10) as int

last_digits[i] = new
deltas[i] = new - old

self->diffseq_to_bananas = calloc(sizeof(self->diffseq_to_bananas[0]), 20*20*20*20)
assert self->diffseq_to_bananas != NULL

# Go backwards so that we overwrite with whatever appears first in array
for i = 1999; i >= 3; i--:
diffseq = [deltas[i-3], deltas[i-2], deltas[i-1], deltas[i]]
self->diffseq_to_bananas[diffseq_to_int(diffseq)] = last_digits[i] as byte


def main() -> int:
max_buyers = 3000
buyers: Buyer* = malloc(sizeof(buyers[0]) * 3000)
assert buyers != NULL
nbuyers = 0

f = fopen("sampleinput2.txt", "r")
assert f != NULL

line: byte[100]
while fgets(line, sizeof(line) as int, f) != NULL:
assert nbuyers < max_buyers
buyers[nbuyers++] = Buyer{seed = atoll(line)}

fclose(f)

for i = 0; i < nbuyers; i++:
buyers[i].init_from_seed()

best = -1

for a = -9; a <= 9; a++:
for b = -9; b <= 9; b++:
for c = -9; c <= 9; c++:
for d = -9; d <= 9; d++:
result = 0
for i = 0; i < nbuyers; i++:
result += buyers[i].diffseq_to_bananas[diffseq_to_int([a, b, c, d])]

if result > best:
best = result

printf("%d\n", best) # Output: 23

for i = 0; i < nbuyers; i++:
free(buyers[i].diffseq_to_bananas)
free(buyers)

return 0
4 changes: 4 additions & 0 deletions examples/aoc2024/day22/sampleinput1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1
10
100
2024
4 changes: 4 additions & 0 deletions examples/aoc2024/day22/sampleinput2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1
2
3
2024

0 comments on commit 7df5770

Please sign in to comment.