45 Commits

Author SHA1 Message Date
Mikaël Capelle
155e0e9521 Final a bit better. 2023-12-12 21:18:57 +01:00
Mikael CAPELLE
13b15aba76 Final. 2023-12-12 19:03:40 +01:00
Mikael CAPELLE
c7d2eb2171 WIP 2. 2023-12-12 18:54:08 +01:00
Mikael CAPELLE
edc50cb9c2 WIP. 2023-12-12 14:49:16 +01:00
Mikaël Capelle
7151499835 2022 day 12. 2023-12-12 07:46:34 +01:00
Mikaël Capelle
1a6ab1cc0e 2023 day 11. 2023-12-11 10:25:56 +01:00
Mikaël Capelle
f5aabbee8f 2021 day 8. 2023-12-10 20:23:22 +01:00
Mikaël Capelle
6c00341ab0 2023 day 10. 2023-12-10 10:09:12 +01:00
Mikaël Capelle
755e0bd4b3 2021 day 7. 2023-12-09 12:52:46 +01:00
Mikaël Capelle
a52d077a40 2021 day 6. 2023-12-09 12:36:10 +01:00
Mikaël Capelle
3fc0f94b1c 2021 day 1-5. 2023-12-09 11:01:28 +01:00
Mikaël Capelle
8a0412f926 Clean 2022. 2023-12-09 09:54:53 +01:00
Mikaël Capelle
855efeb0aa 2023 day 9. 2023-12-09 08:08:46 +01:00
Mikaël Capelle
f2a65e03e5 2023 day 8. 2023-12-08 08:44:03 +01:00
Mikaël Capelle
759f47bfab 2023 day 7. 2023-12-08 08:38:08 +01:00
Mikael CAPELLE
999207b007 Clean 2023. 2023-12-06 08:47:59 +01:00
Mikaël Capelle
d92e4744a4 2023 day 6. 2023-12-06 07:14:26 +01:00
Mikael CAPELLE
8dbf0f101c 2023 day 5. 2023-12-05 13:41:17 +01:00
Mikaël Capelle
b8d8df06d6 2023 day 5 part 1. 2023-12-05 07:22:56 +01:00
Mikaël Capelle
825ebea299 Prepare 2023 days. 2023-12-04 19:32:41 +01:00
Mikaël Capelle
869cd4477f 2023 day 4. 2023-12-04 19:30:44 +01:00
Mikaël Capelle
fd777627d6 2023 day 3. 2023-12-03 09:09:25 +01:00
Mikaël Capelle
98f605f30e 2023 day 2. 2023-12-02 09:47:52 +01:00
Mikaël Capelle
d51fed283c Fix 2023 day 1. 2023-12-01 20:27:42 +01:00
Mikael CAPELLE
e991cd8b04 2023: Day 1. 2023-12-01 10:41:13 +01:00
Mikael CAPELLE
10f67e6bfd Post-christmas cleaning. 2023-01-06 13:48:18 +01:00
Mikaël Capelle
f291b0aa3f Day 25. 2022-12-25 11:34:49 +01:00
Mikaël Capelle
0eb5b5a88f Faster day 24. 2022-12-24 23:00:14 +01:00
Mikaël Capelle
2ec0a3d5f9 Day 24. 2022-12-24 20:50:37 +01:00
Mikael CAPELLE
0327a3f36a Add day 23. 2022-12-23 13:25:22 +01:00
Mikaël Capelle
3732e70ef7 Ugly day 22. 2022-12-22 23:00:36 +01:00
Mikaël Capelle
b0cc6b4a46 Update day 22. 2022-12-22 18:46:59 +01:00
Mikael CAPELLE
8c24b9f9e2 Update day 22. 2022-12-22 17:22:56 +01:00
Mikael CAPELLE
dca6f6a08f Update day 22. 2022-12-22 17:00:09 +01:00
Mikael CAPELLE
8d7a20f575 Day 22 part 1. 2022-12-22 14:10:30 +01:00
Mikael CAPELLE
3934dfd152 Start day 22. 2022-12-22 08:20:09 +01:00
Mikael CAPELLE
b656e8929e Remove tqdm from day 19. 2022-12-21 17:39:43 +01:00
Mikael CAPELLE
c9c69f479b Day 21. 2022-12-21 09:44:05 +01:00
Mikaël Capelle
72ebcfff1f Clean day 20. 2022-12-20 23:39:26 +01:00
Mikaël Capelle
dd72bb3238 Add empty files for following days. 2022-12-20 21:51:38 +01:00
Mikael CAPELLE
c1dd74c57d Faster day 20. 2022-12-20 18:27:09 +01:00
Mikael CAPELLE
1bf2de62c7 Day 20, slow. 2022-12-20 13:39:36 +01:00
Mikael CAPELLE
df808bc98a Start day 20. 2022-12-20 12:35:01 +01:00
Mikaël Capelle
f46e190e98 Add all tests from previous days. 2022-12-19 22:32:15 +01:00
Mikaël Capelle
7f4a34b2d7 Day 19. 2022-12-19 22:09:20 +01:00
209 changed files with 19749 additions and 522 deletions

14
2021/day1.py Normal file
View File

@@ -0,0 +1,14 @@
import sys
lines = sys.stdin.read().splitlines()
values = [int(line) for line in lines]
# part 1
answer_1 = sum(v2 > v1 for v1, v2 in zip(values[:-1], values[1:]))
print(f"answer 1 is {answer_1}")
# part 2
runnings = [sum(values[i : i + 3]) for i in range(len(values) - 2)]
answer_2 = sum(v2 > v1 for v1, v2 in zip(runnings[:-1], runnings[1:]))
print(f"answer 2 is {answer_2}")

13
2021/day10.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day11.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day12.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day13.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day14.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day15.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day16.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day17.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day18.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day19.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

40
2021/day2.py Normal file
View File

@@ -0,0 +1,40 @@
import sys
from math import prod
from typing import Literal, cast
lines = sys.stdin.read().splitlines()
commands = [
(cast(Literal["forward", "up", "down"], (p := line.split())[0]), int(p[1]))
for line in lines
]
def depth_and_position(use_aim: bool):
aim, pos, depth = 0, 0, 0
for command, value in commands:
d_depth = 0
match command:
case "forward":
pos += value
depth += value * aim
case "up":
d_depth = -value
case "down":
d_depth = value
if use_aim:
aim += d_depth
else:
depth += value
return depth, pos
# part 1
answer_1 = prod(depth_and_position(False))
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = prod(depth_and_position(True))
print(f"answer 2 is {answer_2}")

13
2021/day20.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day21.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day22.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day23.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day24.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

13
2021/day25.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

39
2021/day3.py Normal file
View File

@@ -0,0 +1,39 @@
import sys
from collections import Counter
from typing import Literal
def generator_rating(
values: list[str], most_common: bool, default: Literal["0", "1"]
) -> str:
index = 0
most_common_idx = 0 if most_common else 1
while len(values) > 1:
cnt = Counter(value[index] for value in values)
bit = cnt.most_common(2)[most_common_idx][0]
if cnt["0"] == cnt["1"]:
bit = default
values = [value for value in values if value[index] == bit]
index += 1
return values[0]
lines = sys.stdin.read().splitlines()
# part 1
most_and_least_common = [
tuple(Counter(line[col] for line in lines).most_common(2)[m][0] for m in range(2))
for col in range(len(lines[0]))
]
gamma_rate = int("".join(most for most, _ in most_and_least_common), base=2)
epsilon_rate = int("".join(least for _, least in most_and_least_common), base=2)
print(f"answer 1 is {gamma_rate * epsilon_rate}")
# part 2
oxygen_generator_rating = int(generator_rating(lines, True, "1"), base=2)
co2_scrubber_rating = int(generator_rating(lines, False, "0"), base=2)
answer_2 = oxygen_generator_rating * co2_scrubber_rating
print(f"answer 2 is {answer_2}")

45
2021/day4.py Normal file
View File

@@ -0,0 +1,45 @@
import sys
import numpy as np
lines = sys.stdin.read().splitlines()
numbers = [int(c) for c in lines[0].split(",")]
boards = np.asarray(
[
[[int(c) for c in line.split()] for line in lines[start : start + 5]]
for start in range(2, len(lines), 6)
]
)
# (round, score) for each board (-1 when not found)
winning_rounds: list[tuple[int, int]] = [(-1, -1) for _ in range(len(boards))]
marked = np.zeros_like(boards, dtype=bool)
for round, number in enumerate(numbers):
# mark boards
marked[boards == number] = True
# check each board for winning
for index in range(len(boards)):
if winning_rounds[index][0] > 0:
continue
if np.any(np.all(marked[index], axis=0) | np.all(marked[index], axis=1)):
winning_rounds[index] = (
round,
number * int(np.sum(boards[index][~marked[index]])),
)
# all boards are winning - break
if np.all(marked.all(axis=1) | marked.all(axis=2)):
break
# part 1
(_, score) = min(winning_rounds, key=lambda w: w[0])
print(f"answer 1 is {score}")
# part 2
(_, score) = max(winning_rounds, key=lambda w: w[0])
print(f"answer 2 is {score}")

View File

@@ -1,7 +1,4 @@
# -*- encoding: utf-8 -*-
import sys
from collections import defaultdict
import numpy as np
@@ -34,7 +31,6 @@ counts_1 = np.zeros((y_max + 1, x_max + 1), dtype=int)
counts_2 = counts_1.copy()
for (x1, y1), (x2, y2) in sections:
x_rng = range(x1, x2 + 1, 1) if x2 >= x1 else range(x1, x2 - 1, -1)
y_rng = range(y1, y2 + 1, 1) if y2 >= y1 else range(y1, y2 - 1, -1)

21
2021/day6.py Normal file
View File

@@ -0,0 +1,21 @@
import sys
values = [int(c) for c in sys.stdin.read().strip().split(",")]
days = 256
lanterns = {day: 0 for day in range(days)}
for value in values:
for day in range(value, days, 7):
lanterns[day] += 1
for day in range(days):
for day2 in range(day + 9, days, 7):
lanterns[day2] += lanterns[day]
# part 1
answer_1 = sum(v for k, v in lanterns.items() if k < 80) + len(values)
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = sum(lanterns.values()) + len(values)
print(f"answer 2 is {answer_2}")

21
2021/day7.py Normal file
View File

@@ -0,0 +1,21 @@
import sys
import numpy as np
positions = np.asarray([int(c) for c in sys.stdin.read().strip().split(",")])
min_position, max_position = positions.min(), positions.max()
# part 1
answer_1 = min(
np.sum(np.abs(positions - position))
for position in range(min_position, max_position + 1)
)
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = min(
np.sum(abs(positions - position) * (abs(positions - position) + 1) // 2)
for position in range(min_position, max_position + 1)
)
print(f"answer 2 is {answer_2}")

87
2021/day8.py Normal file
View File

@@ -0,0 +1,87 @@
import itertools
import os
import sys
VERBOSE = os.getenv("AOC_VERBOSE") == "True"
digits = {
"abcefg": 0,
"cf": 1,
"acdeg": 2,
"acdfg": 3,
"bcdf": 4,
"abdfg": 5,
"abdefg": 6,
"acf": 7,
"abcdefg": 8,
"abcdfg": 9,
}
lines = sys.stdin.read().splitlines()
# part 1
lengths = {len(k) for k, v in digits.items() if v in (1, 4, 7, 8)}
answer_1 = sum(
len(p) in lengths for line in lines for p in line.split("|")[1].strip().split()
)
print(f"answer 1 is {answer_1}")
# part 2
values: list[int] = []
for line in lines:
parts = line.split("|")
broken_digits = sorted(parts[0].strip().split(), key=len)
per_length = {
k: list(v)
for k, v in itertools.groupby(sorted(broken_digits, key=len), key=len)
}
# a can be found immediately
a = next(u for u in per_length[3][0] if u not in per_length[2][0])
# c and f have only two possible values corresponding to the single entry of
# length 2
cf = list(per_length[2][0])
# the only digit of length 4 contains bcdf, so we can deduce bd by removing cf
bd = [u for u in per_length[4][0] if u not in cf]
# the 3 digits of length 5 have a, d and g in common
adg = [u for u in per_length[5][0] if all(u in pe for pe in per_length[5][1:])]
# we can remove a
dg = [u for u in adg if u != a]
# we can deduce d and g
d = next(u for u in dg if u in bd)
g = next(u for u in dg if u != d)
# then b
b = next(u for u in bd if u != d)
# f is in the three 6-length digits, while c is only in 2
f = next(u for u in cf if all(u in p for p in per_length[6]))
# c is not f
c = next(u for u in cf if u != f)
# e is the last one
e = next(u for u in "abcdefg" if u not in {a, b, c, d, f, g})
mapping = dict(zip((a, b, c, d, e, f, g), "abcdefg"))
value = 0
for number in parts[1].strip().split():
digit = "".join(sorted(mapping[c] for c in number))
value = 10 * value + digits[digit]
if VERBOSE:
print(value)
values.append(value)
answer_2 = sum(values)
print(f"answer 2 is {answer_2}")

13
2021/day9.py Normal file
View File

@@ -0,0 +1,13 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()
# part 1
answer_1 = ...
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = ...
print(f"answer 2 is {answer_2}")

2000
2021/inputs/day1.txt Normal file

File diff suppressed because it is too large Load Diff

0
2021/inputs/day10.txt Normal file
View File

0
2021/inputs/day11.txt Normal file
View File

0
2021/inputs/day12.txt Normal file
View File

0
2021/inputs/day13.txt Normal file
View File

0
2021/inputs/day14.txt Normal file
View File

0
2021/inputs/day15.txt Normal file
View File

0
2021/inputs/day16.txt Normal file
View File

0
2021/inputs/day17.txt Normal file
View File

0
2021/inputs/day18.txt Normal file
View File

0
2021/inputs/day19.txt Normal file
View File

1000
2021/inputs/day2.txt Normal file

File diff suppressed because it is too large Load Diff

0
2021/inputs/day20.txt Normal file
View File

0
2021/inputs/day21.txt Normal file
View File

0
2021/inputs/day22.txt Normal file
View File

0
2021/inputs/day23.txt Normal file
View File

0
2021/inputs/day24.txt Normal file
View File

0
2021/inputs/day25.txt Normal file
View File

1000
2021/inputs/day3.txt Normal file

File diff suppressed because it is too large Load Diff

601
2021/inputs/day4.txt Normal file
View File

@@ -0,0 +1,601 @@
46,12,57,37,14,78,31,71,87,52,64,97,10,35,54,36,27,84,80,94,99,22,0,11,30,44,86,59,66,7,90,21,51,53,92,8,76,41,39,77,42,88,29,24,60,17,68,13,79,67,50,82,25,61,20,16,6,3,81,19,85,9,28,56,75,96,2,26,1,62,33,63,32,73,18,48,43,65,98,5,91,69,47,4,38,23,49,34,55,83,93,45,72,95,40,15,58,74,70,89
37 72 60 35 89
32 49 4 77 82
30 26 27 63 88
29 43 16 34 58
48 33 96 79 94
41 94 77 43 87
2 17 82 96 25
95 49 32 12 9
59 33 67 71 64
88 54 93 85 30
78 84 73 64 81
6 66 54 21 15
72 88 69 5 93
11 96 38 95 44
13 41 94 55 48
5 14 2 82 33
56 26 0 84 92
8 95 24 54 25
68 67 15 85 47
20 91 36 13 88
39 26 33 65 32
78 72 80 51 0
35 64 60 18 31
93 59 83 54 74
86 5 9 98 69
0 8 20 18 70
5 29 65 21 57
68 61 83 63 51
91 73 77 75 80
35 62 16 32 10
51 78 58 67 93
50 14 99 5 31
6 21 48 30 83
22 33 23 1 34
2 72 57 54 42
15 68 4 24 49
12 9 74 88 51
91 19 50 76 75
80 84 23 17 53
67 42 22 85 36
41 78 11 69 9
90 25 98 65 77
97 53 37 84 89
58 63 5 55 1
24 10 74 20 82
42 19 95 89 49
61 31 50 76 3
34 47 32 69 86
78 68 99 11 91
55 12 73 45 23
24 53 95 64 14
40 29 71 57 97
62 70 25 22 2
88 68 33 82 59
72 38 76 78 43
73 36 84 90 40
16 4 57 9 29
38 97 46 51 83
86 88 99 44 32
54 49 37 43 62
18 66 17 49 27
24 93 91 87 72
54 37 77 43 10
88 80 60 15 79
47 68 12 2 69
9 23 13 57 68
38 97 63 88 98
96 62 65 82 58
61 83 29 47 40
21 86 20 16 56
27 90 37 97 52
14 96 76 21 79
0 43 63 81 56
42 62 23 55 74
45 72 77 44 47
8 78 63 24 87
9 23 12 17 68
36 83 45 61 50
84 77 18 86 37
31 26 19 49 94
72 84 59 48 40
92 98 35 1 80
83 15 85 63 39
2 64 58 13 20
29 88 60 12 74
21 94 52 6 4
89 70 39 23 64
96 87 31 54 14
88 35 83 13 56
84 10 98 48 68
70 33 48 21 37
91 95 65 38 77
92 14 26 96 60
12 6 73 13 81
54 55 2 45 80
60 11 67 95 28
5 32 0 71 12
47 78 13 54 43
49 89 82 66 77
26 53 19 79 3
81 9 53 72 29
56 35 60 44 45
42 94 96 88 64
15 92 4 6 14
97 11 17 61 63
24 43 33 9 34
36 28 69 35 7
47 4 14 82 38
11 1 52 0 49
93 87 98 41 5
37 79 99 34 77
38 26 25 95 70
28 78 40 33 86
41 57 96 10 24
9 74 72 50 81
18 96 52 29 61
38 90 1 48 51
78 11 27 55 97
33 21 87 93 67
79 46 94 45 2
27 63 6 90 10
3 60 24 5 89
78 72 76 54 8
33 22 87 51 58
4 37 64 91 43
63 73 87 80 89
29 14 95 48 3
71 55 69 9 67
30 99 19 2 86
26 72 88 85 37
12 57 81 78 40
35 4 55 15 39
33 45 25 60 70
86 79 88 52 3
90 20 28 59 85
92 51 98 47 99
41 78 65 4 46
19 87 39 89 17
12 23 36 29 44
6 82 71 16 37
8 34 81 67 80
83 92 13 11 41
39 89 93 49 43
20 69 3 74 76
44 72 68 70 45
66 39 94 98 28
72 4 25 77 76
56 41 84 59 40
36 87 18 44 73
29 45 79 55 95
45 91 2 92 16
21 47 86 81 56
31 11 62 5 95
39 1 30 65 33
42 60 17 18 83
86 11 77 30 43
51 88 73 98 94
72 63 38 56 10
57 92 49 7 41
79 75 34 23 54
56 95 3 43 65
39 62 93 19 27
61 41 99 96 52
4 92 77 98 70
16 54 11 17 57
6 63 10 71 58
64 70 50 92 0
7 14 99 45 26
78 17 44 46 73
77 38 62 53 37
31 82 67 55 27
57 58 84 6 15
14 41 49 8 85
12 32 91 42 19
23 1 87 54 29
54 60 43 26 4
78 17 28 67 5
87 93 90 71 22
13 30 16 21 85
55 74 52 1 29
50 16 70 32 33
6 94 52 66 22
97 64 98 72 39
27 69 99 34 26
36 91 37 21 14
7 97 64 28 18
85 80 14 37 34
72 1 22 58 73
53 3 68 17 0
29 44 56 95 32
30 66 93 24 92
48 80 79 86 27
89 13 62 94 81
70 65 61 8 54
96 97 20 90 34
87 76 4 7 43
92 55 80 25 62
79 6 88 35 30
10 32 5 45 17
36 27 33 68 63
72 69 27 88 41
34 53 42 84 3
58 18 22 66 65
9 47 85 12 62
73 90 91 57 33
67 16 50 58 52
68 70 84 98 69
4 72 9 64 0
93 97 39 26 5
3 37 79 7 82
61 57 88 54 70
77 8 94 81 63
39 48 18 13 10
55 23 27 4 73
3 5 64 0 96
62 27 0 52 19
28 57 83 25 41
5 59 24 33 80
37 85 2 86 43
22 94 50 8 20
54 32 34 47 87
71 22 43 85 24
11 68 58 36 46
35 56 61 67 18
70 23 72 5 59
3 96 41 45 32
68 2 56 28 24
87 38 40 75 26
53 64 73 80 81
54 88 20 6 18
64 55 51 96 47
59 35 49 67 71
36 91 61 76 68
6 94 20 8 27
60 88 45 7 82
87 94 51 91 1
96 60 28 97 37
26 27 74 53 35
88 89 11 77 8
73 47 18 59 6
46 50 19 36 83
69 28 4 44 70
45 20 63 27 1
53 38 9 47 67
91 31 79 73 86
45 3 98 91 60
40 7 78 34 83
52 73 59 13 4
38 15 82 86 79
42 11 17 20 62
65 86 38 20 72
78 45 73 74 25
62 42 24 75 3
81 8 35 50 51
44 11 94 85 57
13 86 55 65 96
53 18 43 76 20
41 14 32 52 38
90 59 80 68 7
2 23 92 39 50
96 62 85 24 14
37 5 11 91 45
61 28 23 34 77
43 48 20 0 21
10 35 2 26 97
89 5 40 34 84
90 6 72 68 10
13 64 71 31 76
53 60 9 92 62
69 98 8 50 3
17 86 10 75 79
67 94 78 40 56
11 85 82 50 46
53 39 22 9 61
59 73 72 33 45
65 22 18 96 95
55 86 67 52 69
10 2 60 83 98
43 61 87 88 66
41 24 8 84 33
31 53 98 70 91
33 34 48 83 9
40 39 29 71 65
69 10 62 30 4
52 21 11 93 75
8 94 53 85 89
13 84 58 59 29
97 7 21 25 96
45 54 34 22 63
37 17 49 68 67
86 87 84 24 10
82 32 36 59 50
8 62 79 71 43
49 23 85 69 58
21 66 42 25 56
65 88 43 25 19
26 36 63 5 6
37 54 75 1 38
95 46 83 66 28
4 90 80 99 85
78 83 7 77 34
27 92 93 96 82
40 95 52 32 43
17 28 69 41 85
21 65 39 58 19
11 84 28 90 36
74 4 62 5 46
22 8 45 40 98
12 6 30 9 82
37 2 53 29 41
17 65 31 86 57
73 16 24 67 53
60 93 88 45 26
14 80 94 7 44
55 78 49 8 82
95 38 81 25 76
29 13 83 47 12
17 69 4 43 28
63 84 39 52 34
1 97 41 88 8
70 40 16 83 3
15 49 20 74 48
71 30 21 28 84
29 10 97 1 18
57 50 63 35 69
40 13 67 9 41
71 76 8 54 24
15 97 92 49 96
61 34 23 81 31
11 38 48 37 86
77 36 32 75 7
38 18 84 26 2
19 13 99 83 20
35 51 74 6 27
71 48 15 66 69
91 57 41 3 99
74 55 81 77 43
36 52 47 49 45
85 65 5 38 50
90 68 70 16 0
1 90 28 86 27
73 36 67 11 14
71 31 10 65 55
78 21 16 69 12
87 24 33 83 68
90 17 10 84 45
5 68 69 27 92
6 63 98 3 46
94 48 59 34 43
39 88 12 33 73
12 31 33 98 63
65 51 94 83 92
41 38 84 91 66
47 28 76 54 3
48 36 11 13 27
51 84 96 16 8
64 26 74 30 48
29 41 68 97 87
9 38 1 15 39
98 3 45 53 14
53 70 90 95 86
35 22 85 45 66
93 0 83 30 88
64 57 68 36 3
5 51 19 20 89
9 36 69 46 44
37 7 99 57 45
79 10 86 58 30
49 98 52 90 27
14 51 88 60 81
73 97 91 19 48
76 43 18 83 67
62 9 11 82 55
24 17 33 53 22
75 8 56 1 21
27 97 53 0 89
30 70 3 80 54
56 93 40 64 35
46 82 1 44 65
6 59 45 32 34
87 58 73 45 69
24 49 89 71 83
94 6 53 68 50
28 25 88 47 0
36 13 31 18 55
52 63 37 66 9
34 77 57 6 55
85 80 97 78 74
95 75 67 96 29
22 73 92 69 47
79 97 80 36 73
38 77 35 32 53
2 37 29 6 89
78 91 15 47 34
11 52 64 84 0
69 30 21 99 46
72 4 15 25 42
67 98 81 91 63
70 20 57 65 14
0 78 19 8 87
20 4 98 33 85
76 17 94 65 35
95 69 72 52 71
23 25 50 38 27
43 49 96 53 99
16 27 34 65 36
10 40 84 60 82
80 2 54 67 70
52 94 79 17 56
5 14 77 91 88
32 90 50 66 39
30 16 14 20 10
4 42 88 59 12
75 84 54 51 48
33 24 13 89 43
78 42 34 65 51
75 72 3 99 61
15 50 59 8 89
71 18 9 54 53
43 39 97 56 19
50 43 83 4 30
89 97 58 35 39
11 24 61 41 25
87 99 93 15 34
31 57 3 45 44
70 21 63 24 38
34 23 88 7 51
43 18 76 46 49
60 78 47 8 12
11 66 98 25 74
30 17 23 10 92
12 85 69 81 91
47 80 28 29 58
73 44 77 50 32
76 54 78 75 60
71 53 86 48 98
90 37 79 8 56
99 42 97 36 15
31 85 34 10 40
43 89 57 72 51
48 0 65 55 90
45 76 69 97 4
42 52 46 77 56
64 62 68 35 72
71 10 27 30 16
41 69 63 88 57
25 56 23 78 80
8 92 59 66 97
48 61 77 15 14
87 47 91 12 71
51 46 15 2 49
48 33 23 16 4
80 41 43 59 83
62 13 20 63 85
99 30 7 87 8
69 80 96 43 47
61 75 45 62 15
32 22 91 83 58
82 13 50 52 8
89 20 63 73 14
40 2 96 52 73
25 27 26 43 34
60 38 80 78 5
83 63 48 10 66
97 46 53 74 86
46 7 0 69 15
79 19 85 27 73
63 45 5 49 54
93 29 84 28 66
72 23 99 8 33
20 72 85 99 49
69 0 10 52 23
88 56 28 67 21
16 91 83 54 81
14 73 32 30 59
31 52 63 12 3
96 20 82 6 89
55 38 8 95 40
5 60 84 81 75
51 14 65 27 61
46 93 1 47 76
8 98 7 16 63
44 78 17 14 92
42 62 20 12 68
56 3 74 6 21
8 94 11 40 44
43 92 78 91 18
75 80 12 54 26
67 9 45 22 21
86 1 90 36 30
21 19 83 90 8
50 28 45 65 75
59 88 25 29 70
58 23 0 95 49
36 68 76 78 66
77 28 43 56 97
73 71 8 72 46
23 25 70 69 41
90 17 34 67 48
32 75 81 63 21

1
2021/inputs/day6.txt Normal file
View File

@@ -0,0 +1 @@
2,3,1,3,4,4,1,5,2,3,1,1,4,5,5,3,5,5,4,1,2,1,1,1,1,1,1,4,1,1,1,4,1,3,1,4,1,1,4,1,3,4,5,1,1,5,3,4,3,4,1,5,1,3,1,1,1,3,5,3,2,3,1,5,2,2,1,1,4,1,1,2,2,2,2,3,2,1,2,5,4,1,1,1,5,5,3,1,3,2,2,2,5,1,5,2,4,1,1,3,3,5,2,3,1,2,1,5,1,4,3,5,2,1,5,3,4,4,5,3,1,2,4,3,4,1,3,1,1,2,5,4,3,5,3,2,1,4,1,4,4,2,3,1,1,2,1,1,3,3,3,1,1,2,2,1,1,1,5,1,5,1,4,5,1,5,2,4,3,1,1,3,2,2,1,4,3,1,1,1,3,3,3,4,5,2,3,3,1,3,1,4,1,1,1,2,5,1,4,1,2,4,5,4,1,5,1,5,5,1,5,5,2,5,5,1,4,5,1,1,3,2,5,5,5,4,3,2,5,4,1,1,2,4,4,1,1,1,3,2,1,1,2,1,2,2,3,4,5,4,1,4,5,1,1,5,5,1,4,1,4,4,1,5,3,1,4,3,5,3,1,3,1,4,2,4,5,1,4,1,2,4,1,2,5,1,1,5,1,1,3,1,1,2,3,4,2,4,3,1

1
2021/inputs/day7.txt Normal file
View File

@@ -0,0 +1 @@
1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,209,573,1277,704,518,276,196,62,1226,170,58,1450,101,65,99,435,986,1437,1570,35,354,247,110,105,139,1209,23,1074,339,69,483,21,33,323,1348,111,2,270,1239,316,529,1680,1056,1960,257,1009,1073,59,425,1181,198,31,299,771,53,817,728,931,72,517,39,279,304,401,1271,533,1551,133,297,162,902,370,985,643,1217,78,16,380,223,177,600,349,12,776,26,1738,526,85,1542,111,844,93,595,1545,873,836,422,180,1187,329,231,1521,54,162,212,471,1329,156,1299,160,541,676,67,200,22,24,76,242,178,1093,1173,818,1380,284,335,642,1047,112,271,541,927,52,983,238,116,135,871,400,436,1094,684,249,263,303,24,437,813,32,45,19,620,57,866,44,68,277,1112,110,77,1481,437,302,678,541,904,322,13,186,1474,836,43,1020,201,1586,1169,1149,470,535,55,879,133,1229,106,989,1023,256,103,56,401,667,557,98,288,694,286,237,1661,933,1063,20,227,80,815,289,1414,234,517,227,616,829,191,1211,92,591,279,22,139,67,214,60,145,468,10,521,807,1243,76,163,190,122,804,88,383,319,1127,399,376,423,304,126,10,297,377,1103,691,139,70,519,16,15,43,397,468,1183,90,28,1262,151,1448,62,64,1072,386,1330,1313,12,100,657,28,55,612,337,1865,704,263,565,249,564,565,1218,40,1146,150,718,1253,228,120,713,925,159,36,1087,1023,1490,316,540,1124,1127,781,417,656,0,174,1006,529,389,86,90,78,403,1500,253,35,655,650,933,815,108,168,321,345,147,251,258,25,173,243,740,48,476,1507,634,425,738,160,1415,395,448,156,636,1967,516,316,628,810,817,26,20,753,22,1133,352,204,211,47,22,874,43,12,18,1015,779,108,579,251,1398,33,1507,93,274,904,221,1062,868,3,363,42,14,435,62,1508,540,64,267,1690,418,205,502,152,142,414,178,50,344,780,81,635,128,355,239,1708,1814,29,251,624,22,38,789,948,186,529,895,76,150,416,502,975,1216,456,862,522,1149,131,10,121,1353,313,568,595,6,318,633,331,1652,656,214,21,35,289,80,860,229,244,1188,350,594,424,235,327,6,1083,40,134,839,279,172,1452,197,47,2,73,607,238,1151,844,533,110,1207,125,129,16,1000,965,236,228,497,589,111,1245,453,179,956,116,212,47,497,380,574,355,799,209,384,47,449,688,312,748,1531,1092,23,1001,69,155,924,1352,163,1561,743,609,1261,1231,32,1,739,513,300,370,36,568,89,487,201,11,146,274,163,1029,829,469,299,118,732,769,120,1093,776,610,1944,90,67,494,831,88,227,1257,344,662,401,310,664,56,94,183,935,179,643,4,1083,567,1525,208,204,899,123,36,438,1171,265,1406,177,202,1398,631,444,385,589,29,124,96,237,374,793,794,502,665,287,575,113,305,157,465,376,66,662,77,595,75,141,243,254,30,5,622,140,443,566,360,192,1531,1113,1299,598,147,469,732,1565,409,1380,550,173,232,361,131,99,37,547,132,1779,193,228,664,553,568,389,1069,58,71,610,738,624,261,491,158,105,416,131,198,35,823,9,313,6,429,1492,290,313,272,281,427,280,661,141,54,383,3,130,43,418,2,1040,1051,1006,38,151,1325,1357,117,1473,175,201,613,1458,1218,588,169,228,565,901,420,42,117,110,442,9,99,1685,979,84,35,129,248,1,21,360,123,203,1320,1200,209,510,362,106,148,313,292,63,842,93,88,134,720,565,156,118,983,119,1451,757,736,445,466,226,265,573,612,652,170,225,32,1049,1332,366,1375,692,270,388,321,1153,909,1266,93,5,495,377,212,429,90,199,278,631,693,63,816,395,281,315,0,737,575,121,865,1,485,262,49,804,518,109,600,358,221,14,370,450,947,448,67,576,22,1266,226,100,10,607,620,295,568,316,51,687,199,1478,45,489,1878,1035,298,219,363,85,664,1290,492,70,644,78,163,100,102,465,732,439,93,25,847,297,172,361,393,304,461,583,122,121,762,58,112,85,142,48,193,1617,386,685,1054,584,488,394,665,277,263,596,290,1231,171,1394,9,1218,77,54,487,182,528,695,662,413,345,51,690,1702,203,1500,461,1755,190,371,1122,1614,324,238,569,1482,15,711,1332,700,437,242,174,642,660,987,1232,121,620,17,389,22,105,847,36,251,285,1238,162,1227,1473,411,66,258,377,1135,438,117,664,281,1070,301,132,256,498,172,194,103,662,606,342,340,1501,802,549,380,58,179,361

200
2021/inputs/day8.txt Normal file
View File

@@ -0,0 +1,200 @@
caebgd dagc eabgd aebfgc fbdacge edg dg dbgcef eabfd cgeba | gbcdae dagc acgd gd
fgcbed bcedga cafb acgfd cgabd cgf dfaeg dfbcga bceagdf fc | cf gdfea fdagbc dfacg
gaed egcbdf edagcf fcaegdb facge afg ga ecbaf fgced fgdabc | cgeaf gfa ga efbac
cbdeg cbgeadf cgdfa cgdbae decgf efg cebf egbfdc fgbead ef | fge gfe dcegabf gdcfe
bacd cgdbe ecgbf cd cde degba cfaegd gfadbe gbdace baegcdf | cfgdea dce bacd cabd
gdbafc cedagb cebga bc edcb gbdefa cebgdaf agfce acb bgdae | afgedb bdce dabeg dbec
fadce bad edafbc cgbfa edcagf dacbge dfabc bgecadf edbf bd | efbd baegdc dab db
fcaed eb afcdge cfbae gacbf edab becgdaf gcedbf efb bdecaf | be gadbfec eb cedfa
cdgbea ebcga feacb age ge afcdgb faegdc acbgd agcfdbe bdeg | gedcab dcagb gea edbg
eda bgeaf eabdcg ad ebgdacf egdfac ecdbfg dcfge acdf dagfe | ad ad da beagf
cegfa bf ecfabd fgcb egcafd ebfga bgade afb eagbfc dgfbeca | bcegaf fcgb adgbe bcgf
fegacb dbagc gdcae fbcd bc dfbgca gdbfa cgb adefbg ecdabgf | cgb fbgdac cabfdg acdeg
gfbead cfbgea cfeb bf agcfb baf cdgaf begacd aebcg acgdfbe | fab gdcbeaf afcbeg bfa
df acgbf bedag gecbdf dgefacb fdagb gfadeb fbd abgecd efad | bcafg cafdgeb bdf fd
defbc dg gadc caebdfg bceagf gecba adegbf ebagdc gecdb dbg | bfgdea aefbdcg dgb dbceg
cegbd cafegb gedcab gcebdf ecdf dfbag fbgde ef efg fbaecgd | fedc ef fdec ebagcf
dbfag gabdcf dfgbeac efdcag gbcfe ed efbadg efd bade efbgd | bagfd def ed efgbda
gafbcde gfbdc fc geafbc cgf ecdfgb cfde dbgac gdfeb gedabf | fced gfc cdbag gfc
ef adbefg efdbc cfabd fcea fbe cebdg cbfgda abecfd dagbefc | degcbaf ef fecdagb dafebc
acdbf abefgd ea dgcfe acedgf agec faedcgb afe gcbdfe fecad | geca gebadfc fgeabcd efdca
agfecd acbg aefdb bg gdcfa gdafb cebdagf gfb dgcafb cgbefd | fbg dgafc fbg bafdg
db ebafd dcafeg bcedag eafgb bcdf ecafd adb eabdfc cdbgaef | bgafe dfbea bd daefc
egfacd cegfa afbdg facgbe de dfegbc cdae edafg egd ecdfbga | edg defcga aegfc de
abdgfce begca egcbf ag gdafbc afge fbdcge daecb cefabg cag | gbfced ga cgedbfa ag
faed abcedf eafdbcg aebcf cbagf cgebda ef fbe cbgfde bdcae | afbcg dafe fbe fbe
bcea cfdae dcafeb ab cfbdg dgeabf afbcd baf fdacge gacfdbe | baf decgfab fab abce
dbeacg agefcd agbefdc cagfe ae aeg aedf gdafc bfceg bacdfg | gea begcf fdcage ea
cagdeb ca bcfgad badgef cbaf cgbefad adc fcdga gdfec bfagd | aecbdfg afcb ac bcfa
bc begda gebfcad bfcd dbeac abdfce dcafe cbe cafdge bgcfae | bcdf ebdga gbfecda bce
dfacgb edbcg gfedab egfab bac begac fcea ca dgfcabe ebacfg | bac cba bgcde ca
fgacbe dgeba agebf afb fbcaed eafcgd fb dfegacb bgfc cfgea | cfegabd ceafg bf cbadef
fgcab ceabdgf fdabc da gdabcf gdcaeb ecfbag fadg cdbef acd | fagd gfad fcbgae adgf
afbgecd cedga cdfb ebgdcf gbfade bcfeag cedgb efgbc bd gdb | fedbcg cefdbg edcag dgb
bfcga gfadb egcadf cbeagfd bdfeag bcfegd bd edgaf dbae dfb | bfgadec dfb bfd cbfga
cbegad bacde eafdb bcgea cad cfgadb cd gced fgedcab bfecag | fdgbeac eacbdfg acdbe abdfe
cebaf dcegbaf edfgab cabgfe bafeg cgaf aegbdc cea febdc ca | ac ac ca cfga
db bfd ecdfg febdc debfac egdfab cadb efgacb defacgb bcfae | edbcagf bd debfac fdb
egfdcab dcgbe dacgef fbad bafcge ab degfa ebfgad gbdea gab | ba fabgecd ab agedbf
afbc efadc efcgabd dfbeac ac bdgeac cfgbed afgde cfdbe dac | ac fegcdb afedc facb
acbde cgfdea cdbge cfbdea abd ab gacbdfe fdcgab acefd fabe | fbae dagefbc aefbcgd dba
cedbfga dabecf afbge fab ecbfdg gedfba fbgde cbeag dfag af | beafg acbfed fa gdaf
ecbgfa eab agdfebc adbg gdfbe dfgecb dabfe afced bagfde ab | bdag gdba dfbge gbda
egfdac eadbg gfdab bcdega ae egabdfc cdfbeg dae gcbed bace | dgbefc gadefc ea eacb
bgacf dgfcea cbfgeda fdab fa fag fbgadc gcbef cdabeg bcgda | gfa fag afg aedcbg
egafdcb dcega dgfbc egdbaf ebdcg dbe eb cabdeg ceab fcdaeg | bed edcfag gadefc fcdbg
dgcab afgb bcg dcaeb dbgcaf bg ecfdgba gafced fbcdeg cfdga | cefgdb gacfbed afdgc gbcdfa
cgeda bafcg cgdfa dgfcae bceagd bdgface adf fd feabcd efdg | edfg gdeca cgbdfae dcfgaeb
dbefga eadcgb gbaedcf daebc geadc bd bcgd bafec bad gaecfd | edagc abcef fceba aecdg
bcegf cfbega bgedca befca gabecdf bgc gfca gebdf cg dcfabe | efdbg bcg acgf fecbadg
gfcdeba dbaec ecgaf gde agedfb bcafeg gdfc dgeac dg cadefg | egfca fegac edg daebgf
bea geadbf be efcad afecgb adfcbg cbefa fcabg gecb egbdfca | eab cbfae gbcafed cbeadgf
adgfec bgea fbcdg be fdceba bgedc edb acged bfdceag dgbcea | decfba efcdba gbdface aedgfc
ebgfc dcb dc ecfd fecbgd debcg bgfacd defcgab bacgef dgabe | dc adfbceg befgc cfed
cbgdea gafc fcegd eagdfb bfdce egc efdag gdafec cg gfbceda | cg ceg dgfea cg
fgdab egacbfd decgaf eaf edcfgb ea efdcb aefcbd eadbf abec | fdbea ea acefdb ea
bdegcf aegfb eacd ec acfgd gfdeca fce adcfbg begafdc gcaef | acde gbefcd adce fec
cdgfbe fdacg cegdf cebd cbeafdg efgcb aegcbf bgfead efd de | fcegdba cbde gbcadfe fed
adfge efgbda gacfde gecfba ce feacd adbfc cgde fce dfabgce | fgcaed cgde gfaced fdeac
ga cgaefdb dcebfg fbegac gbda acdef cdgeb gbaedc ecadg cag | bagd bgfdce cbgde dbfaecg
gec efdabg bfgdcae dfebc agbc aefbg afgbce agecfd cg cegbf | acfdgbe cbdef abcg afbedcg
ebcgaf cagdf afbdeg fbcda dcfbeag beacfd befca bfd bd cebd | dfb dbf feacbg gfdaecb
ecgdfa afe gbafd bfgdac ae decbf dgebaf afbed abeg cedabfg | egab cgeabfd eadgbfc ebag
agcfdeb fdabe gfcaeb edf cegfad badce gdbf fd gbafe fedbga | efd bfgd daecgfb cabefg
bcdef gefcadb fdeba fdega ba bgea bgdafc efbagd dfcgae dba | ba ba edafb ebga
acgbe age ga agebfd afcebg bdegc acfeb fgca cefdba cabegdf | ag eag afgc ag
bacfd feb gfea dabge fegadbc adegbf fe aefdb cbdgae gdcbfe | ef ebdfcg fgdeba efb
efgca fadbc daecgf ecbfgd gd daeg dfcagbe agfdc bafecg dgf | fgd cfeagb afegc dfg
cgeabd cdagf dfab afcbgd dceafbg adgbc cfd df efdgcb afgec | cdf cfabdg abfd df
bgacef acegf adgce cgbfaed dgbec gcdefa afed ad badcgf cda | ad egadc degbfac efcagd
de ceafb bfedacg decf cbeda aed gdefab dfacbe gadcb gecbfa | acefb eda edcf ead
fdebga dgbcef baf af caefb debcf baecg cgdfaeb dafc facdbe | af fdac fgceadb efcba
dgbfac cabdefg ag gda dgcbf gafdb dfaeb bedgcf cafg adcebg | fgadb egfbcad fgca gfbda
egcbfda fagbde cb egbcf fbc dcgb cdbafe fgdbe dcefbg ceafg | bfc gfcebda bcf bcf
cfeba ag fecag feacgb eag defgc egabfd gbcafed agcb bdacef | gcfabe efcadgb ga gabc
fgeadb gbfdace feacb ed bacfde fdbcg edca ecbdf cebgfa def | ebcfa acebdgf efd aced
fcgad aegfdb ea bdfcea dea egfbd aebg cgbedaf begfdc fedag | geba egbfd fdagbe dcbaef
faebdg efbca fadce bgefa fcbgae dbecfag bgcf cb ecb dgaecb | cadebgf ecb gcfb cb
ecdf begca cbagfd ed edb dfebacg cdgfb bcedg cgbfed edagbf | de dfce gedcbf de
badfec dfgcab gdbeafc cbf defc acefb ebdgaf cf abedf egacb | cdfe cdef fedc fc
afcgbd fdcg fbc bgdac acbgef cf fcabd gdebca fbaed fcdageb | cf fbc cf gfcd
cefba dbef fe gdafec dbcae fdebac bfadcge fec gceabd abcfg | gacedb debac bcaed gacfdbe
bagfe db bdf gafdc bfgda cgefbd cafedg fcgabd fdeacbg dacb | gabdf cdgbfa bd egfbdc
dbcaef bacfd begfcd gbafc cedbf da eabd gecdfa cda fbecgda | aedb cda efcdb adcfbe
faebgd afcbdg gf dbacfeg gdf degfa dcfea gebda dgaceb gfbe | bgfe decaf gf edgfa
fg aecgbfd ebcfa efabg adgeb fge egcbdf bedagf dbcaeg fagd | fg dfga gfda gafd
cedgabf dcba ab cedaf bae cabefd fgaced fdaeb fabgec dfgeb | bedfac ab fecbga debfcag
dec ce fcabde daefb fgabde aefc bdagc dcgfeb efcdabg caedb | gadbfec ecfa baefgd ce
egcaf ed adbe afbcd dgfecba acbdgf edf decfab edcaf egbcfd | dgecfab eabdfcg fbdaec abed
fea febcg eacgf ecda cdgfa agcedfb edgfba ae agcfde cbadgf | fcegb fgbaced dcafg caed
gebfd ec dec eabc bafcged debgc fecgda fdgabc dcgabe cgadb | adegbcf gbacfed bfgcdea ce
egfdab cad bcgad cd bcfga gfdbcea dgcaeb cedg defbac beagd | cadbfe decg cd cadfeb
cge gadebfc fbcgae gc dagec agdeb dcefga cgdf afbecd ecfda | ebgcaf dbeag fgcdbae dgcf
bdegca ecbdaf bfae cgdfb ebafdgc ba dfabc bac feagcd fdcea | bac ebcfadg ba ab
gceda eab agbfedc eafcdg ab gbac bgdef gacbed dgbea cfaebd | bgfcade ba abgc bae
gbfe eg gcfdeb daebcg bcdef cgefd cdfag fbdeac egcadfb gec | ge befgdc gce egc
bga gbeacd cbgde gdefcab cagbdf ab beda cfbegd aecgf agecb | agfce daeb bead agb
fedgba agecbf bc bcdf cgb febdcg ecgfabd gcade dgbec efgdb | bgedfac cb bc bc
gfaeb bcdfe cea gfca bdacge aecbdfg fegbca ac dfgbae caefb | cfga agcf cfga cbgade
cgeab fbegda adb dagbfec eafgbc bd bgcd adecf cegdba daebc | efbcdag gdcb bd deacfgb
bcagd cbgde gbfad eabdgf cda ceabfd fcag cdgabf agcbdfe ca | ca ca ac cda
agdce dageb eacdbf ecgdaf bafgd dgfacbe dgbaec bceg bea be | gceb bgdcaef edgac aedgc
bceadf adcfeg ga dfag geacd cabegdf ceafgb gca aecfd edcbg | ag acbfde gdfa ag
fdcegb abdfce cdega bgcad gfea cae ae bcafged fagedc fgdec | gfdce bafcde gfcdeb ae
egbcda cebadf bfe ef bedcg bgfda fgec fedbg begcfad gdbcef | bef gcbeda ef ecgf
egfdb cgd gdbfea cgbdf fdcba fgbdaec agbdec cg fecg cgdbfe | abgfedc fbcgd cegf gc
cfbegd ab gbacfd agefd ceab baf acfgdeb eafbgc bfegc bagef | ba abf beca baf
fcega fecda cbgaef fgaedb gbfc geadbc fag ecbdgaf eacgb fg | ecdfa bfgc dgebaf gcabe
aefdcg gfdcab ab fagb dbaegcf adb faecbd gcadb fcgad ebdgc | gadcef bfdaecg fgba fgecad
eabfc cdebf bgfca ecfbgad fbdceg aeb gceabd afde ea cbfade | abcdgef eabfc abe bdcfae
cd dgfceab dec cbegfd gedaf adfgec ecbag fgadbe cadf cgdea | fgedbc edc dce adcgfeb
agcdbf ecdgf adfcg agfcbed ef ecdfab efc agfe cgebd defagc | eadcfb cfdbega cef geaf
cdbafe deacf ga dbecag fecdagb bcfge gfda caedfg gae eagfc | ga eag gfcebad cfgae
ceadfg bdf gfbec adbe fbegd abgdfc bd gdefa gdfeba dgacefb | bagedfc facedgb fbd bd
ecdba ecdagb gcfeda fbdaeg cfedb befcdag ca agedb abcg ace | cea fbaged eca bcag
gfedc gdaf gaefc dcf bgcde gdeafc fcgadeb gecabf cdafbe df | fd gcaef df egfdca
afegb cefgb eadcbg cgfbad dbecg cfde aegbcdf fcb gdebfc fc | fbcged bcf gbced aefgdcb
ca bfeda cae ecdfgb edgcf dgceaf gbaced afcg gbeacdf aefcd | ac dfcebag cagf ace
begcad efdagb fbgeadc fedcba aec abedg fcegb ca cgda abegc | abcfgde fgebadc bagedf gdca
aegb cfeadb acdgf decgbf ecgdb gcfedab bgdcea ba gbdac bad | bgceda gdafc fgadc dafcbe
fgecba aec adfe deacb ae abegdcf bcdag ecbfd gecdbf dafceb | gdcab ae edfa daef
agfde eacg adebfg fdgcb cafdg fgdeca cfbaed ac gcadfbe acf | fca gdfae acge dbeacf
fbagce de deg edfa fcbdg gbdcae aegfb dbgfe dgacbfe gefbad | edfa de ged bdgcf
bacfdg cdeafgb aecbfd daefb agedc afc abdefg cebf deacf cf | gbdafc efbc cfead fc
cegfab cdag bdc dc febad gfdbce dcaefbg gfbac dcafbg cdabf | dgafcb cdag dcbgeaf gaefdbc
dagefb acefg afdcb gd dgfaecb facbgd bcdg gda badcfe fgacd | fbecgda cfadb gbdc fcaeg
gfbd cfeda gabcfe db dba baefg beafd bcgdae fedcbag efbdag | dba bad ebgaf dbegfca
cf fbdega aefbg afbcedg edgca dgbcfe gfaec febcag ecf afcb | aefbg gcaefb dbcegaf cef
gebdaf abgd cdabfe gacefbd agfed dg ged fegac aebfd fbdcge | egd abdegcf gadb afbgde
gcdf efdcb acfebd beagdc gd bdefg ebfcgd bdg fbega geabcfd | dgceba ecadgb adgfbce edbgf
fdcaebg efbdgc bgdacf dcae cbdge gebaf abd edgab da bgaedc | cebagd ad da gebcda
bfgcae cbd bcfea aedcb gbefcd cd adecfb adfc cagdfbe dbega | fcad cdabgfe dacf dcb
becg gfbace egacfbd acbfg acdfgb aec ce bdfea cgedaf fbcea | afcbg fedagc befac aecfgd
befa cgfed cfadb gdcfba acdfe ace edgbac fgcdbea ceafdb ae | feab eacdf bcdgafe bfae
bcdefag dafeg fgec dgeafc gea gdfbca cgdaeb bfdea eg dgafc | eg aefcdgb ecdfag gea
gfadb gedfb bdecgfa adbefg dcgaf abf gdcefb aebg ab bafced | gdbfe gbfed ebag cabgfde
dbegfa acgbdf eg gcfbed gdafb bfacegd ebg aged fageb bacfe | ge gefcdba ge bgdfa
adbgec fdceg afdgc bedf cfe fe gaecbdf faebgc gcbed fcbedg | acfdg gdeabc debf ef
dfgbe da ecbadg dafeg fadb gfdbea dagcfbe dbgfec cfgea dga | befdg agd eafdg fabd
bedc aefbc ceadfb fdb cbagfed fecgab dcfba gaebdf cfagd bd | db bfd bfcae adgefb
cabedgf edbfgc gedcfa bacegf fde dgbf baced fd fedbc fegbc | fcdeb adbgefc adecgbf fde
fged egafc ecafgd efcda dfa dfcabg becfag fd agcdfbe ecdab | dgef fd dgfe df
deafgb gbfdc dg dbg agdc dbcafg cadfb bafced fgbce daegbfc | gbfdac afdgcb dgb gdcfb
dfecb fabdge cegbaf fdca faecb aefcdb bdf gdbce afgcebd fd | dbf fbd edcabgf fadc
cbf egabfdc fdcgba fabecd cf dfagb gfac adbegf cdegb bcfgd | acfg afgbed cgdfab fc
ebdfagc bcfa gecfdb af daegbf fgcbd bcdfag egcda fgdca gfa | fcab gafcdb dbfega acfb
adfbg eacb abfcg ecafbg gface ecfgad bc degfbc cbg gabdefc | cb gabefcd cagfebd agcbfe
ebgad bef gacfe gceadf fb efcagbd eabfcd cegfab gbfc ebagf | cefadg fcgae fgbc ebacdgf
dcg aged efacd cfgdae edacbf edfcg bcagdef gd fecbg dcfbag | cdeabgf gd gcd adge
fecgda cdabefg gabfc gfacbd ecgabf cbafe bcdef ea ace bgea | egba gabe beagfdc fbcag
bacdgf eafbd cagde becad afgcedb bc fbegad cfbe cba fcdaeb | fcbe abc dbecaf edcba
ecbdf dagfceb abcfde cbade aebgc adb bfgead debfgc cafd ad | bad dcaf begac da
gbae deafb fdgbea cegfd ag cdaefb cgabefd degfa dag dfcgab | baeg agefdb bcdafg cbdfga
ebcdf gdeafbc cdgbfe eaf cdfa deafbc gedab aecfbg ebadf af | befacd ebfda af af
cfab dcb gfedbac bc cgaedb fbdge cbfdg acgbdf gdcaf acgdfe | bc fcab afcb dbc
edbag gebdc bedfag eacdbg bcedgfa ecab ec gaedcf bdcfg cge | ce ceab ec bdegcaf
fedcba fbgca cbafge ef gbdacf efbgcad gefca befg ecdga afe | fea adgfcb fcage bcdfae
da edfgc cgfdba adfecgb gfaeb dcefga fecdgb gad gdeaf ecad | cedfg dbfcega gfcaed abdcfeg
fcgbed fcbedga cafbe gdceba bcafge bfe fagb fb eacbg facde | cdfbeg fb ebgcadf fgcedba
fecdb fdcbae afdeg cdfea aec efgbadc ca cbfa dcagbe gbefdc | facb fabc fcdbega efadcb
dagcf gadfeb ad dfegbc cgdfba dbac abgecfd dcgfb cfgae adf | fgadc cbda ad cfagd
fdgcb agedbc cdbef feac efb ef febdac afdegb abced edgafcb | fe bfecd dcebf cafe
cafdbg eaf fe gebf befcag cfbga cgaef fdaecbg edcga febacd | gfbe egbf aebgcdf faceg
bfc febg cdfga dafbec cegbd fb cdbgfe cbfgd cadegb gbefdac | dcefgb dbfcg deafbc gbdec
bacgd cedfbg cf aefc dfc aecgdf adfcgeb gafed cafgd baefdg | dgafc fc dfc gfbced
bcge fgc efcdab ecgafb cfeab fabgd fagbc bgcdeaf efcagd cg | cbeg bdagf bcgaf fgc
cdaeg fbaec ceafd fd cfd adfceb bgaecf dbcegf bdaf cgeabdf | df cdf fdagbce cbedaf
dgcbf gecfadb gbdecf gfdbca fbagde ad cdgab dag afcd caegb | cgbedf dfac bdacfeg cafdbg
defacg bd cdbegaf cfaeb dbf cbefgd cgdaf cfbgda facbd gabd | gfadec bdf gbad adgcef
bagdce deagcf bcdf cfa abgfdc cf geacfbd afgeb bacfg dcagb | cf cdbf aedcbfg fbdc
fbceda bedcf dg gefcdb aefbgd gdf cgde gfacb bdcfg dfcegab | dfbagec dfg cabdfeg gd
gda cfgbde dgbfc fgabdc fcagd cagfe baecgdf faebdg ad adbc | efgdcb dag dacb ad
dagec eca fgeacd cdefab gfdacbe afged dabgfe ac dcebg afgc | bdgce ecdga eagdc ca
da bda gadc dbafg fabgc faedcb dfcbgea agcfbe bedgf gfbadc | acbfegd gfabdc bad da
gdce aebfdg faebc fcdabg acgfedb eacgdb adc adgeb cd daceb | cd cgbadf cad edcg
caedb agbed gfbcad eca fdce gbface baefdcg acfdb fbedca ce | eac cebadf fagcdb cae
fcbadeg fcae bfdca ceb ec cdebaf ecbdf gcedab bgdfe dfagcb | geabcd acef agbced gdbeafc
cbdef degba efbad eafc dbcfge ecdafb af fcbgad edfbcag baf | gbdea ecaf eacf egfcdab
fcde gabfd cdgeba fac fc dcabe bfaced dacbf ebgfac cgfbeda | adcfb fca gebdfca fadbc
fdceg cbd edcgfa cb cdgfeb gdebac edgcafb fceb agbdf bgcfd | adfgce beacdgf bc cedfbag
fcbegda dbcefg gcebad gbfc cdb gfbaed bc cebfd ecdfa bdegf | dcb gabedf beafdg bc
cfaed bacdg egd aegcdf gcef gedac cdbefga afdgbe bdfaec eg | gcade cefad bdgfea gaedc
ac dbeacg ace defba fcaebdg dabfce abfedg dcaf cbfae efbcg | fegdba cfbae cea dbacfe
dgcaef bgcaef cfdgeb gd fgecb dcgfbae gebfd bgdc adebf fdg | gdf dafgbec dfg adfeb
ag cadg cgfed aefbc bcegdf agdfbe agf egfca gefcdba gdfeac | dgca dgcaef cdga adebcfg
dfcgbe badg aedgc eabfc dfcbega cgdafe eagbc aegcdb gbe bg | acfdge bge adbg bg
bcfage adcefg dfagc fgaec cdf abcgd dcbgafe df dfae fgcbed | df cfd eacgf fdc
cbadfe bfg cfgebd cbdg edfgbca bg egbdf feagcb fedag cefdb | fgdeb gfb fbdeca bgcd
bcde fdcgba abfcde dbfac abefc befga aec ce acfdge afdegbc | fcbad eac ec becd
ce cbagdf gdcbf cfaebdg gcbe acfdge fcdegb dbaef cef bcefd | acbgdfe cfebd gcebdf ec
ecgbd eacbf cgadeb edf ecafbdg afgebd dcgf ecfbd fgcbed fd | bcfea edf efgabcd df
dgbf egafcd cfedbag cgb abcef dcefg ebcfg cgeadb bg cgbfed | adfgebc egbcf cfeab gaefbdc
gecbfd gbedc dgabcef baefgd abegc dbfce bfdace dg gdb dfcg | dfgc bedfac dg dbg
acbdgf daeb gcbeaf gdfce adefg fbdga cbdfega fae fgdbea ea | ea fcdgaeb ae gecfadb
ga bdgafe bcaed dcgaebf bacfed acedg gbadec edgfc agd bcga | adg dga agcb fdecgab
ebdcfg cfbdg ecgabf gcd edfc fdcbeag ebcdag dabgf dc cgebf | cd gcd gacbde cd
egdfac bf afebdg baf bfdeca bgdf fedga egacb gecbafd gbeaf | bfa fb gfdb fb
gcafb dc gecd fecbgda cfdbg dfebgc cdf fbegd dcfbea fgedab | edfcbg dgbcf cd dcf
badf fcagd agcefb dfgcab ba dcbeg cedabgf abgdc acegfd abg | ebfagc dfab ab fcbdeag
cfgbad gdbfe fe efgdacb cbdge dabgfe egdcaf befa bdgfa egf | decagfb eabf baef fe
dbfea bcaefdg dcfgeb ag bfceag egfcda becfg fgeba gcab ega | agbfecd aedfcgb gcba ga

0
2021/inputs/day9.txt Normal file
View File

10
2021/tests/day1.txt Normal file
View File

@@ -0,0 +1,10 @@
199
200
208
210
200
207
240
269
260
263

0
2021/tests/day10.txt Normal file
View File

0
2021/tests/day11.txt Normal file
View File

0
2021/tests/day12.txt Normal file
View File

0
2021/tests/day13.txt Normal file
View File

0
2021/tests/day14.txt Normal file
View File

0
2021/tests/day15.txt Normal file
View File

0
2021/tests/day16.txt Normal file
View File

0
2021/tests/day17.txt Normal file
View File

0
2021/tests/day18.txt Normal file
View File

0
2021/tests/day19.txt Normal file
View File

6
2021/tests/day2.txt Normal file
View File

@@ -0,0 +1,6 @@
forward 5
down 5
forward 8
up 3
down 8
forward 2

0
2021/tests/day20.txt Normal file
View File

0
2021/tests/day21.txt Normal file
View File

0
2021/tests/day22.txt Normal file
View File

0
2021/tests/day23.txt Normal file
View File

0
2021/tests/day24.txt Normal file
View File

0
2021/tests/day25.txt Normal file
View File

12
2021/tests/day3.txt Normal file
View File

@@ -0,0 +1,12 @@
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010

19
2021/tests/day4.txt Normal file
View File

@@ -0,0 +1,19 @@
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7

0
2021/tests/day5.txt Normal file
View File

1
2021/tests/day6.txt Normal file
View File

@@ -0,0 +1 @@
3,4,3,1,2

1
2021/tests/day7.txt Normal file
View File

@@ -0,0 +1 @@
16,1,2,0,4,2,7,1,2,14

10
2021/tests/day8.txt Normal file
View File

@@ -0,0 +1,10 @@
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce

0
2021/tests/day9.txt Normal file
View File

View File

@@ -1,20 +1,7 @@
# -*- encoding: utf-8 -*-
import sys
lines = sys.stdin.readlines()
blocks = sys.stdin.read().split("\n\n")
values = sorted(sum(map(int, block.split())) for block in blocks)
# we store the list of calories for each elf in values, and we use the last element
# of values to accumulate
values: list[int] = [0]
for line in lines:
if not line.strip():
values = values + [0]
else:
values[-1] += int(line.strip())
# part 1
print(f"answer 1 is {max(values)}")
# part 2
print(f"answer 2 is {sum(sorted(values)[-3:])}")
print(f"answer 1 is {values[-1]}")
print(f"answer 2 is {sum(values[-3:])}")

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import sys
lines = sys.stdin.read().splitlines()

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import copy
import sys
from functools import reduce
@@ -7,7 +5,6 @@ from typing import Callable, Final, Mapping, Sequence
class Monkey:
id: Final[int]
items: Final[Sequence[int]]
worry_fn: Final[Callable[[int], int]]
@@ -97,8 +94,7 @@ def run(
# number of inspects
inspects = {monkey: 0 for monkey in monkeys}
for round in range(n_rounds):
for _ in range(n_rounds):
for monkey in monkeys:
for item in items[monkey]:
inspects[monkey] += 1

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import heapq
import sys
from typing import Callable, Iterator, TypeVar
@@ -44,7 +42,6 @@ def dijkstra(
visited.add(current)
for neighbor in neighbors(current):
if neighbor in visited:
continue
@@ -60,7 +57,6 @@ def dijkstra(
def make_path(parents: dict[Node, Node], start: Node, end: Node) -> list[Node] | None:
if end not in parents:
return None
@@ -109,7 +105,6 @@ def neighbors(
(c_row, c_col - 1),
(c_row, c_col + 1),
):
if not (n_row >= 0 and n_row < n_rows and n_col >= 0 and n_col < n_cols):
continue

View File

@@ -1,27 +1,27 @@
# -*- encoding: utf-8 -*-
import json
import sys
from functools import cmp_to_key
from typing import TypeAlias, cast
blocks = sys.stdin.read().strip().split("\n\n")
pairs = [tuple(json.loads(p) for p in block.split("\n")) for block in blocks]
Packet: TypeAlias = list[int | list["Packet"]]
def compare(lhs: list[int | list], rhs: list[int | list]) -> int:
def compare(lhs: Packet, rhs: Packet) -> int:
for lhs_a, rhs_a in zip(lhs, rhs):
if isinstance(lhs_a, int) and isinstance(rhs_a, int):
if lhs_a != rhs_a:
return rhs_a - lhs_a
else:
if not isinstance(lhs_a, list):
lhs_a = [lhs_a]
lhs_a = [lhs_a] # type: ignore
elif not isinstance(rhs_a, list):
rhs_a = [rhs_a]
rhs_a = [rhs_a] # type: ignore
assert isinstance(rhs_a, list) and isinstance(lhs_a, list)
r = compare(lhs_a, rhs_a)
r = compare(cast(Packet, lhs_a), cast(Packet, rhs_a))
if r != 0:
return r

View File

@@ -1,7 +1,4 @@
# -*- encoding: utf-8 -*-
import sys
from collections import defaultdict
from enum import Enum, auto
from typing import Callable, cast
@@ -23,10 +20,10 @@ def print_blocks(blocks: dict[tuple[int, int], Cell]):
blocks: Set of blocks to print.
"""
x_min, y_min, x_max, y_max = (
min(x for x, y in blocks),
min(x for x, _ in blocks),
0,
max(x for x, y in blocks),
max(y for x, y in blocks),
max(x for x, _ in blocks),
max(y for _, y in blocks),
)
for y in range(y_min, y_max + 1):
@@ -56,13 +53,12 @@ def flow(
The input blocks.
"""
y_max = max(y for x, y in blocks)
y_max = max(y for _, y in blocks)
while True:
x, y = 500, 0
while y <= y_max:
moved = False
for cx, cy in ((x, y + 1), (x - 1, y + 1), (x + 1, y + 1)):
if (cx, cy) not in blocks and fill_fn(cx, cy) == Cell.AIR:
@@ -117,10 +113,10 @@ print_blocks(blocks)
print()
x_min, y_min, x_max, y_max = (
min(x for x, y in blocks),
min(x for x, _ in blocks),
0,
max(x for x, y in blocks),
max(y for x, y in blocks),
max(x for x, _ in blocks),
max(y for _, y in blocks),
)
# === part 1 ===

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import sys
import numpy as np
@@ -7,7 +5,6 @@ import parse
def part1(sensor_to_beacon: dict[tuple[int, int], tuple[int, int]], row: int) -> int:
no_beacons_row_l: list[np.ndarray] = []
for (sx, sy), (bx, by) in sensor_to_beacon.items():
@@ -37,7 +34,7 @@ def part2_intervals(
its.append((max(0, sx - dx), min(sx + dx, xy_max)))
its = sorted(its)
s, e = its[0]
_, e = its[0]
for si, ei in its[1:]:
if si > e + 1:

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
from __future__ import annotations
import heapq
@@ -69,7 +67,6 @@ def part_1(
distances: dict[tuple[Pipe, Pipe], int],
relevant_pipes: FrozenSet[Pipe],
):
node_at_times: dict[int, dict[Pipe, dict[FrozenSet[Pipe], int]]] = defaultdict(
lambda: defaultdict(lambda: defaultdict(lambda: 0))
)
@@ -79,7 +76,6 @@ def part_1(
for c_pipe, nodes in node_at_times[time].items():
for flowing, flow in nodes.items():
for target in relevant_pipes:
distance = distances[c_pipe, target] + 1
if time + distance >= max_time or target in flowing:
continue

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import sys
from typing import Sequence, TypeVar
@@ -49,7 +47,6 @@ def build_tower(
early_stop: bool = False,
init: np.ndarray = np.ones(WIDTH, dtype=bool),
) -> tuple[np.ndarray, int, int, dict[int, int]]:
tower = EMPTY_BLOCKS.copy()
tower[0, :] = init
@@ -59,7 +56,6 @@ def build_tower(
rock_count = 0
for rock_count in range(n_rocks):
if early_stop:
if i_rock == 0 and (i_rock, i_jet) in done_at:
break
@@ -75,7 +71,6 @@ def build_tower(
tower = np.concatenate([tower, EMPTY_BLOCKS], axis=0)
while True:
jet, i_jet = next_cycle(jets, i_jet)
dx = 0

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import sys
from typing import FrozenSet

View File

@@ -1,17 +1,12 @@
# -*- encoding: utf-8 -*-
import heapq
import math
import sys
import time
from collections import defaultdict
from typing import Literal, TypedDict
from typing import Literal
import numpy as np
import parse
from tqdm import tqdm
Reagent = Literal["ore", "clay", "obsidian", "geode"]
REAGENTS: tuple[Reagent] = (
REAGENTS: tuple[Reagent, ...] = (
"ore",
"clay",
"obsidian",
@@ -20,23 +15,6 @@ REAGENTS: tuple[Reagent] = (
IntOfReagent = dict[Reagent, int]
lines = sys.stdin.read().splitlines()
blueprints: list[dict[Reagent, IntOfReagent]] = [
{
"ore": {"ore": 4},
"clay": {"ore": 2},
"obsidian": {"ore": 3, "clay": 14},
"geode": {"ore": 2, "obsidian": 7},
},
{
"ore": {"ore": 2},
"clay": {"ore": 3},
"obsidian": {"ore": 3, "clay": 8},
"geode": {"ore": 3, "obsidian": 12},
},
]
class State:
robots: IntOfReagent
@@ -64,11 +42,6 @@ class State:
and self.reagents == other.reagents
)
def __lt__(self, other) -> bool:
return isinstance(other, State) and tuple(
(self.robots[r], self.reagents[r]) for r in REAGENTS
) > tuple((other.robots[r], other.reagents[r]) for r in REAGENTS)
def __hash__(self) -> int:
return hash(tuple((self.robots[r], self.reagents[r]) for r in REAGENTS))
@@ -89,399 +62,121 @@ def dominates(lhs: State, rhs: State):
)
MAX_TIME = 24
blueprint = blueprints[1]
lines = sys.stdin.read().splitlines()
# parents: dict[State, tuple[State | None, int]] = {State(): (None, 0)}
# queue = [(0, State())]
# visited: set[State] = set()
# at_time: dict[int, list[State]] = defaultdict(lambda: [])
blueprints: list[dict[Reagent, IntOfReagent]] = []
for line in lines:
r = parse.parse(
"Blueprint {}: "
"Each ore robot costs {:d} ore. "
"Each clay robot costs {:d} ore. "
"Each obsidian robot costs {:d} ore and {:d} clay. "
"Each geode robot costs {:d} ore and {:d} obsidian.",
line,
)
# while queue:
# time, state = heapq.heappop(queue)
# if state in visited:
# continue
# print(time, state)
# visited.add(state)
# at_time[time].append(state)
# if time > MAX_TIME:
# continue
# if len(queue) % 200 == 0:
# print(len(queue), len(visited), time)
# can_build_any: bool = False
# for reagent in REAGENTS:
# needed = blueprint[reagent]
# if any(state.robots[r] == 0 for r in needed):
# continue
# time_to_complete = max(
# max(
# math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
# for r in needed
# ),
# 0,
# )
# # if time_to_complete != 0:
# # continue
# if time + time_to_complete + 1 > MAX_TIME:
# continue
# wait = time_to_complete + 1
# reagents = {
# r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
# for r in REAGENTS
# }
# robots = state.robots.copy()
# robots[reagent] += 1
# state_2 = State(reagents=reagents, robots=robots)
# if state_2 in visited:
# continue
# if any(dominates(state_v, state_2) for state_v in at_time[time + wait]):
# continue
# # print(time + wait)
# # if any(dominates(state_3, state_2) for state_3 in at_time[time + wait]):
# # print("?")
# # continue
# if state_2 not in parents or parents[state_2][1] > time + wait:
# parents[state_2] = (state, time + wait)
# heapq.heappush(queue, (time + wait, state_2))
# can_build_any = True
# at_time[time + wait].append(state_2)
# if not can_build_any:
# state_2 = State(
# reagents={
# r: state.reagents[r] + state.robots[r] * (MAX_TIME - time)
# for r in REAGENTS
# },
# robots=state.robots,
# )
# if state_2 in visited:
# continue
# if state_2 not in parents or parents[state_2][1] > time + wait:
# parents[state_2] = (state, MAX_TIME)
# heapq.heappush(queue, (MAX_TIME, state_2))
# print(len(visited))
# print(max(state.reagents["geode"] for state in visited))
# exit()
# while states:
# state = states.pop()
# processed.append(state)
# if state.time > MAX_TIME:
# continue
# if len(states) % 100 == 0:
# print(len(states), len(processed), min((s.time for s in states), default=1))
# can_build_any: bool = False
# for reagent in REAGENTS:
# needed = blueprint[reagent]
# if any(state.robots[r] == 0 for r in needed):
# continue
# time_to_complete = max(
# max(
# math.ceil((needed[r] - state.reagents[r]) / state.robots[r])
# for r in needed
# ),
# 0,
# )
# if state.time + time_to_complete + 1 > MAX_TIME:
# continue
# wait = time_to_complete + 1
# reagents = {
# r: state.reagents[r] + wait * state.robots[r] - needed.get(r, 0)
# for r in REAGENTS
# }
# robots = state.robots.copy()
# robots[reagent] += 1
# can_build_any = True
# state_2 = State(time=state.time + wait, reagents=reagents, robots=robots)
# # print(f"{state} -> {state_2}")
# states.add(state_2)
# if not any(dominates(s2, state_2) for s2 in states):
# states.add(state)
# # print(f"can build {reagent} in {time_to_complete}")
# if not can_build_any:
# states.add(
# State(
# time=MAX_TIME + 1,
# reagents={
# r: state.reagents[r] + state.robots[r] * (MAX_TIME - state.time)
# for r in REAGENTS
# },
# robots=state.robots,
# )
# )
# if len(states) % 1000 == 0:
# print("filtering")
# states = {
# s1
# for s1 in states
# if not any(dominates(s2, s1) for s2 in states if s2 is not s1)
# }
# # if len(states) > 4:
# # break
# # break
# print(len(processed))
# print(max(state.reagents["geode"] for state in processed))
# exit()
# for t in range(1, 25):
# states = set()
# for state in state_after_t[t - 1]:
# robots_that_can_be_built = [
# robot
# for robot in REAGENTS
# if all(
# state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
# for reagent in REAGENTS
# )
# ]
# new_states = set()
# # new reagents
# reagents = {
# reagent: state.reagents[reagent] + state.robots[reagent]
# for reagent in REAGENTS
# }
# # if we can build anything, there is no point in waiting
# if len(robots_that_can_be_built) != len(REAGENTS):
# new_states.add(State(robots=state.robots, reagents=reagents))
# for robot in robots_that_can_be_built:
# robots = state.robots.copy()
# robots[robot] += 1
# reagents = {
# reagent: state.reagents[reagent]
# + state.robots[reagent]
# - blueprint[robot].get(reagent, 0)
# for reagent in REAGENTS
# }
# new_states.add(State(robots=robots, reagents=reagents))
# new_states = [
# s1
# for s1 in new_states
# if not any(s1 is not s2 and dominates(s2, s1) for s2 in new_states)
# ]
# states = {
# s1 for s1 in states if not any(dominates(s2, s1) for s2 in new_states)
# }
# states.update(new_states)
# state_after_t[t] = states
# exit()
blueprints.append(
{
"ore": {"ore": r[1]},
"clay": {"ore": r[2]},
"obsidian": {"ore": r[3], "clay": r[4]},
"geode": {"ore": r[5], "obsidian": r[6]},
}
)
MAX_TIME = 24
blueprint = blueprints[0]
def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
# since we can only build one robot per time, we do not need more than X robots
# of type K where X is the maximum number of K required among all robots, e.g.,
# in the first toy blueprint, we need at most 4 ore robots, 14 clay ones and 7
# obsidian ones
maximums = {
name: max(blueprint[r].get(name, 0) for r in REAGENTS) for name in REAGENTS
}
state_after_t: dict[int, list[State]] = {0: [State()]}
state_after_t: dict[int, set[State]] = {0: [State()]}
for t in range(1, 25):
print(t, len(state_after_t[t - 1]))
for t in range(1, max_time + 1):
# list of new states at the end of step t that we are going to prune later
states_for_t: set[State] = set()
bests_for_robots: dict[tuple[int, ...], list[State]] = {}
bests_for_reagents: dict[tuple[int, ...], list[State]] = {}
for state in state_after_t[t - 1]:
robots_that_can_be_built = [
robot
for robot in REAGENTS
if all(
state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
)
]
state_after_t[t] = []
t1 = time.time()
for state in state_after_t[t - 1]:
robots_that_can_be_built = [
robot
for robot in REAGENTS
if all(
state.reagents[reagent] >= blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
states_for_t.add(
State(
robots=state.robots,
reagents={
reagent: state.reagents[reagent] + state.robots[reagent]
for reagent in REAGENTS
},
)
)
]
# print(t, robots_that_can_be_built)
new_states: set[State] = set()
if "geode" in robots_that_can_be_built:
robots_that_can_be_built = ["geode"]
else:
robots_that_can_be_built = [
robot
for robot in robots_that_can_be_built
if state.robots[robot] < maximums[robot]
]
# new reagents
reagents = {
reagent: state.reagents[reagent] + state.robots[reagent]
for reagent in REAGENTS
for robot in robots_that_can_be_built:
robots = state.robots.copy()
robots[robot] += 1
reagents = {
reagent: state.reagents[reagent]
+ state.robots[reagent]
- blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
}
states_for_t.add(State(robots=robots, reagents=reagents))
# use numpy to switch computation of dominated states -> store each state
# as a 8 array and use numpy broadcasting to find dominated states
states_after = np.asarray(list(states_for_t))
np_states = np.array(
[
[state.robots[r] for r in REAGENTS]
+ [state.reagents[r] for r in REAGENTS]
for state in states_after
]
)
to_keep = []
while len(np_states) > 0:
first_dom = (np_states[1:] >= np_states[0]).all(axis=1).any()
if first_dom:
np_states = np_states[1:]
else:
to_keep.append(np_states[0])
np_states = np_states[1:][~(np_states[1:] <= np_states[0]).all(axis=1)]
state_after_t[t] = {
State(
robots=dict(zip(REAGENTS, row[:4])),
reagents=dict(zip(REAGENTS, row[4:])),
)
for row in to_keep
}
# if we can build anything, there is no point in waiting
new_states.add(State(robots=state.robots, reagents=reagents))
return max(state.reagents["geode"] for state in state_after_t[max_time])
for robot in robots_that_can_be_built:
robots = state.robots.copy()
robots[robot] += 1
reagents = {
reagent: state.reagents[reagent]
+ state.robots[reagent]
- blueprint[robot].get(reagent, 0)
for reagent in REAGENTS
}
new_states.add(State(robots=robots, reagents=reagents))
for s1 in new_states:
r1 = tuple(s1.robots[r] for r in REAGENTS)
if r1 not in bests_for_robots:
bests_for_robots[r1] = [s1]
else:
is_dominated = False
for s2 in bests_for_robots[r1]:
if all(s2.reagents[r] >= s1.reagents[r] for r in REAGENTS):
is_dominated = True
break
if not is_dominated:
bests_for_robots[r1].append(s1)
answer_1 = sum(
(i_blueprint + 1) * run(blueprint, 24)
for i_blueprint, blueprint in enumerate(blueprints)
)
print(f"answer 1 is {answer_1}")
r2 = tuple(s1.reagents[r] for r in REAGENTS)
if r2 not in bests_for_reagents:
bests_for_reagents[r2] = [s1]
else:
is_dominated = False
for s2 in bests_for_reagents[r2]:
if all(s2.robots[r] >= s1.robots[r] for r in REAGENTS):
is_dominated = True
break
if not is_dominated:
bests_for_reagents[r2].append(s1)
# state_after_t[t].extend(new_states)
t2 = time.time()
for bests in bests_for_robots.values():
dominated = [False for _ in range(len(bests))]
for i_s1, s1 in enumerate(bests):
if dominated[i_s1]:
continue
for i_s2, s2 in enumerate(bests[i_s1 + 1 :], start=i_s1 + 1):
if dominated[i_s2]:
continue
if all(s1.reagents[r] >= s2.reagents[r] for r in REAGENTS):
dominated[i_s2] = True
state_after_t[t].extend(
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
)
for bests in bests_for_reagents.values():
dominated = [False for _ in range(len(bests))]
for i_s1, s1 in enumerate(bests):
if dominated[i_s1]:
continue
for i_s2, s2 in enumerate(bests[i_s1 + 1 :], start=i_s1 + 1):
if dominated[i_s2]:
continue
if all(s1.robots[r] >= s2.robots[r] for r in REAGENTS):
dominated[i_s2] = True
state_after_t[t].extend(
s1 for i_s1, s1 in enumerate(bests) if not dominated[i_s1]
)
t3 = time.time()
np_states = np.array(
[
[state.robots[r] for r in REAGENTS] + [state.reagents[r] for r in REAGENTS]
for state in state_after_t[t]
]
)
dominated = np.zeros(len(np_states), dtype=bool)
t4 = time.time()
# c = (np_states[None, :, :] <= np_states[:, None, :]).all(axis=-1)
# c[np.arange(len(np_states)), np.arange(len(np_states))] = False
# dominated = c.any(axis=0)
for i in range(len(np_states)):
if dominated[i]:
continue
dominated[i] = not (np_states[i + 1 :] <= np_states[i]).any(axis=1)
dominated[i + 1 :] = (np_states[i + 1 :] <= np_states[i]).all(axis=1)
t5 = time.time()
state_after_t[t] = list(np.array(state_after_t[t])[~dominated])
t6 = time.time()
print(
"->",
t,
len(state_after_t[t]),
dominated.sum(),
t2 - t1,
t3 - t2,
t4 - t3,
t5 - t4,
t6 - t5,
)
# print("->", len(state_after_t[t]))
# dominated = [False for _ in range(len(state_after_t[t]))]
# keep = set()
# for i_s1, s1 in enumerate(tqdm(state_after_t[t])):
# if dominated[i_s1]:
# continue
# for i_s2, s2 in enumerate(state_after_t[t][i_s1 + 1 :], start=i_s1 + 1):
# if dominated[i_s2]:
# continue
# if dominates(s1, s2):
# dominated[i_s2] = True
# elif dominates(s2, s1):
# dominated[i_s1] = True
# break
# if not dominated[i_s1]:
# keep.add(s1)
# state_after_t[t] = list(keep)
# print(len(state_after_t[t]))
# print(sum(dominated))
# break
print(max(state.reagents["geode"] for state in state_after_t[24]))
answer_2 = run(blueprints[0], 32) * run(blueprints[1], 32) * run(blueprints[2], 32)
print(f"answer 2 is {answer_2}")

View File

@@ -1,20 +1,5 @@
# -*- encoding: utf-8 -*-
import sys
lines = sys.stdin.readlines()
# the solution relies on replacing rock / paper / scissor by values 0 / 1 / 2 and using
# modulo-3 arithmetic
#
# in modulo-3 arithmetic, the winning move is 1 + the opponent move (e.g., winning move
# if opponent plays 0 is 1, or 0 if opponent plays 2 (0 = (2 + 1 % 3)))
#
# we read the lines in a Nx2 in array with value 0/1/2 instead of A/B/C or X/Y/Z for
# easier manipulation
values = [(ord(row[0]) - ord("A"), ord(row[2]) - ord("X")) for row in lines]
def score_1(ux: int, vx: int) -> int:
# here ux and vx are both moves: 0 = rock, 1 = paper, 2 = scissor
@@ -48,8 +33,21 @@ def score_2(ux: int, vx: int) -> int:
return (ux + vx - 1) % 3 + 1 + vx * 3
lines = sys.stdin.readlines()
# the solution relies on replacing rock / paper / scissor by values 0 / 1 / 2 and using
# modulo-3 arithmetic
#
# in modulo-3 arithmetic, the winning move is 1 + the opponent move (e.g., winning move
# if opponent plays 0 is 1, or 0 if opponent plays 2 (0 = (2 + 1 % 3)))
#
# we read the lines in a Nx2 in array with value 0/1/2 instead of A/B/C or X/Y/Z for
# easier manipulation
values = [(ord(row[0]) - ord("A"), ord(row[2]) - ord("X")) for row in lines]
# part 1 - 13526
print(f"score 1 is {sum(score_1(*v) for v in values)}")
print(f"answer 1 is {sum(score_1(*v) for v in values)}")
# part 2 - 14204
print(f"score 2 is {sum(score_2(*v) for v in values)}")
print(f"answer 2 is {sum(score_2(*v) for v in values)}")

74
2022/day20.py Normal file
View File

@@ -0,0 +1,74 @@
from __future__ import annotations
import sys
class Number:
current: int
value: int
def __init__(self, value: int):
self.current = 0
self.value = value
def __str__(self):
return str(self.value)
def __repr__(self):
return str(self)
def decrypt(numbers: list[Number], key: int, rounds: int) -> int:
numbers = numbers.copy()
original = numbers.copy()
for index, number in enumerate(numbers):
number.current = index
for _ in range(rounds):
for number in original:
index = number.current
offset = (number.value * key) % (len(numbers) - 1)
target = index + offset
# need to wrap
if target >= len(numbers):
target = offset - (len(numbers) - index) + 1
for number_2 in numbers[target:index]:
number_2.current += 1
numbers = (
numbers[:target]
+ [number]
+ numbers[target:index]
+ numbers[index + 1 :]
)
else:
for number_2 in numbers[index : target + 1]:
number_2.current -= 1
numbers = (
numbers[:index]
+ numbers[index + 1 : target + 1]
+ [number]
+ numbers[target + 1 :]
)
number.current = target
index_of_0 = next(
filter(lambda index: numbers[index].value == 0, range(len(numbers)))
)
return sum(
numbers[(index_of_0 + offset) % len(numbers)].value * key
for offset in (1000, 2000, 3000)
)
numbers = [Number(int(x)) for i, x in enumerate(sys.stdin.readlines())]
answer_1 = decrypt(numbers, 1, 1)
print(f"answer 1 is {answer_1}")
answer_2 = decrypt(numbers, 811589153, 10)
print(f"answer 2 is {answer_2}")

107
2022/day21.py Normal file
View File

@@ -0,0 +1,107 @@
import operator
import sys
from typing import Callable
def compute(monkeys: dict[str, int | tuple[str, str, str]], monkey: str) -> int:
value = monkeys[monkey]
if isinstance(value, int):
return value
else:
op: dict[str, Callable[[int, int], int]] = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.floordiv,
}
value = op[value[1]](compute(monkeys, value[0]), compute(monkeys, value[2]))
monkeys[monkey] = value
return value
def invert(
monkeys: dict[str, int | tuple[str, str, str]], monkey: str, target: int
) -> dict[str, int | tuple[str, str, str]]:
"""
Revert the given mapping from monkey name to value or operation such that
the value from 'monkey' is computable by inverting operation until the root is
found.
Args:
monkeys: Dictionary of monkeys, that will be updated and returned.
monkey: Name of the monkey to start from.
target: Target value to set for the monkey that depends on root.
Returns:
The given dictionary of monkeys.
"""
monkeys = monkeys.copy()
depends: dict[str, str] = {}
for m, v in monkeys.items():
if isinstance(v, int):
continue
op1, _, op2 = v
assert op1 not in depends
assert op2 not in depends
depends[op1] = m
depends[op2] = m
invert_op = {"+": "-", "-": "+", "*": "/", "/": "*"}
current = monkey
while True:
dep = depends[current]
if dep == "root":
monkeys[current] = target
break
val = monkeys[dep]
assert not isinstance(val, int)
op1, ope, op2 = val
if op1 == current:
monkeys[current] = (dep, invert_op[ope], op2)
elif ope in ("+", "*"):
monkeys[current] = (dep, invert_op[ope], op1)
else:
monkeys[current] = (op1, ope, dep)
current = dep
return monkeys
lines = sys.stdin.read().splitlines()
monkeys: dict[str, int | tuple[str, str, str]] = {}
op_monkeys: set[str] = set()
for line in lines:
parts = line.split(":")
name = parts[0].strip()
try:
value = int(parts[1].strip())
monkeys[name] = value
except ValueError:
op1, ope, op2 = parts[1].strip().split()
monkeys[name] = (op1, ope, op2)
op_monkeys.add(name)
answer_1 = compute(monkeys.copy(), "root")
print(f"answer 1 is {answer_1}")
# assume the second operand of 'root' can be computed, and the first one depends on
# humn, which is the case is my input and the test input
p1, _, p2 = monkeys["root"] # type: ignore
answer_2 = compute(invert(monkeys, "humn", compute(monkeys.copy(), p2)), "humn")
print(f"answer 2 is {answer_2}")

223
2022/day22.py Normal file
View File

@@ -0,0 +1,223 @@
import re
import sys
from typing import Callable
import numpy as np
VOID, EMPTY, WALL = 0, 1, 2
TILE_FROM_CHAR = {" ": VOID, ".": EMPTY, "#": WALL}
SCORES = {"E": 0, "S": 1, "W": 2, "N": 3}
board_map_s, direction_s = sys.stdin.read().split("\n\n")
# board
board_lines = board_map_s.splitlines()
max_line = max(len(line) for line in board_lines)
board = np.array(
[
[TILE_FROM_CHAR[c] for c in row] + [VOID] * (max_line - len(row))
for row in board_map_s.splitlines()
]
)
directions = [
int(p1) if p2 else p1 for p1, p2 in re.findall(R"(([0-9])+|L|R)", direction_s)
]
# find on each row and column the first and last non-void
row_first_non_void = np.argmax(board != VOID, axis=1)
row_last_non_void = board.shape[1] - np.argmax(board[:, ::-1] != VOID, axis=1) - 1
col_first_non_void = np.argmax(board != VOID, axis=0)
col_last_non_void = board.shape[0] - np.argmax(board[::-1, :] != VOID, axis=0) - 1
faces = np.zeros_like(board)
size = np.gcd(board.shape[0], board.shape[1])
for row in range(0, board.shape[0], size):
for col in range(row_first_non_void[row], row_last_non_void[row], size):
faces[row : row + size, col : col + size] = faces.max() + 1
SIZE = np.gcd(*board.shape)
# TODO: deduce this from the actual cube...
faces_wrap: dict[int, dict[str, Callable[[int, int], tuple[int, int, str]]]]
if board.shape == (12, 16): # example
faces_wrap = {
1: {
"W": lambda y, x: (4, 4 + y, "S"), # 3N
"N": lambda y, x: (4, 11 - x, "S"), # 2N
"E": lambda y, x: (11 - y, 15, "W"), # 6E
},
2: {
"W": lambda y, x: (11, 19 - y, "N"), # 6S
"N": lambda y, x: (0, 11 - y, "S"), # 1N
"S": lambda y, x: (11, 11 - x, "N"), # 5S
},
3: {
"N": lambda y, x: (x - 4, 8, "E"), # 1W
"S": lambda y, x: (15 - x, 8, "E"), # 5W
},
4: {"E": lambda y, x: (8, 19 - y, "S")}, # 6N
5: {
"W": lambda y, x: (7, 15 - y, "N"), # 3S
"S": lambda y, x: (7, 11 - x, "N"), # 2S
},
6: {
"N": lambda y, x: (19 - x, 11, "W"), # 4E
"E": lambda y, x: (11 - y, 11, "W"), # 1E
"S": lambda y, x: (19 - x, 0, "E"), # 2W
},
}
else:
faces_wrap = {
1: {
"W": lambda y, x: (3 * SIZE - y - 1, 0, "E"), # 4W
"N": lambda y, x: (2 * SIZE + x, 0, "E"), # 6W
},
2: {
"N": lambda y, x: (4 * SIZE - 1, x - 2 * SIZE, "N"), # 6S
"E": lambda y, x: (3 * SIZE - y - 1, 2 * SIZE - 1, "W"), # 5E
"S": lambda y, x: (x - SIZE, 2 * SIZE - 1, "W"), # 3E
},
3: {
"W": lambda y, x: (2 * SIZE, y - SIZE, "S"), # 4N
"E": lambda y, x: (SIZE - 1, SIZE + y, "N"), # 2S
},
4: {
"W": lambda y, x: (3 * SIZE - y - 1, SIZE, "E"), # 1W
"N": lambda y, x: (SIZE + x, SIZE, "E"), # 3W
},
5: {
"E": lambda y, x: (3 * SIZE - y - 1, 3 * SIZE - 1, "W"), # 2E
"S": lambda y, x: (2 * SIZE + x, SIZE - 1, "W"), # 6E
},
6: {
"W": lambda y, x: (0, y - 2 * SIZE, "S"), # 1N
"E": lambda y, x: (3 * SIZE - 1, y - 2 * SIZE, "N"), # 5S
"S": lambda y, x: (0, x + 2 * SIZE, "S"), # 2N
},
}
def wrap_part_1(y0: int, x0: int, r0: str) -> tuple[int, int, str]:
if r0 == "E":
return y0, row_first_non_void[y0], r0
elif r0 == "S":
return col_first_non_void[x0], x0, r0
elif r0 == "W":
return y0, row_last_non_void[y0], r0
elif r0 == "N":
return col_last_non_void[x0], x0, r0
assert False
def wrap_part_2(y0: int, x0: int, r0: str) -> tuple[int, int, str]:
cube = faces[y0, x0]
assert r0 in faces_wrap[cube]
return faces_wrap[cube][r0](y0, x0)
def run(wrap: Callable[[int, int, str], tuple[int, int, str]]) -> tuple[int, int, str]:
y0 = 0
x0 = np.where(board[0] == EMPTY)[0][0]
r0 = "E"
for direction in directions:
if isinstance(direction, int):
while direction > 0:
if r0 == "E":
xi = np.where(board[y0, x0 + 1 : x0 + direction + 1] == WALL)[0]
if len(xi):
x0 = x0 + xi[0]
direction = 0
elif (
x0 + direction < board.shape[1]
and board[y0, x0 + direction] == EMPTY
):
x0 = x0 + direction
direction = 0
else:
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
if board[y0_t, x0_t] == WALL:
x0 = row_last_non_void[y0]
direction = 0
else:
direction = direction - (row_last_non_void[y0] - x0) - 1
y0, x0, r0 = y0_t, x0_t, r0_t
elif r0 == "S":
yi = np.where(board[y0 + 1 : y0 + direction + 1, x0] == WALL)[0]
if len(yi):
y0 = y0 + yi[0]
direction = 0
elif (
y0 + direction < board.shape[0]
and board[y0 + direction, x0] == EMPTY
):
y0 = y0 + direction
direction = 0
else:
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
if board[y0_t, x0_t] == WALL:
y0 = col_last_non_void[x0]
direction = 0
else:
direction = direction - (col_last_non_void[x0] - y0) - 1
y0, x0, r0 = y0_t, x0_t, r0_t
elif r0 == "W":
left = max(x0 - direction - 1, 0)
xi = np.where(board[y0, left:x0] == WALL)[0]
if len(xi):
x0 = left + xi[-1] + 1
direction = 0
elif x0 - direction >= 0 and board[y0, x0 - direction] == EMPTY:
x0 = x0 - direction
direction = 0
else:
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
if board[y0_t, x0_t] == WALL:
x0 = row_first_non_void[y0]
direction = 0
else:
direction = direction - (x0 - row_first_non_void[y0]) - 1
y0, x0, r0 = y0_t, x0_t, r0_t
elif r0 == "N":
top = max(y0 - direction - 1, 0)
yi = np.where(board[top:y0, x0] == WALL)[0]
if len(yi):
y0 = top + yi[-1] + 1
direction = 0
elif y0 - direction >= 0 and board[y0 - direction, x0] == EMPTY:
y0 = y0 - direction
direction = 0
else:
y0_t, x0_t, r0_t = wrap(y0, x0, r0)
if board[y0_t, x0_t] == WALL:
y0 = col_first_non_void[x0]
direction = 0
else:
direction = direction - (y0 - col_first_non_void[x0]) - 1
y0, x0, r0 = y0_t, x0_t, r0_t
else:
r0 = {
"E": {"L": "N", "R": "S"},
"N": {"L": "W", "R": "E"},
"W": {"L": "S", "R": "N"},
"S": {"L": "E", "R": "W"},
}[r0][direction]
return y0, x0, r0
y1, x1, r1 = run(wrap_part_1)
answer_1 = 1000 * (1 + y1) + 4 * (1 + x1) + SCORES[r1]
print(f"answer 1 is {answer_1}")
y2, x2, r2 = run(wrap_part_2)
answer_2 = 1000 * (1 + y2) + 4 * (1 + x2) + SCORES[r2]
print(f"answer 2 is {answer_2}")

103
2022/day23.py Normal file
View File

@@ -0,0 +1,103 @@
import itertools
import sys
from collections import defaultdict
Directions = list[
tuple[
str, tuple[int, int], tuple[tuple[int, int], tuple[int, int], tuple[int, int]]
]
]
# (Y, X)
DIRECTIONS: Directions = [
("N", (-1, 0), ((-1, -1), (-1, 0), (-1, 1))),
("S", (1, 0), ((1, -1), (1, 0), (1, 1))),
("W", (0, -1), ((-1, -1), (0, -1), (1, -1))),
("E", (0, 1), ((-1, 1), (0, 1), (1, 1))),
]
def min_max_yx(positions: set[tuple[int, int]]) -> tuple[int, int, int, int]:
ys, xs = {y for y, x in positions}, {x for y, x in positions}
return min(ys), min(xs), max(ys), max(xs)
def print_positions(positions: set[tuple[int, int]]):
min_y, min_x, max_y, max_x = min_max_yx(positions)
print(
"\n".join(
"".join(
"#" if (y, x) in positions else "." for x in range(min_x - 1, max_x + 2)
)
for y in range(min_y - 1, max_y + 2)
)
)
def round(
positions: set[tuple[int, int]],
directions: Directions,
):
to_move: dict[tuple[int, int], list[tuple[int, int]]] = defaultdict(lambda: [])
for y, x in positions:
elves = {
(dy, dx): (y + dy, x + dx) in positions
for dy, dx in itertools.product((-1, 0, 1), (-1, 0, 1))
if (dy, dx) != (0, 0)
}
if not any(elves.values()):
to_move[y, x].append((y, x))
continue
found: str | None = None
for d, (dy, dx), d_yx_check in directions:
if not any(elves[dy, dx] for dy, dx in d_yx_check):
found = d
to_move[y + dy, x + dx].append((y, x))
break
if found is None:
to_move[y, x].append((y, x))
positions.clear()
for ty, tx in to_move:
if len(to_move[ty, tx]) > 1:
positions.update(to_move[ty, tx])
else:
positions.add((ty, tx))
directions.append(directions.pop(0))
POSITIONS = {
(i, j)
for i, row in enumerate(sys.stdin.read().splitlines())
for j, col in enumerate(row)
if col == "#"
}
# === part 1 ===
p1, d1 = POSITIONS.copy(), DIRECTIONS.copy()
for r in range(10):
round(p1, d1)
min_y, min_x, max_y, max_x = min_max_yx(p1)
answer_1 = sum(
(y, x) not in p1 for y in range(min_y, max_y + 1) for x in range(min_x, max_x + 1)
)
print(f"answer 1 is {answer_1}")
# === part 2 ===
p2, d2 = POSITIONS.copy(), DIRECTIONS.copy()
answer_2 = 0
while True:
answer_2 += 1
backup = p2.copy()
round(p2, d2)
if backup == p2:
break
print(f"answer 2 is {answer_2}")

98
2022/day24.py Normal file
View File

@@ -0,0 +1,98 @@
import heapq
import math
import sys
from collections import defaultdict
lines = sys.stdin.read().splitlines()
winds = {
(i - 1, j - 1, lines[i][j])
for i in range(1, len(lines) - 1)
for j in range(1, len(lines[i]) - 1)
if lines[i][j] != "."
}
n_rows, n_cols = len(lines) - 2, len(lines[0]) - 2
CYCLE = math.lcm(n_rows, n_cols)
east_winds = [{j for j in range(n_cols) if (i, j, ">") in winds} for i in range(n_rows)]
west_winds = [{j for j in range(n_cols) if (i, j, "<") in winds} for i in range(n_rows)]
north_winds = [
{i for i in range(n_rows) if (i, j, "^") in winds} for j in range(n_cols)
]
south_winds = [
{i for i in range(n_rows) if (i, j, "v") in winds} for j in range(n_cols)
]
def run(start: tuple[int, int], start_cycle: int, end: tuple[int, int]):
def heuristic(y: int, x: int) -> int:
return abs(end[0] - y) + abs(end[1] - x)
# (distance + heuristic, distance, (start_pos, cycle))
queue = [(heuristic(start[0], start[1]), 0, ((start[0], start[1]), start_cycle))]
visited: set[tuple[tuple[int, int], int]] = set()
distances: dict[tuple[int, int], dict[int, int]] = defaultdict(lambda: {})
while queue:
_, distance, ((y, x), cycle) = heapq.heappop(queue)
if ((y, x), cycle) in visited:
continue
distances[y, x][cycle] = distance
visited.add(((y, x), cycle))
if (y, x) == (end[0], end[1]):
break
for dy, dx in (0, 0), (-1, 0), (1, 0), (0, -1), (0, 1):
ty = y + dy
tx = x + dx
n_cycle = (cycle + 1) % CYCLE
if (ty, tx) == end:
heapq.heappush(queue, (distance + 1, distance + 1, ((ty, tx), n_cycle)))
break
if ((ty, tx), n_cycle) in visited:
continue
if (ty, tx) != start and (ty < 0 or tx < 0 or ty >= n_rows or tx >= n_cols):
continue
if (ty, tx) != start:
if (ty - n_cycle) % n_rows in south_winds[tx]:
continue
if (ty + n_cycle) % n_rows in north_winds[tx]:
continue
if (tx + n_cycle) % n_cols in west_winds[ty]:
continue
if (tx - n_cycle) % n_cols in east_winds[ty]:
continue
heapq.heappush(
queue,
((heuristic(ty, tx) + distance + 1, distance + 1, ((ty, tx), n_cycle))),
)
return distances, next(iter(distances[end].values()))
start = (
-1,
next(j for j in range(1, len(lines[0]) - 1) if lines[0][j] == ".") - 1,
)
end = (
n_rows,
next(j for j in range(1, len(lines[-1]) - 1) if lines[-1][j] == ".") - 1,
)
distances_1, forward_1 = run(start, 0, end)
print(f"answer 1 is {forward_1}")
distances_2, return_1 = run(end, next(iter(distances_1[end].keys())), start)
distances_3, forward_2 = run(start, next(iter(distances_2[start].keys())), end)
print(f"answer 2 is {forward_1 + return_1 + forward_2}")

27
2022/day25.py Normal file
View File

@@ -0,0 +1,27 @@
import sys
lines = sys.stdin.read().splitlines()
coeffs = {"2": 2, "1": 1, "0": 0, "-": -1, "=": -2}
def snafu2number(number: str) -> int:
value = 0
for c in number:
value *= 5
value += coeffs[c]
return value
def number2snafu(number: int) -> str:
values = ["0", "1", "2", "=", "-"]
res = ""
while number > 0:
mod = number % 5
res = res + values[mod]
number = number // 5 + int(mod >= 3)
return "".join(reversed(res))
answer_1 = number2snafu(sum(map(snafu2number, lines)))
print(f"answer 1 is {answer_1}")

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import string
import sys
@@ -13,13 +11,13 @@ priorities = {c: i + 1 for i, c in enumerate(string.ascii_letters)}
# part 1
part1 = sum(priorities[c] for p1, p2 in parts for c in p1.intersection(p2))
print(f"score 1 is {part1}")
print(f"answer 1 is {part1}")
# part 2
n_per_group = 3
part2 = sum(
priorities[c]
for i in range(0, len(lines), n_per_group)
for c in set.intersection(*map(set, (lines[i : i + n_per_group])))
for c in set(lines[i]).intersection(*lines[i + 1 : i + n_per_group])
)
print(f"score 2 is {part2}")
print(f"answer 2 is {part2}")

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import sys
lines = [line.strip() for line in sys.stdin.readlines()]
@@ -12,8 +10,8 @@ def make_range(value: str) -> set[int]:
sections = [tuple(make_range(part) for part in line.split(",")) for line in lines]
score_1 = sum(s1.issubset(s2) or s2.issubset(s1) for s1, s2 in sections)
print(f"score 1 is {score_1}")
answer_1 = sum(s1.issubset(s2) or s2.issubset(s1) for s1, s2 in sections)
print(f"answer 1 is {answer_1}")
score_2 = sum(bool(s1.intersection(s2)) for s1, s2 in sections)
print(f"score 1 is {score_2}")
answer_2 = sum(bool(s1.intersection(s2)) for s1, s2 in sections)
print(f"answer 1 is {answer_2}")

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import copy
import sys

View File

@@ -1,9 +1,5 @@
# -*- encoding: utf-8 -*-
import sys
data = sys.stdin.read().strip()
def index_of_first_n_differents(data: str, n: int) -> int:
for i in range(len(data)):
@@ -12,5 +8,8 @@ def index_of_first_n_differents(data: str, n: int) -> int:
return -1
data = sys.stdin.read().strip()
print(f"answer 1 is {index_of_first_n_differents(data, 4)}")
print(f"answer 2 is {index_of_first_n_differents(data, 14)}")

View File

@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-
import sys
from pathlib import Path

View File

@@ -1,8 +1,7 @@
# -*- encoding: utf-8 -*-
import sys
import numpy as np
from numpy.typing import NDArray
lines = sys.stdin.read().splitlines()
@@ -27,7 +26,7 @@ answer_1 = (highest_trees.min(axis=2) < trees).sum()
print(f"answer 1 is {answer_1}")
def viewing_distance(row_of_trees: np.ndarray, value: int) -> int:
def viewing_distance(row_of_trees: NDArray[np.int_], value: int) -> int:
w = np.where(row_of_trees >= value)[0]
if not w.size:

View File

@@ -1,12 +1,9 @@
# -*- encoding: utf-8 -*-
import sys
import numpy as np
def move(head: tuple[int, int], command: str) -> tuple[int, int]:
h_col, h_row = head
if command == "L":
@@ -22,7 +19,6 @@ def move(head: tuple[int, int], command: str) -> tuple[int, int]:
def follow(head: tuple[int, int], tail: tuple[int, int]) -> tuple[int, int]:
h_col, h_row = head
t_col, t_row = tail
@@ -33,8 +29,7 @@ def follow(head: tuple[int, int], tail: tuple[int, int]) -> tuple[int, int]:
def run(commands: list[str], n_blocks: int) -> list[tuple[int, int]]:
blocks = [(0, 0) for _ in range(n_blocks)]
blocks: list[tuple[int, int]] = [(0, 0) for _ in range(n_blocks)]
visited = [blocks[-1]]
for command in commands:

30
2022/inputs/day19.txt Normal file
View File

@@ -0,0 +1,30 @@
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 12 clay. Each geode robot costs 4 ore and 19 obsidian.
Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 2 ore and 7 obsidian.
Blueprint 3: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 13 clay. Each geode robot costs 3 ore and 12 obsidian.
Blueprint 4: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian.
Blueprint 5: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 4 ore and 13 obsidian.
Blueprint 6: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 7: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 17 obsidian.
Blueprint 8: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 13 clay. Each geode robot costs 3 ore and 7 obsidian.
Blueprint 9: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 12 clay. Each geode robot costs 3 ore and 15 obsidian.
Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 11: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 2 ore and 15 obsidian.
Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 3 ore and 7 obsidian.
Blueprint 13: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 10 clay. Each geode robot costs 2 ore and 10 obsidian.
Blueprint 14: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.
Blueprint 15: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 8 obsidian.
Blueprint 16: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 18 obsidian.
Blueprint 17: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 9 clay. Each geode robot costs 3 ore and 19 obsidian.
Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 4 ore and 8 obsidian.
Blueprint 19: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 12 clay. Each geode robot costs 3 ore and 17 obsidian.
Blueprint 20: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian.
Blueprint 21: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 16 obsidian.
Blueprint 22: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 4 ore and 16 obsidian.
Blueprint 23: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 4 ore and 11 obsidian.
Blueprint 24: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 9 obsidian.
Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 17 clay. Each geode robot costs 3 ore and 16 obsidian.
Blueprint 26: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 4 ore and 7 obsidian.
Blueprint 27: Each ore robot costs 2 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 8 clay. Each geode robot costs 2 ore and 14 obsidian.
Blueprint 28: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 20 clay. Each geode robot costs 3 ore and 14 obsidian.
Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 4 ore and 8 obsidian.
Blueprint 30: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian.

Some files were not shown because too many files have changed in this diff Show More