Skip to content

Commit 9f6d493

Browse files
committed
Everybody Codes: solve 2025/07 (rough)
1 parent d3d5bab commit 9f6d493

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""Everyone Codes Day N."""
2+
3+
import collections
4+
import functools
5+
from lib import parsers
6+
7+
8+
def solve(part: int, data: str) -> int:
9+
"""Solve the parts."""
10+
rev_pairs = collections.defaultdict(set)
11+
pairs = collections.defaultdict(set)
12+
for line in data.split("\n\n")[1].splitlines():
13+
a, b = line.split(" > ")
14+
for c in b.split(","):
15+
pairs[a].add(c)
16+
rev_pairs[c].add(a)
17+
18+
@functools.cache
19+
def possibilities(size: int, letter: str) -> int:
20+
if size == 11:
21+
return 1
22+
count = 0 if size < 7 else 1
23+
size += 1
24+
return count + sum(possibilities(size, i) for i in pairs[letter])
25+
26+
total = 0
27+
names = data.split("\n\n")[0].split(",")
28+
if part == 3:
29+
names = set(names)
30+
names = {n for n in names if not any(n != m and n.startswith(m) for m in names)}
31+
32+
for idx, name in enumerate(names, start=1):
33+
for a, b in zip(name, name[1:]):
34+
if a not in rev_pairs[b]:
35+
break
36+
else:
37+
if part == 1:
38+
return name
39+
if part == 2:
40+
total += idx
41+
else:
42+
total += possibilities(len(name), name[-1])
43+
return total
44+
45+
46+
TEST_DATA = [
47+
"""\
48+
Oronris,Urakris,Oroneth,Uraketh
49+
50+
r > a,i,o
51+
i > p,w
52+
n > e,r
53+
o > n,m
54+
k > f,r
55+
a > k
56+
U > r
57+
e > t
58+
O > r
59+
t > h""",
60+
"""\
61+
Xanverax,Khargyth,Nexzeth,Helther,Braerex,Tirgryph,Kharverax
62+
63+
r > v,e,a,g,y
64+
a > e,v,x,r
65+
e > r,x,v,t
66+
h > a,e,v
67+
g > r,y
68+
y > p,t
69+
i > v,r
70+
K > h
71+
v > e
72+
B > r
73+
t > h
74+
N > e
75+
p > h
76+
H > e
77+
l > t
78+
z > e
79+
X > a
80+
n > v
81+
x > z
82+
T > i""",
83+
"""\
84+
Xaryt
85+
86+
X > a,o
87+
a > r,t
88+
r > y,e,a
89+
h > a,e,v
90+
t > h
91+
v > e
92+
y > p,t""",
93+
"""\
94+
Khara,Xaryt,Noxer,Kharax
95+
96+
r > v,e,a,g,y
97+
a > e,v,x,r,g
98+
e > r,x,v,t
99+
h > a,e,v
100+
g > r,y
101+
y > p,t
102+
i > v,r
103+
K > h
104+
v > e
105+
B > r
106+
t > h
107+
N > e
108+
p > h
109+
H > e
110+
l > t
111+
z > e
112+
X > a
113+
n > v
114+
x > z
115+
T > i""",
116+
]
117+
TESTS = [
118+
(1, TEST_DATA[0], "Oroneth"),
119+
(2, TEST_DATA[1], 23),
120+
(3, TEST_DATA[2], 25),
121+
(3, TEST_DATA[3], 1154),
122+
]
123+
124+
if __name__ == "__main__":
125+
for _part, _data, expected in TESTS:
126+
assert solve(_part, PARSER.parse(_data)) == expected
127+
print("Tests pass.")
128+
day = __file__.split("_", maxsplit=-1)[-1].split(".")[0]
129+
for _part in range(1, 4):
130+
with open(f"inputs/{day}.{_part}.txt", encoding="utf-8") as f:
131+
print(_part, solve(_part, PARSER.parse(f.read())))

0 commit comments

Comments
 (0)