1from __future__ import annotations
2
3import math
4import dataclasses
5import typing
6
7@dataclasses.dataclass
8class Node:
9 value: int
10 nxt: Node | None = None
11
12
13def get_data(path: str) -> typing.Iterator[int]:
14 with open(path) as f:
15 yield from (int(x) for x in f.read().strip().split())
16
17def blink(node):
18 while node:
19 match node.value:
20 case 0:
21 node.value = 1
22 case it if int(math.log(it, 10)) % 2 == 1:
23 digits = int(math.log(it, 10)) + 1
24 leading_digits = int(str(it)[:digits // 2])
25 trailing_digits = int(str(it)[digits // 2:])
26
27 new_node = Node(trailing_digits, node.nxt)
28 node.nxt = new_node
29 node.value = leading_digits
30 node = new_node
31 case _:
32 node.value *= 2024
33 node = node.nxt
34
35def main(data: typing.Iterator[int]) -> int:
36 front_node = Node(next(data))
37 last_node = front_node
38 for datum in data:
39 last_node.nxt = Node(datum)
40 last_node = last_node.nxt
41
42 for _ in range(25):
43 blink(front_node)
44
45 node_count = 0
46 node = front_node
47 while node:
48 node_count += 1
49 node = node.nxt
50
51 return node_count
52
53
54if __name__ == "__main__":
55 print(main(get_data("day_11_input.txt")))
1from __future__ import annotations
2
3import math
4import collections
5import typing
6
7def get_data(path: str) -> typing.Iterator[int]:
8 with open(path) as f:
9 yield from (int(x) for x in f.read().strip().split())
10
11def blink(counter: dict[int, int]) -> dict[int, int]:
12 next_counter = collections.defaultdict(int)
13 for k, count in counter.items():
14 match k:
15 case 0:
16 next_counter[1] += count
17 case it if int(math.log(it, 10)) % 2 == 1:
18 digits = int(math.log(it, 10)) + 1
19 leading_digits = int(str(it)[:digits // 2])
20 trailing_digits = int(str(it)[digits // 2:])
21 next_counter[leading_digits] += count
22 next_counter[trailing_digits] += count
23 case _:
24 next_counter[k * 2024] += count
25
26 return next_counter
27
28def main(data: typing.Iterator[int]) -> int:
29 counter = collections.defaultdict(int)
30
31 for datum in data:
32 counter[datum] += 1
33
34 for _ in range(75):
35 counter = blink(counter)
36
37 return sum(counter.values())
38
39
40if __name__ == "__main__":
41 print(main(get_data("day_11_input.txt")))