solve_day20 :: (test: bool) {
contents := read_entire_file(ifx test then "inputs/day20_test.txt" else "inputs/day20.txt");
lines := split(contents, cast(u8) #char "\n");
numbers: [..]Num;
part1 := 0;
part2 := 0;
array_reserve(*numbers, lines.count);
magic_val :: 811589153;
for line, line_index: lines {
array_add(*numbers, .{
value = string_to_int(line, 10, s64),
next = null,
prev = null,
});
}
for *numbers {
it.next = *numbers[(it_index + 1) % numbers.count];
it.prev = *numbers[(numbers.count + it_index - 1) % numbers.count];
}
part1 = run_numbers(numbers, 1);
print("Part 1: %\n", part1);
for *numbers {
it.value *= magic_val;
it.next = *numbers[(it_index + 1) % numbers.count];
it.prev = *numbers[(numbers.count + it_index - 1) % numbers.count];
}
part2 = run_numbers(numbers, 10);
print("Part 2: %\n", part2);
}
run_numbers :: (numbers: [..]Num, rounds: s64) -> s64 {
result := 0;
zero := *numbers[0];
while true {
if zero.value == 0 break;
zero = zero.next;
}
for 1..rounds {
for *number: numbers {
n := << number;
current := number;
if number.value > 0 {
n.prev.next = n.next;
n.next.prev = n.prev;
for 1..(number.value % (numbers.count - 1)) {
current = current.next;
}
p1 := << current;
p2 := << number;
p3 := << current.next;
p1.next.prev = number;
p3.prev.next = number;
number.prev = p3.prev;
number.next = p1.next;
} else {
n.prev.next = n.next;
n.next.prev = n.prev;
for 1..((-number.value) % (numbers.count - 1)) {
current = current.prev;
}
p1 := << current.prev;
p2 := << number;
p3 := << current;
p1.next.prev = number;
p3.prev.next = number;
number.prev = p3.prev;
number.next = p1.next;
}
}
}
for 1..3000 {
zero = zero.next;
if it == 1000 || it == 2000 || it == 3000 result += zero.value;
}
return result;
}
reset_list :: (list: [..]Num) {
}
Num :: struct {
value: s64;
next: *Num;
prev: *Num;
}