Compare commits

...

100 commits

Author SHA1 Message Date
02110dfaeb 2017: d25: ex2: add solution 2025-05-12 00:05:25 +01:00
50e3321a74 2017: d25: ex2: add input 2025-05-12 00:05:19 +01:00
12a1c92929 2017: d25: ex1: add solution 2025-05-12 00:05:14 +01:00
a22f8c1baa 2017: d25: ex1: add input 2025-05-12 00:05:03 +01:00
f21f1b7db0 2017: d24: ex2: add solution 2025-05-11 23:39:18 +01:00
fe1d76f55e 2017: d24: ex2: add input 2025-05-11 23:39:01 +01:00
e67c050303 2017: d24: ex1: add solution 2025-05-11 23:38:56 +01:00
31e167a38d 2017: d24: ex1: add input 2025-05-11 23:38:51 +01:00
cc916af0b7 2017: d23: ex2: add solution 2025-05-11 23:14:23 +01:00
3e51e4176f 2017: d23: ex2: add input 2025-05-11 23:14:15 +01:00
8e0f57e836 2017: d23: ex1: add solution 2025-05-11 23:14:07 +01:00
660de4339d 2017: d23: ex1: add input 2025-05-11 23:13:55 +01:00
b3f39262fe 2017: d22: ex2: add solution 2025-05-11 22:33:11 +01:00
f18af71775 2017: d22: ex2: add input 2025-05-11 22:32:59 +01:00
2426ac2fb1 2017: d22: ex1: add solution 2025-05-11 22:32:53 +01:00
2ac7701a6d 2017: d22: ex1: add input 2025-05-11 22:32:41 +01:00
8d0f95e46b 2017: d21: ex2: add solution 2025-05-11 21:59:19 +01:00
49c121deba 2017: d21: ex2: add input 2025-05-11 21:59:15 +01:00
645546fd8c 2017: d21: ex1: add solution 2025-05-11 21:59:09 +01:00
2089266e58 2017: d21: ex1: add input 2025-05-11 21:59:03 +01:00
2cde2f7d82 2017: d20: ex2: add solution 2025-05-11 03:59:18 +01:00
7108246f19 2017: d20: ex2: add input 2025-05-11 03:57:45 +01:00
321696264b 2017: d20: ex1: add solution 2025-05-11 03:57:40 +01:00
454032bb1c 2017: d20: ex1: add input 2025-05-11 03:57:22 +01:00
c2c2fac322 2017: d19: ex2: add solution 2025-05-11 01:13:16 +01:00
99b2298165 2017: d19: ex2: add input 2025-05-11 01:13:04 +01:00
bbafa72fd3 2017: d19: ex1: add solution 2025-05-11 01:12:58 +01:00
f97e96bf2c 2017: d19: ex1: add input 2025-05-11 01:12:46 +01:00
84da8f5e6f 2017: d18: ex2: add solution 2025-05-10 14:42:36 +01:00
69a57c1e4f 2017: d18: ex2: add input 2025-05-10 14:42:17 +01:00
58474371d7 2017: d18: ex1: add solution 2025-05-10 14:42:12 +01:00
3005867f9e 2017: d18: ex1: add input 2025-05-10 14:42:07 +01:00
0b148f649d 2017: d17: ex2: add solution 2025-05-10 13:46:26 +01:00
d636ec9673 2017: d17: ex2: add input 2025-05-10 13:46:22 +01:00
41a7054551 2017: d17: ex1: add solution 2025-05-10 13:46:17 +01:00
3c2fdb87d9 2017: d17: ex1: add input 2025-05-10 13:46:12 +01:00
e1c56b2257 2017: d16: ex2: add solution 2025-05-10 12:50:24 +01:00
e92ae7907d 2017: d16: ex2: add input 2025-05-10 12:50:20 +01:00
260f28ed28 2017: d16: ex1: add solution 2025-05-10 12:50:15 +01:00
30ce157e6e 2017: d16: ex1: add input 2025-05-10 12:50:10 +01:00
e0bae5d69b 2017: d15: ex2: add solution 2025-05-09 23:53:28 +01:00
593fe1ae89 2017: d15: ex2: add input 2025-05-09 23:53:22 +01:00
290ac25ea1 2017: d15: ex1: add solution 2025-05-09 23:53:17 +01:00
3c7e4725d0 2017: d15: ex1: add input 2025-05-09 23:53:12 +01:00
711fab975b 2017: d14: ex2: add solution 2025-05-09 23:39:27 +01:00
af8dca3341 2017: d14: ex2: add input 2025-05-09 23:37:52 +01:00
1882d6c8cb 2017: d14: ex1: add solution 2025-05-09 23:37:37 +01:00
ed7e1eb331 2017: d14: ex1: add input 2025-05-09 23:37:33 +01:00
dd0a8c9e44 2017: d13: ex2: add solution 2025-05-09 23:37:26 +01:00
54055e181e 2017: d13: ex2: add input 2025-05-09 23:37:17 +01:00
679a7ab896 2017: d13: ex1: add solution 2025-05-09 23:36:59 +01:00
dc95ad558a 2017: d13: ex1: add input 2025-05-09 23:36:53 +01:00
182256f243 2017: d12: ex2: add solution 2025-05-09 22:38:36 +01:00
8dd0166344 2017: d12: ex2: add input 2025-05-09 22:38:28 +01:00
4b5dde286b 2017: d12: ex1: add solution 2025-05-09 22:38:19 +01:00
6bdd04bf86 2017: d12: ex1: add input 2025-05-09 22:38:14 +01:00
acae5d1ac7 2017: d11: ex2: add solution 2025-05-09 22:25:07 +01:00
f982f0c1c3 2017: d11: ex2: add input 2025-05-09 22:24:56 +01:00
9e100a2253 2017: d11: ex1: add solution 2025-05-09 22:24:51 +01:00
f14f10d342 2017: d11: ex1: add input 2025-05-09 22:24:46 +01:00
b95e2692d0 2017: d10: ex2: add solution 2025-05-09 20:40:09 +01:00
a0a987fa93 2017: d10: ex2: add input 2025-05-09 20:39:28 +01:00
fe26aad92c 2017: d10: ex1: add solution 2025-05-09 20:39:09 +01:00
de1ac4e86c 2017: d10: ex1: add input 2025-05-09 20:39:04 +01:00
375f3a869b 2017: d09: ex2: add solution 2025-05-09 19:36:51 +01:00
ea9c7c2b06 2017: d09: ex2: add input 2025-05-09 19:36:42 +01:00
1316159034 2017: d09: ex1: add solution 2025-05-09 19:36:37 +01:00
af04c1cf3d 2017: d09: ex1: add input 2025-05-09 19:36:26 +01:00
05ed480e05 2017: d08: ex2: add solution 2025-05-09 19:10:09 +01:00
767fa3d28f 2017: d08: ex2: add input 2025-05-09 19:09:57 +01:00
dc594e697a 2017: d08: ex1: add solution 2025-05-09 19:09:51 +01:00
74ad567803 2017: d08: ex1: add input 2025-05-09 19:09:38 +01:00
cb5b497a30 2017: d07: ex2: add solution 2025-05-09 18:40:14 +01:00
00fc68766b 2017: d07: ex2: add input 2025-05-09 18:39:39 +01:00
b5fdff5945 2017: d07: ex1: add solution 2025-05-09 18:39:32 +01:00
4570e2c20e 2017: d07: ex1: add input 2025-05-09 18:39:23 +01:00
f6c88b4f7b 2017: d06: ex2: add solution 2025-05-09 18:00:34 +01:00
cac1a0d672 2017: d06: ex2: add input 2025-05-09 18:00:29 +01:00
fd4e28c410 2017: d06: ex1: add solution 2025-05-09 18:00:24 +01:00
1b36307f94 2017: d06: ex1: add input 2025-05-09 18:00:20 +01:00
ca1ceaa487 2017: d05: ex2: add solution 2025-05-09 16:44:54 +01:00
d69b3b13c4 2017: d05: ex2: add input 2025-05-09 16:44:44 +01:00
abd946c749 2017: d05: ex1: add solution 2025-05-09 16:44:39 +01:00
f33f53335a 2017: d05: ex1: add input 2025-05-09 16:44:30 +01:00
d473d73f53 2017: d04: ex2: add solution 2025-05-09 16:11:35 +01:00
48d50b56c6 2017: d04: ex2: add input 2025-05-09 16:11:29 +01:00
511e8abb0a 2017: d04: ex1: add solution 2025-05-09 16:11:23 +01:00
71ab7e5dc2 2017: d04: ex1: add input 2025-05-09 16:11:17 +01:00
e1c8817c8c 2017: d03: ex2: add solution 2025-05-09 16:06:58 +01:00
ff9f668a4c 2017: d03: ex2: add input 2025-05-09 16:06:43 +01:00
f651907e86 2017: d03: ex1: add solution 2025-05-09 16:06:37 +01:00
795eda00c4 2017: d03: ex1: add input 2025-05-09 16:06:32 +01:00
3e6fb347c0 2017: d02: ex2: add solution 2025-05-09 15:06:03 +01:00
c31f2128f5 2017: d02: ex2: add input 2025-05-09 15:05:53 +01:00
b252c19691 2017: d02: ex1: add solution 2025-05-09 15:05:45 +01:00
fa3a1ae980 2017: d02: ex1: add input 2025-05-09 15:05:36 +01:00
660af9f0b1 2017: d01: ex2: add solution 2025-05-09 14:59:41 +01:00
f1f6bd4ade 2017: d01: ex2: add input 2025-05-09 14:59:37 +01:00
64db8a4834 2017: d01: ex1: add solution 2025-05-09 14:59:31 +01:00
cc723e61bd 2017: d01: ex1: add input 2025-05-09 14:59:25 +01:00
100 changed files with 17632 additions and 0 deletions

17
2017/d01/ex1/ex1.py Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
nums = [int(n) for n in input.strip()]
return sum(n for n, m in zip(nums, nums[1:] + nums[:1]) if n == m)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d01/ex1/input Normal file
View file

@ -0,0 +1 @@
5255443714755555317777152441826784321918285999594221531636242944998363716119294845838579943562543247239969555791772392681567883449837982119239536325341263524415397123824358467891963762948723327774545715851542429832119179139914471523515332247317441719184556891362179267368325486642376685657759623876854958721636574219871249645773738597751429959437466876166273755524873351452951411628479352522367714269718514838933283861425982562854845471512652555633922878128558926123935941858532446378815929573452775348599693982834699757734714187831337546474515678577158721751921562145591166634279699299418269158557557996583881642468274618196335267342897498486869925262896125146867124596587989531495891646681528259624674792728146526849711139146268799436334618974547539561587581268886449291817335232859391493839167111246376493191985145848531829344198536568987996894226585837348372958959535969651573516542581144462536574953764413723147957237298324458181291167587791714172674717898567269547766636143732438694473231473258452166457194797819423528139157452148236943283374193561963393846385622218535952591588353565319432285579711881559343544515461962846879685879431767963975654347569385354482226341261768547328749947163864645168428953445396361398873536434931823635522467754782422557998262858297563862492652464526366171218276176258582444923497181776129436396397333976215976731542182878979389362297155819461685361676414725597335759976285597713332688275241271664658286868697167515329811831234324698345159949135474463624749624626518247831448143876183133814263977611564339865466321244399177464822649611969896344874381978986453566979762911155931362394192663943526834148596342268321563885255765614418141828934971927998994739769141789185165461976425151855846739959338649499379657223196885539386154935586794548365861759354865453211721551776997576289811595654171672259129335243531518228282393326395241242185795828261319215164262237957743232558971289145639852148197184265766291885259847236646615935963759631145338159257538114359781854685695429348428884248972177278361353814766653996675994784195827214295462389532422825696456457332417366426619555

18
2017/d01/ex2/ex2.py Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
nums = [int(n) for n in input.strip()]
half = len(nums) // 2
return sum(n for n, m in zip(nums, nums[half:] + nums[:half]) if n == m)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d01/ex2/input Normal file
View file

@ -0,0 +1 @@
5255443714755555317777152441826784321918285999594221531636242944998363716119294845838579943562543247239969555791772392681567883449837982119239536325341263524415397123824358467891963762948723327774545715851542429832119179139914471523515332247317441719184556891362179267368325486642376685657759623876854958721636574219871249645773738597751429959437466876166273755524873351452951411628479352522367714269718514838933283861425982562854845471512652555633922878128558926123935941858532446378815929573452775348599693982834699757734714187831337546474515678577158721751921562145591166634279699299418269158557557996583881642468274618196335267342897498486869925262896125146867124596587989531495891646681528259624674792728146526849711139146268799436334618974547539561587581268886449291817335232859391493839167111246376493191985145848531829344198536568987996894226585837348372958959535969651573516542581144462536574953764413723147957237298324458181291167587791714172674717898567269547766636143732438694473231473258452166457194797819423528139157452148236943283374193561963393846385622218535952591588353565319432285579711881559343544515461962846879685879431767963975654347569385354482226341261768547328749947163864645168428953445396361398873536434931823635522467754782422557998262858297563862492652464526366171218276176258582444923497181776129436396397333976215976731542182878979389362297155819461685361676414725597335759976285597713332688275241271664658286868697167515329811831234324698345159949135474463624749624626518247831448143876183133814263977611564339865466321244399177464822649611969896344874381978986453566979762911155931362394192663943526834148596342268321563885255765614418141828934971927998994739769141789185165461976425151855846739959338649499379657223196885539386154935586794548365861759354865453211721551776997576289811595654171672259129335243531518228282393326395241242185795828261319215164262237957743232558971289145639852148197184265766291885259847236646615935963759631145338159257538114359781854685695429348428884248972177278361353814766653996675994784195827214295462389532422825696456457332417366426619555

23
2017/d02/ex1/ex1.py Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[list[int]]:
return [[int(n) for n in line.split()] for line in input.splitlines()]
def checksum(row: list[int]) -> int:
return max(row) - min(row)
sheet = parse(input)
return sum(map(checksum, sheet))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

16
2017/d02/ex1/input Normal file
View file

@ -0,0 +1,16 @@
5048 177 5280 5058 4504 3805 5735 220 4362 1809 1521 230 772 1088 178 1794
6629 3839 258 4473 5961 6539 6870 4140 4638 387 7464 229 4173 5706 185 271
5149 2892 5854 2000 256 3995 5250 249 3916 184 2497 210 4601 3955 1110 5340
153 468 550 126 495 142 385 144 165 188 609 182 439 545 608 319
1123 104 567 1098 286 665 1261 107 227 942 1222 128 1001 122 69 139
111 1998 1148 91 1355 90 202 1522 1496 1362 1728 109 2287 918 2217 1138
426 372 489 226 344 431 67 124 120 386 348 153 242 133 112 369
1574 265 144 2490 163 749 3409 3086 154 151 133 990 1002 3168 588 2998
173 192 2269 760 1630 215 966 2692 3855 3550 468 4098 3071 162 329 3648
1984 300 163 5616 4862 586 4884 239 1839 169 5514 4226 5551 3700 216 5912
1749 2062 194 1045 2685 156 3257 1319 3199 2775 211 213 1221 198 2864 2982
273 977 89 198 85 1025 1157 1125 69 94 919 103 1299 998 809 478
1965 6989 230 2025 6290 2901 192 215 4782 6041 6672 7070 7104 207 7451 5071
1261 77 1417 1053 2072 641 74 86 91 1878 1944 2292 1446 689 2315 1379
296 306 1953 3538 248 1579 4326 2178 5021 2529 794 5391 4712 3734 261 4362
2426 192 1764 288 4431 2396 2336 854 2157 216 4392 3972 229 244 4289 1902

29
2017/d02/ex2/ex2.py Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env python
import itertools
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[list[int]]:
return [[int(n) for n in line.split()] for line in input.splitlines()]
def evenly_divide(row: list[int]) -> int:
for a, b in itertools.combinations(sorted(row), 2):
assert a <= b # Sanity check
if b % a:
continue
return b // a
assert False # Sanity check
sheet = parse(input)
return sum(map(evenly_divide, sheet))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

16
2017/d02/ex2/input Normal file
View file

@ -0,0 +1,16 @@
5048 177 5280 5058 4504 3805 5735 220 4362 1809 1521 230 772 1088 178 1794
6629 3839 258 4473 5961 6539 6870 4140 4638 387 7464 229 4173 5706 185 271
5149 2892 5854 2000 256 3995 5250 249 3916 184 2497 210 4601 3955 1110 5340
153 468 550 126 495 142 385 144 165 188 609 182 439 545 608 319
1123 104 567 1098 286 665 1261 107 227 942 1222 128 1001 122 69 139
111 1998 1148 91 1355 90 202 1522 1496 1362 1728 109 2287 918 2217 1138
426 372 489 226 344 431 67 124 120 386 348 153 242 133 112 369
1574 265 144 2490 163 749 3409 3086 154 151 133 990 1002 3168 588 2998
173 192 2269 760 1630 215 966 2692 3855 3550 468 4098 3071 162 329 3648
1984 300 163 5616 4862 586 4884 239 1839 169 5514 4226 5551 3700 216 5912
1749 2062 194 1045 2685 156 3257 1319 3199 2775 211 213 1221 198 2864 2982
273 977 89 198 85 1025 1157 1125 69 94 919 103 1299 998 809 478
1965 6989 230 2025 6290 2901 192 215 4782 6041 6672 7070 7104 207 7451 5071
1261 77 1417 1053 2072 641 74 86 91 1878 1944 2292 1446 689 2315 1379
296 306 1953 3538 248 1579 4326 2178 5021 2529 794 5391 4712 3734 261 4362
2426 192 1764 288 4431 2396 2336 854 2157 216 4392 3972 229 244 4289 1902

46
2017/d03/ex1/ex1.py Executable file
View file

@ -0,0 +1,46 @@
#!/usr/bin/env python
import itertools
import sys
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
def solve(input: str) -> int:
def target_coord(target: int) -> Point:
for dist in itertools.count():
side = dist * 2 + 1
bot_right = side * side
if bot_right < target:
continue
# Target must be in the last loop, before bot_right
bot_left = bot_right - side + 1
top_left = bot_left - side + 1
top_right = top_left - side + 1
if bot_left <= target <= bot_right:
return Point(dist - (bot_right - target), -dist)
if top_left <= target <= bot_left:
return Point(-dist, -dist + (bot_left - target))
if top_right <= target <= top_left:
return Point(-dist + (top_left - target), dist)
if target <= top_right:
return Point(dist, dist - (top_right - target))
assert False # Sanity check
assert False # Sanity check
target = int(input)
coord = target_coord(target)
return abs(coord.x) + abs(coord.y)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d03/ex1/input Normal file
View file

@ -0,0 +1 @@
347991

56
2017/d03/ex2/ex2.py Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env python
import itertools
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
def neighbours(self) -> Iterator["Point"]:
for dx, dy in itertools.product((-1, 0, 1), repeat=2):
if dx == 0 and dy == 0:
continue
yield Point(self.x + dx, self.y + dy)
def solve(input: str) -> int:
def spiral() -> Iterator[Point]:
yield Point(0, 0)
for dist in itertools.count(1):
side = dist * 2 + 1
for start, dx, dy in (
(Point(dist, -dist), 0, 1),
(Point(dist, dist), -1, 0),
(Point(-dist, dist), 0, -1),
(Point(-dist, -dist), 1, 0),
):
# We need a non-zero step for `range`, and to make it inclusive
stepx = dx if dx != 0 else 1
stepy = dy if dy != 0 else 1
# Don't include the corner, which was already output in previous loop
# Hence, `side - 1` points in the range
xs = range(start.x + dx, start.x + (side - 1) * dx + stepx, stepx)
ys = range(start.y + dy, start.y + (side - 1) * dy + stepy, stepy)
yield from (Point(x, y) for x, y in itertools.product(xs, ys))
target = int(input)
values = {Point(0, 0): 1}
# Skip the origin, which we already know
for p in itertools.islice(spiral(), 1, None):
if (res := sum(values.get(n, 0) for n in p.neighbours())) > target:
return res
values[p] = res
assert False # Sanity check
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d03/ex2/input Normal file
View file

@ -0,0 +1 @@
347991

23
2017/d04/ex1/ex1.py Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[list[str]]:
return [line.split() for line in input.splitlines()]
def validate_passphrase(passphrase: list[str]) -> bool:
return len(set(passphrase)) == len(passphrase)
passphrases = parse(input)
return sum(map(validate_passphrase, passphrases))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

512
2017/d04/ex1/input Normal file
View file

@ -0,0 +1,512 @@
vxjtwn vjnxtw sxibvv mmws wjvtxn icawnd rprh
fhaa qwy vqbq gsswej lxr yzl wakcige mwjrl
bhnlow huqa gtbjc gvj wrkyr jgvmhj bgs umo ikbpdto
drczdf bglmf gsx flcf ojpj kzrwrho owbkl dgrnv bggjevc
ndncqdl lncaugj mfa lncaugj skt pkssyen rsb npjzf
kdd itdyhe pvljizn cgi
jgy pyhuq eecb phwkyl oeftyu pyhuq hecxgti tpadffm jgy
zvc qdk mlmyj kybbh lgbb fvfzcer frmaxa yzgw podt dbycoii afj
zfr msn mns leqem frz
golnm ltizhd dvwv xrizqhd omegnez nan yqajse lgef
gbej rvek aehiz bgje
yej cphl jtp swe axhljo ddwk obwsq mnewiwu klddd
ipiev henods rpn qfpg gjfdgs zcpt sswab eosdhn teeil
gzje ydu oiu jzge udy sqjeoo olxej
mgn gox tcifta vzc lxry gox gox mvila qdl jipjnw dvu
hxk xhk unhdmdz yomze povrt nbww bxu qqsqc rvuk tgffy twddm
fyx fyx nzkm fyx
ymnoc zogudq yncom tqrob sidvy dfuu ccjpiej yidvs
bxebny akknwxw jeyxqvj syl cedps akknwxw akknwxw zpvnf kuoon pnkejn wqjgc
kcebrkj zmuf ueewxhi mgyepbr nleviqc dez
argavx fqguii gebohvw klnrq rkqnl goevhbw
ywqi abwi eswph nlplbl pswhe lnqx fpgk lllnpb
abpb mpkw ampey yapme xnuyj
tmuaq asd bhbs sqmbsnw wsbnqsm ydwdncn rpa vrllkh
dnltf cck djy ydj
wywwl scezo clowuz dkgqaj dohyzcp
diimshr vlmsnlj whqb dkicau ckdaiu terp kgcii npqc vvzrqzv nol
wfpxe sqf tbb ruqpcq zfgb
kajykuz tsxgtys vuz kglmgg ihnnn plyjxj rcrvo mij plyjxj jqiur
pxs hmet dwgvd mvhkvn cjxg yvid vmhnkv kwxz rfemsua wdgvd okixk
lzwxas ddtyeh ivyama crrhxdt hedytd jfw
vjfv oyd fvjv kfwlj mradbx mckseee xradmb
llga yytxyvj lstspek lstspek lstspek
fabgf wgop fabgf bvsfoaw
grqnbvo tntomdw hizg tmotdwn
mau ufkw cxfi rhehj ebe xyv rhehj acxngo arl qtl rhehj
kbkto stqjtm tpcwshj saerkrt pffj dthp pfjf axc gwmmfdw glnqtdy xmskw
veff zqm hzhxap lgwnwq twsdk mqz xbbarbv cdx fhnwt qjcji bbvbrxa
fjw eds hofskl nkbsv des hvx xyn
qzort qzort qesz rtq oonk vwzlw wapoj ifr cta
pja hvy nhjg paj smtfe fmtse
xvi tcjj xvkjtab nqftt aumijl xkd cmilegf hvsmodx uuo igmcelf mslkq
mdhezgv lelzy kzfvsqu hvmvaxw pxiqjc hvmvaxw kzfvsqu
hsicsav csshrhx znojm eapi lhmzq bbwnz seao gfk azk
pup xtgjyzy wqt ijeektl
ktwh qdegzs btj pfwzzho
xdkmdm izqtjrr iqbke vtp
fmrbpdr zpccv tmtwx tmtwx tmtwx bys
ehphfgq idd ehphfgq ehphfgq uphe hvrc jcscne nbnslqy
xzqucgj fcih fljk barz lvln hcfi azrb
cmfmclv mfgvifw rnxgn jpg bsnq wnduzj ymsdx smdxy pqomf
rlqsm qrsml emts qsmcowv scmvwqo
tshzkpa zwtpda ftsiwo nil tpawdz kjpa ptzashk
mnep sfc swjawtd vnwud gyulluw zpa kmwyvln evd btnmoi dnwe
jwq scepq redoxmw rbdzsa wlkzso kxpm bttg vxuc moxwdre ijtdd rzsabd
wpvo dsjox amuwjm pls lgwksva ctakgpl rmsjj lzwwpr zzm udg
bji obbn tmwyc afpmkxr glvrd kahhgpq rna qkxyntp vmd mloshc
ymq rtnr nxjzm pqiddrn qmy vgxw ull
mmzk ikge zhtzhs xyo qwe lll gjjm icetq qgrr mzwqa knec
kxomfck idlh xrbowo nyetbnl qskh xuwkkxe upmmmf zhvuyp
srcwyhl czgr xmhuws jueyh xcuib xhsuwm bxuic
crkueh beyxopz xpyozbe dxgadw qktmce rjropjg
lbktun imdpcp fkssp fhcpt fehho jqdnt aoewa
jmun pynzjo trs ijwcc pelf oft pcsqdxg zvql
mneaaq vjrg jidlrzz phd mvxpivd ldkhu
sao xqw nrukn gatkz quscpsx vmz oscoeb
goi wzxhb rrk aylqqcd mlcbvvf ororn heptid kdu byevr
qsj lsbieef deez vzwdx hez iwd
lmgfb keqt mqbsuis ogrr errbi xiqe xsszacp
ato hmk zfjaj kmh plxup cida dqd pfwh nkbxvpr buajw pxkrvnb
cli bdwu vrwott vowtrt grle
zisgks ciuaqr zvk tcb kvz ugmtv
oegrojm wofpwp gnaocx rweyull ellhwow dtefylf dqsz oiw varr bcirpf oxusz
oydkmib oydkmib yefts gbl gbl
sruwjk pgkrp kea gppkr zdcky cfljh
obpxbax jhpcrj slcsa lgd fborz vvpaus wsrpsws ifijuzo
rixz jwh uhdaf hoacv hdfua
kntk qprmfow kntk tbmcjx
vnqe ooyxtb ixl hdmnpn orpz ykspl xromvj kowtq wmho gquos
ynk xjjqw sut lmtub bmtlu zdo dztlk bpkuul smhpx rbczg
zals csdbe sbj dibicq kdfwwt
coyy pjddlfc lwvhyms ldjdcfp ryubz kfwst dqjrjja jtv jjjaqrd
jaexhms iqoiln ewgyr exmnrr fsr lgmyy fdofhn
pjgyn hfoz zbcnz nczbz
ovntivq vcey vdrkse giu ohyaxy ionyy fvpn yvwrgrv qta
yelpz htbk njgeyub tggh mdthzp fwyux rduqli twlhfp pnh gywif ttn
yxhsbil vplsmmx rgtq grsf lyibxhs hctnkfr awg lmloz jroy lpgb wga
kzytass szyksat tyskasz ehmhhu
jkus hwjv ymnnkk yffugg cvtnits gbl lywkn szihcn dbrbalf rxqpbqh
koyfcef wkom mwok qgjrytl
slmhry lcr slmhry lcr
mvoxbt cfkz purnsui xar ouhtc thbx
xcdifw kvvxyrj knac qmypw bou tmukqy eusgaoo bktiu
ablgnhb axumg bwpxnjp zqpc vtw ghhoxu zqpc znfpvl ghhoxu jlg ntdk
vmvc cdkhrx cvz rvxk mmcuo udpcayd lsmm gufduzt linj
mgyeqkv hqionh rgnqgz kkc qrgnzg egkmqyv topdp
koa dimwx gjxa atlfdy
uuez ueuz zeuu ezo daq
ofpaw bgomvmt mqa dexpy mbipd epyzcoa nuwrh vwly xppz qkjrleo rwhnu
wok grxk lchvtg plrzr lwaax cfeu ijapws dmkdwc cfeu
zkd hysxxip hlydw wicsvy gbwoaw dapre ktjn dzg uri
blzh hblz qgmjceg fyf
vkhpn xnc ogva pjrh cxn hkpnv
aja cldzta tdcazl lorr fwmxxh knilf ges tdhp gnlo vihrl
ucpr peair nlbmc msfg
trv ppq bmo xqd vbui yegsr xqxawu fvuz aclhspo wnan
loiq fvg kare rmgq hir rzo ossd ziw renh ygtkjys vda
xmans kio alexs ujekfl vvf ddghn
fcxvsf bjuytet zrzsobo uhn mlfzhlq bjefs
zys htlqvky plno pbcqfuf fjwc vshkxrl lonp lyzmy dqmui vyyc glad
tlc krhcter krhcter bolk tlc opryl
idcii dverl uswb wusb zgax zhbt gjsnlso yhs
cti npri rcbxjdw ollj nirp ghfvxzh
blyhug aflnrrz zudyw ccnstq cyoju jxtqoj ntuknjq gunjiwy ycuoj igac cqctns
bul yehpnw jifjrhc ifetu ufrodp hqzpeqf hdvpc qtvgxg ibb wcxsitx xztshb
xzct scetn eoaufyo jtudgkx xrpgxip lpubtq juezstc nuc hokswh obkf ipbu
nfq lwpmn qltal xnphsqs zlrgf iewtrtd mqzsob duokpy kfbqs icg
vil zjz xkqrvni uay ystq
terrrnt lnfg clm lbs ptpiy ybcuup ayzjm pqugx lmc yppit mbf
dtajh vqivg vnblt fmn qxkw stiwna pclrrr fro khu wbslnqp tjyosu
uqlehn tjuiy obt uedct bbwiq uxndqn
hiqfovy xiimca zwne ivunvjk cmctzi mxnnrx dclib xzaoq ieztkg
shpr xuorihj chuwq poadbo mhtvex gymsp iltgl sypjfua fmyh sgiv
alv nxjt txnj bhact
vjvtrex obmrxk fgigs meixbc fggsi awi rxdjpeg
ypwo oicmbdw xbpeeyj uabzj cjvutvc oicmbdw immtmks
exijri hogl epr gzdqyur xiiejr pre ihzlgzu
rlh qfhx lrh qmvrx
kogq okhd mivmivb mivmivb okhd
taekt nhjaa znbaahn iaospxy jawwf
ytdvq ghtqwud jkiig mre kzmmjxu jba nwpykc
ktyzr aczd exgadhb uinrgac izazxky yyfe
yrifb qgc lsiuapg teyelxn ugezu
wdzkc ltx fkhncb hwrecp kfbchn sfcpc hjvq
rjdjyt ahwxh nvggsmx lmz oshd xbcik powse ahhxw yhiq gxmgsnv
qdr qjnam gag qjamn kooek mqnaj
pza gml opf ilfbblu kjp luilbfb rhfrzgp ixagj ofp
yphz runy dhull bozcsgk wfxekrd akgkbz urcphc
tfyxwol lhcl npik beug
szatel yfkve yfkve lzqhs
yjzqon pcjibu bdncmcl kczuymm pbmg nyn
rerqvs aoxucwi pmstl sstawu joqu abvcchg mvgjn mslpt vhmfkr utusuh
gqbec jjpqdh yeaiavi nledfi jhzwc vyxjpf momnm vnknjs nvgjzik ipm
psirt rispt lrkgma irtsp
jbbaph xvunete gsvnr mjd ifxhpry cpsx hmuokkx vhcm yth shrrl zbhd
gfa bcmlxtf sqyanrp cugg qxfvftz pbl ujsgc jajxltm gugc oil
xjuhyg aht vmyvzhh oby oyb ybo xbybgmx
atfk qjudfzz mky tfy
nxk yzy jqgg qxgjt bevvvv efi xcbw bohc zaqlqjq
hdc qpnx ygmtqw acvoa udboxw dhc klh mwgpk xfpuri
cycgbkq skwhyf skwhyf veaqss skwhyf
jnezf jowjt vsdu uck scgxd fvopomz vfajslp
djvi epgkyqn apzd cpm owm kpwih fsr adlhqu jicp pmc
erxlmhj wqxvofi ugj ttrmtsb
omku vmrgoy tdicbje ewml dfnwbap
gpih pyt ptsmzc gmdbu rqxkqmz objm nurxjz oozbere ztxug koth
jpnl jpnl dmeh qed
intdwv ksgw qwlzhq zpd lrl mwjl dozrjwq aujbet bsnf vhqyg
eqs uot qyz xor aem kmrh mrhk jqx tsbrf
irytjab mdzm qbb kkjt gofiwo xgbovg kyeyxqn tcks tljhx
zgejy qodgah nqavvx xnigdvt
eqve bizrxq lkhz yzwxgt nwe zfe sxypkz xnssept
bxqn lkfg yfxbszo sphwifz wnj crhbq dvokzw
vzn afatwye ogzvnu vnz rfjba xtugnj kpbgly ocsjd
xrc cxr rahv yvhk khyv bed ctgbuq cmqwpqa jlbg hpj vmesvw
jbshkya dgqw lfl mzcch jxsg czcmh ifruvlw ufwrlvi xcczlol cqqchmr
rbk mhn tnmqdc sxnnn kvoa mhn sxnnn mgemob ieiyajs
cqi ghxg ghxg ghxg
uqwdxn qli gdtkngp gnptdgk udxqwn
dmcczr dnjaqc qwdta rhrbi hkdwe qdjcan peic iulaz xns
tcmppb nzq ecy sitdud nft ecy afrbf wvnc vmfpzx tcmppb cgb
plitv efnpq mjqav nrxxo izg lpitv rwbzdo rdbzwo
day dntga adtng agndt hhvtd
yrg iudsh gyr ryg
qttyeew tco flq bszw jkzftc wdh efcwnp mja rfmju
moch prkze uslzyv plhjuy kxczyq qlmm hgq
xtg ypz izy ixg bvs xlqgj xcy sepza abiylsg
wxvsxn bqag jnlzgxq ikxwa dfd plqxl xlgqnjz nuqvoyb emhodso gaqb
bzjdsm xmxkj fhuqn gauyw ntl kjxmx zcxdr vrds
ofjcc uxyzlk ofjcc ofjcc
zwosex kkvwobl cpudsmb kes zklf bayuojr otqnyr udbbs
iqpvzh ybds piovrh oivprh voprih pov sfl
upns cpeelht xboyk itb hsxdmt dnwgfbw upns fygf kwdpxzm mli dyy
djwutl sikh shki ikhs gecd jqkon trqyw
prbbdf vdp bvvfjcg ydqb muxygg
vhpurzn psemqe xwqfk hrvonxu nxkxacq
xicmhss tnpja qiad woipfy uvadcq usljh hzgs jntvfv wzikk
mmupc twntp upcmm pumcm
qnisuzy lppnfd uiqr eyqbain uxlp eyrfwjo olgkrps sbikam zin vckr
nmokl skfni jcdfot njzqeaj nqzjjea
slmaxx offfzqp wudicrf nfn rwfcdui cwirufd
paffi murnjd oyj lbtjdqe babuas dtqh qkt stapzl yrqlp
eedc rig zmnfmn edec ecde
bcfdf edovdj lacx nzvze sordvxj ybs ujh zvvvp rzstejg ueosuq
xrrfsd okuvem znzlvmb jwzcb bfg bmuxbc qzwfry
pqgxybd cvgra acgn ocd ancg fvfcx fbb bfb zfzv
tmmv mpywyg fwl bnvcv lcnv flw
xxnfbro papc ianru beuzx apcp rnt
wuyhycj nrnc cka ebg rncn rvo wcyhjuy
thh cmoog hwf imqfp okzpxd
rzxiqt rtaiy ytria tyria
cjkmro myif myif xyirn aqxlol wlhwibi dhzsen pzwgm bfbz bufjs qwffg
mxhiui umiihx zomyll vfieccs
yyntf rjk iivgj mwh rjk
dsshx wsmaxhc xcwuelh rdsgtr wsmaxhc rgtsfj
rdh nwlxiwu xsjzbpr bsgps
ufyo vqtzkg kpeohu mxzt fyuo gawgaq youf
hzbhut bxsnjwb zuhhbt zhhtbu
pdz sgntypg ragev hrrji goitft yphnebs xjzoo sqf jsuzijq dsocb hcxg
pptsq woomypc woomypc woomypc
axcg wfbnpql ejqb cmnn nncm csvlc wraludb pkmp whtht tfpicer
moom oomm ommo vfqeii
xvrgpp rofl yxyrkb oage nypzau pwfnkn jxnhkw cyxsi clzb adwpuh
mfbz vdtt muzhm wvwwfl ttdv
cpqgvbu byc pgfrlkr aftl tqm zcqxi juu gnf ppovxh huoa
konpcp lzordid jqng lwxs nqgj gghkxmf kyn ngqj
iorhccj xfygc cnfr tysqc xpcyf vmjpitf nut zmrk mgbrtb tcblxwf dkadwrm
kov jtmp xoatesx qxkilp rmggpfx ltpxzwf vko reqms mqq nps
hjigmk fyqy wpuwe mwmso thsimfs okcmeyh mzqkez duzaq vzhyrm uyvpkox cwivpls
ukoerf korufe zhs ntwfz hugem vriyk enfaib hrrcdgf zllsk vkiyr
shkx khxs wntpjv qdevaw noqyht nwpvjt egh hgok mukdjfi law bzbvjz
dquk kczxsq tdu trnkjs wqtdc ybvcb
hlrotxn cumcjkm qwufgle ylm nejh hnje pvaigrx myl sfvsd
szmvisn aywic vsnimsz iufmybr
zjozr zojzr qmn ffrggdh wam dafvok
nxkvlhr posmf posmf posmf zhlzb
ywis kpqpyb qae zqxpuz pcj hbsfz ejlwa lajew znuom
qxsl ussivur dstd avojo
yoeagao egpaqm ymzf kkauy ivm illir wsvchne skmamvn nqxc
cldo ixzzy vhk nra zhypgab
qjdd ecxud tbuqq mpotbdk tjdpczn knncm tyy
rbfc fhhjf innia tsjbbbv fmtcuup rapvhqz ebpzt whdbms gvjoy lykl fquvcby
bihhfwi lhal udxz uwjwp dmb
fekxamy uophet yzvv rqj zawlp ldrv mdymkzy taauf
rcwxvmh edueui ltdyo xfghz dgjig senm ifj
qcu fii axmgijj ifi oixjfsg jxagijm
sdtyr rbdh yvnvq czzuig wro
lot xkto cmpiena nht ozcg aotcw xiegl cyaouj und lsclep cexn
pgihljk cmgmv sajhi zfvbqij ogwoc ajsih zmppe
jexwkdp dwpexjk mzjydfu bff rubgdb
yshfhx emkl hshxyf mkle
dxgti jdo tkwprv pbxbrqd oiz gsbdphd qotu utfdnq tzvve bqc
ovdf bshfxyl xspjpd vljdsm mgkd djlsvm mlsjdv
etyia eytai sfq qafj xzgp ewhsn snwhe lhqp
zjz mwh dorxm ges gexo rckwsa dltoq mmntha
hqkuj ypsjcxo dixbe rmvnhjh ovnr
edc iffaxc lolu xwrvpb gva vti vit
ceuxq xbwejr lzyvm rozseit cwe mham fivpwj qtv omaktaw
alzdrk tsxbuld mdbq pgbdtoo xwf vzalric nqe jqwlxsy cbtylu dtubxsl lqm
rqjmjcs exjpn kpilcgu ihcm lfadjm mlri hpd vqs cxqwqhu twxrtk
aeuvlcp aubvnw riedvz arypagp uuvg kliehx cokt ogh xsdw cdsyywv
ddwrgvp bscaq bbfv qrbutp
jpdg uey eyu uyarl zgbk qyhqq fdvlql zmwkp
kbt bkt lebhpfu smrzt xalw mmwa zmtzfry tkb
fcvcv oewfzu fvvcc mldww lwdmw
ejrltsu sqoyx wfvsdbp bfdspvw bfir jqhgrmt ofdmrjg ysq
jzwucwn erqjd eikq knpf cvk xvqnscy eei wvfjzmj xujq cqaim boev
jqhkmr ipjpj zwno ybu krhqjm zqfyyzb dyciy
ugwsw rpwteje qtvwi pwyhrzt hfcdfmc qbovk ibws
ffy kdder qjookz bfvmvvq yjzuaj fvxllfb pjyz jcezhye fimyydt qjookz qjookz
loupd nwsc yytvuqo ltcqxnf
iho ulvxguz fxbf iqu ofjtmvq xhs ybbusd kxg mebdnah ucttcf zufb
wzdb wumuhtv kef aavv buu xmjtlur faaccl wospwff bjasr eapfsi
jau qzszci ciu inagax
kui tqig fyovsp fvwol fyovsp mzth tcp nhoq
ajdla wtpj amylu jly tvq wjqef
ofqc einz bdze tows bdze eew
avwavzt aesrsjv lbmpi hllv chdbul ezelxn
imcprs cafb clfg rsjo iylqu nvk vkrq izezlnu vkqr tyhnv
rwj zboui reh buzio wuhpvid cpzy jrw tsbuiby hmxwqr ute
ixq luwbi uoiwsjh souz ysoubw uilbw ffwjvw ewzswoh hci zmfdaov whowzse
xrhgqf xrhgqf giyv giyv
toiqgzv gakg udgdlb wvi carrn pjyha muqclu
wuxthi srtszr ourab hpds bakvy fnk yefe yfee doowxcx
ijdc ujhvls xmy hwg yetsda qelbe nang xgywo wgh
bhm icq cnam dec enksf qfctz pwxoo bdf cnma xoowp rbls
jguzh fextz yax kesaunn waljo jltcza tfzxe dezs syi ebwxnks
flvq bzgd clvqw ahtyvu xbdyv wssxx boscm grgl nqcg
caskpli hqctxxc nwpyo wjlqfqf ebti dva
wmsz fzpd ikgeq gti ejftoou ezs cqef mybojc rgwz
mdaay yfppa pavl fuuvfkh hpod tpb dhxmia emdecm rbqcwbk vecyt
neha rmvl ndp vlrm dpn debghi vyhvc
bnp zkxdu iqqkesd abtlx hmjasdq kyvekr krt srrjyd oxmfev oot
dumlcqd ccm hyir oritdz madjjw
oakqrs advfmu verrc zkfdcn btndsp
onlkinl rdtm bscfxre bnu oumyrvv kgc zkj
tfxfsgm uwmic agswclg uofezgc
wpfdyjn kjlihk etbot fbu scm gwccce xgownte wig cuaijbo
bzbdk etozk qracb oftfoo lkooe
xupzw vmxwu sis wzpxu
gbz oqbgh jwgrru bzg kwmxcfc jrurgw
agyjnyc tuec imxlult omwiyjg fiwnoqx nhmnro qtg kbr agyjnyc
koiq llreotu elrtoul dubfvgy whq
htm lll crzppb gdjaae nsmxzh gnfvn obiuy ymspzbo iuboy
thm xlfrr pbxdfo mht tygi sapxgbv mmngzf dej
eus seu qmstw ues
yvfsw esut biblze kbjcpk estu xih qzki ezlbbi blzv
ohq ugc tqqeo jygvpwm vfs ldnfibp ycbpa sml rmime
kuuow gbg nzwdaf wiimtg lam oqmm
wsbwkdd hda nqk ticz mvt
gqbljyh zqugqs cjod sxwlqy qkfs wwvwvt dsojb qbhjlgy riusoa uosari
jkphfx dbt les jsvoij rnuw mxmmchu dol vto swn
qqxe vwvephr twdqlyg cvdu xjiych clooq vkwavl whvverp yuz vkwval
txtbudi tiutdbx wqhx tws utgbf amh hmf izsez ooz
egdube nhsxjs nxjshs xoy sjsxnh
egdziod diodegz ejxn zogedid uhhkr rnm cyvvuc uqbl
rbn pinwag sidwdwv jqdbe jlbemk blkeaqq ipfqbtn zkrbp
bdryz sbh wxvn mhot wemsfm oemkff
vxyn xvdwwo xhd vyca zxjaw vfkz xhg ofsphks dyq mmzzd
yjrqsjf iiesdh envwyx rmtbmiv ggzsg ukx bprfym qmyqc vag ymho hjtoh
fuxxrd wbweptd vkoffr wbweptd
gfwcez smetli yjyh pslpz qyokpsm qsy cxjymg wqfkf obuq awz
eqhm ceest kayf heqm
rdi dti vntcf ewkmpvf jjwoihc
sfq qlb xrm ocy vtnj zdznbal zvon stln zwnj wsgalvq vhphap
pya jay mgnyo pya xmapdn
hrwbj xhr gvwl ktq ktq gvwl
rzgqi hjwtthl kxhggbl wepc hgavj ctmqug
tzfwkc xeqfath iiuwq iiuwq dhwuvy
gibagy smq getjofc lum msq ulm xuxu bilrus ily
xlv ndrkch hdcknr nqltoze xvl
wmc vuzlrj mwc atp cvpx atv ujatz
hxpafgl ymjltv nvvpy ahycdk jhpdcks ettm lvqyw ertpivm dnezwxx usi kdhcay
vrh hqyomv mcq ilwjbkz yprjxad
ugv szfitxg zeluib pfj ijm zmiigxx gltxzz jzljhgh otskue
mxp bilj jlbi tce yfted zxsqas ftyed
ykasqv ehye kirmnl upmi dojwmw wzj ykasqv ifixn vreoypz
kerbgub nnroqk onkqnr gbebkur tjhl knjo ccsem yozvrcg
ygq evkoj wkn ffljhds scxeibh egsybeg mwvi vgjblj qda ywqpp
hocvpl ozgkxp xgmj ejzyxm
gernu kks lxe nxzv sypg xle goz
xoatis fjp wzlbo dzkonz jtutyj vdonj swro tqclemv xhomap ymeqkua vaxcw
mxcyjs ywyxndk wng vpftv nsuvu
jmiyyhh gwser shgcu jmyg cjzegc hmhe eopg kmkan
smdd dmds mgqhtkh qtamih haqmit skkcy
dnj rmggy rgymg uburbao rymgg
klcpjgq ons ajyv sqryt son pjlcgkq xlobdt
piw shonk tzi mcdumz noskh tebolw yaypn
ozm mvmjgtg nxj weommiq asnmhzq xjn uobztuo cqgjh utfb oydt ommiewq
qlwgsc vvpe xgft ahpjc zjtx iyof scwqlg dxgcokx ltrefj xyzq rwto
ggqdd dqgdg ggdqd kjkmmfp
htzjam fjbg iagc xls iagc iydtf ihxl boa iydtf
vhe nqj bwgdoi hhaoa qtulz
axvyja hpdkwee hnryj prou rgadv oubjdqg knjbc
caz xibj wqkzwe peioeya vmz hesy ftb
dudwcr gupj sjrtzc xsqbb hiet nujv bebcvsj eks uuzlcx gex
kywozi tfzuc mflssw hnxxxqt zzc tzfuc hkokuv mnjg lwkavjp lvpwjak xez
izgh zfv cingjt dkf cknite qox vfz zvf
ojpu dzk tehpgnt gntpteh
glxfxa uxq ajtles ahgzn ajlste zwgc mrpu adz wuunwhc zda
hdgdtn hnoyz aromkb qujfv yjgmn tbf atw
uyvsv oaopjv uyvemxk ldpp tthe iisjk txr hebmd yxevukm rkziao znt
ypdr mnwuzvw acpg kzwz ywbn wcrr umrnlbe lkult ljify azyhu mgqoo
abmpl omsd xmyl mxyl mgoq kracrf ufm ppwi zpggh
uxfdpv jnm vvc vchunhl ubv ktj mxolsxz
fcja eci edzrb nlvksaw lhf ycohh tfztt xso ceub tyv
rkwtp tcmmvv kufg cxui hdamg suuaej fgku cvjlv
oldbgy riadoyo djsi wca zxoeq pmemqap aijxa
nyy ruxcosx xisqoz yny jvzfpbe tlfdiaj ybd jifatdl zuzv
kxwdz qvrvx svllp ergmme
swjfuv eronk favcxfm acptbh pnbjn ciqcrlt rgvdnlt icgahb
ddza xxfn use obqka bfzwjp gmf bld fyvde mxdfdl
ame bmxbyf ame bmxbyf
rdgby pyfog dybrg gdryb lpztd
sntg impd uxgxai naoalb ntnk xgix
oadpmqj oso criln izih oos
ouzjq gtl ito xefqt phnv ouzjq hoyjjj
mlp rboq lpm roqb whvp
tghcw ggshevw dzsgj ggshevw kec ggshevw
kmwhb kfcb mbhkw gemz fdh
euve veue kplrq evue
hikfiw bcdktj hcnawja gjasvwc vcht igrzly rkxijxe ikfwhi dvmp
hvksis kafs ktcs sfyqzyt etctrgt vodwr wff tskc juobnm
dpcsodn ehwc pglywfl yhdp mdiyzx
ibog umftejh cfm pnxhna wqwx yabnk ygws dqw
dezz tqw qism rarfe fpmlab xvbau irwtfs wwmoyss yvn xetqp xtqep
pchqwk npsmd jefec qok uuc ucnpz rlkakn
kudh rjysb xrdbx bkbmjfo xrdbx
rogu ssdwsus voa ncw obkxsr
tflf hlevus scq rrbpat tau wxsq wxoblt
rzr lex kqdy whtj ffnys xlgkkff msjhy dimaq hrc wyde qkwf
ghtwd wernjpn tdgwh olrfvmr edq gxvp
rjirvf skhdgln aauit bipu mubjiwp kowz gyjfbjx cmgdqs
aftfpbv agajyy aqjll vsf twh robpys lebt eav yribup
sby ymkla sxkbfwl awmd nhb vlp
kizvjj ycjswr jkzjiv vuy jijzkv jcs
cwvch xzqfal tephz lqfzax cnkbdcr mql zflaxq
jjxzwl himpra ssjf bibfiui seeaq pzse
jogrn jogrn sqew jogrn oixgwr
khonpyw iiyxir vybhc ndnxxv kzlt ipmncn
okqkqu svbemi nfn ovd xgwy edd ujet nrrbv dde vdo
jobvf dus asvio vaosi sovia
knmz qbz nkmz zmkn
isbmopr unduey impobrs hea zswciev sopbmri duuj
ocs ntgnrdu kbvtzp cvyieu fiyn znmh lhrz ixtnzrj vktbpz lbpqx vzkpbt
muduhc sabc dlyoisz kuaz ogpyepw yuog ictiiqt
xjflsf nfklvml thfh uajnmby cichyj xxoqi lpime bxpyx
riahifn bohbgd obhdgb jni qzvkf ybp hjkkwq ytutd cakcsh smfdoe tuytd
iddku nccp zgtl yne ppzpqcx lwm
refpcz uqt uqt uqt
mtn czxkagb nmt caqacrg bcakxgz
itxjii uethxbj vpds bsqod diqax inv zrwt doepe
bfyaj nbvhg zmi buf
dtre dkwdr nrapm qtfth odvt bbcnae vxuk gqm enlg
ybt qcfozrk yzrh bfp euuozuz pzsdkxx mhi nbkzprb
vpuhqn gyx caint antci vfep incat kqdakdx
ddhi chgnjk ibg xbemitr mjtdph eovw
ngbtuvq qdttlsg dbqhhwk bkrqze qdttlsg qdttlsg
evn smvhi dgcmn xjo ascc ahbpj uvzc pwn tung
ksu thr omg onvsqzz rllakar ysfjtfj grxwyx oawix gpk suk
qvb iouav yhtndkd vuoia ouaiv
kud kofcip hcczrgc cvvxxlk rvyamwe duthdzr dftun
rgv ynw gph tmxwfup nwy
dnc trawj kwzbx trawj zvp
ogqxijy tbqtsg tbo vqinnlq jbvgl sfafh rve mcxqs ubh
qccr lpv puuvdyb tydaflf uxic
tlon tbfwkxg tlon tlon
iytiz qjlqaqw uixb lnt zwro uzgxqfi gklgnqs zwgoidw iifk wkwdo
tmvhxw tmvhxw tmvhxw fhiqpjy ejk kvysd
cmphg xjjz groiccd dvetuk xbwa zhm lyi ohhd neg bxaw yil
kdmzopy lxx bvhach goxmxu qbqvzcm qbbrhvb nrfom aixmio grpxz hbrqbbv lkucih
bnqn phqr uycuxc mopyyfh bbpesqm stgigq stggqi cwtjm asqhpl imvlxj lbmloo
pws iuvbvjr cwccm qbr srqnstz cjebq
bfh jobkcy gtbroe lpagq icmax jobyck fbh
ounqdo qrrr pwi alho rrqr beao rsioepe
vrccqge qvcgrce cbslkjs qnclw rvmjkw
aaxjns deupjs wtgxtp penad depbho tbrdt depbho qxg zhjxpgd
drqfo kbp jfa jaf
izn oczcitj cpae quvzqo iwwk jck idjdpm
ecort zgcvxx bvh vrprsf
fhubfvy ndcfjo kol hyufbfv hvpka
kpt zgajpc rjvsxa gayznjd
xeoixk peq kfu lqa mjnv mzvh bicl hlfk
wyt imdx lksy twy
xeptp ilxs qbsqzwn rsy slxi xtpep dsdkekl
rotvbt fuirp elos ciu nhx bxej trmtx ixn xbpc vrxtma
skcprn yns sao ghlq vftezvc aaryahy telt
fkaov gexa xijv yiksa xega dhgw okfva gxxs edkecag mqbqvrm nrzcqub
ljc jujxeof fdj gdzjzr mabbktu pmyrfv uspven zxry snt hrah
nhujhdr jdhrnuh midm bbavhpp cpjk zmpbasz eptrpou znq zqn
ywzfq wuu lfflon uuw rke qzwyf hjbms gakx
yqrq zsk jzn uuuzrml kzs lseupsg waynfh blech
gwyqej weyjqg uwuje uujwe
lxud rnwkc bgygkh csq rfvtos ystqp keb gkakodj uthcce eqxifl
elvj evj rfwo vvgkosh aarcgjs utsbh orwf jxcqvmh uowmktl qtgf
bqszre oxntty ombwiz mbiwzo
ccp iilcc tacf czk giwv erqi jgdfah wip xtrzhv wosvbyb
gymyw rwsxeg gvydr izyk spsonkg knospsg
djj tbr tbr tbr ice
yyzh zkykapw puydtik ysxc hjumhsd cuhhw dnnhida yyzh lnklymg
nhbcxsu ccrbbyw scbxunh ghxrkqh brcwcyb
latdaav sexa ipzuzjl ayusb etb fshh
giz akqd vjmabii arfuzgv efrww jxkvolg efrww vrnzgbx
jmcc vqy adkzj fqrkdo tjrczp ccmj cfponk rptzjc
jsviu sraw imsj fujm cdf xwqhl lhz ojejzuy trtqblg
ibz dulm muoq quom etvjzxn tuhrpp jfukac jqctqn qhgbae msgmcit ludm
zgx bpfa elhp rnyqtq wyceube nkeuxz
lzxfo vygpecv jszacku zfxlo
cpmv ysaaj xnp wbvqg hrsiuj venjxna yeqvwmk ftaga dcqxc jgapb rqdixp
xpbbe tyn hfdlu fto wrgzkou sxylv cqto wdv xqc pnu rapk
pkrxypl wnu oipq tzbhnc gpug tgzf ofjb
mvaz bwcv gll itgcye dessw szt gzimgeu bvmohh wbywyhc kzerxbr anjsive
lhvnrzs qkmjwy pnyciwp mgp jfdz ghvtf yusfzg upab
xbscukx aubulj snbcmc uscxkbx ddpucyg
hgv ollh yzpjmpy fcicyae vhg gvh
prd onyd iux oik xui
zipadig nvewx cir lbpcusx dljqy
ifyxzsc btmy lsu tmyb lus ldyzx
egmyxbe ieasvek dylmj qahtatr uyqgbk
mejjczw spj vaekp kdud
vwan mgenld mnlged vpfuil euoxlr rclkpi dfknyoa rhthij kcyxl qaxab crlpik
pqm eihogk iwml nuauxi ngilkoh jmu mbdi cqxz nblb rmuj zczdgp
pswbe mtzch wbeps fxtnc psa aioff pas
prwrpvz oadpqvz tgzrt giom pjyihh rxdir dmya xjolzxv
khdybe obqkjn kdq jkvmgwo enpat wyw qjbnko waid msest wwkoyts
yep liv ofmtpod imdd qyw
afnrx jgn gxarpb myltj ggrsajy mdaobjo vbtn vbtn zlziz eds
hqr kqu oub skoeqk icnfm cqvld aay bto
rga odaf exoosh pwevx zpbd plaa xoseoh
mbr gqu oxvchrt nqa larxmjx pfozej
ozuo ywubjbg xcua eblwqp nfdvw hmhen zkjfu gmhgp bsyi ktprtf
src vrysby srybvy znwjm hmypwdl gdmau pqe
cldr crhi lbaq fbuduyn hygbz uhida
qrxukq dygkp oaks soka oask
vpido ajgfq pwlv hezt fmg epwrxo rqvjke iovpd hhkjm
anxf ydl xnfa hqph olorp
exydcg onxjm psqlbv ehz boar hze qsblpv
mnzrvc ipj swg ijp sgw gdkntsd fzz grqwly
erpq qghpj fay gci uglm afy
jwbq hbxaub jpdilyt yvalrlk topl qup
eczonk ftcc paltirb owz tihhe dglxory wthvqcb qdnxm lirejh alyxsr
ooruaby gboyeu lkv arrz jcqyzl uxlfk fhmeony fcmh
wzr xjb pwmf okqj adwcedy lkidve uwekxf asbdzr biub
dikhur pxgh urdinjh wednf ulzdxs
iplf byt tyt qnnlba pzt bednml ljjtkvo tjovlkj uwms xat
htzk ltmfha xikeze atfmhl fchxhyz
lqala bqwgcul vetaa xuxjau zcb wtdmomu wfqmpq sief uyblyz ahv
aytvvo awm ojaaigg awm dbfaokz
abq npcyld fzbfku oia qss jkxldm wgtmki pasgxi dieix rpqnuac tecnfy
nmr qzfj qjfz lsz vnahex
djxoo jzlkh svy xige
tjlkkg glcuvmh fwzlhi ecun qlgulj hrfhyql qgdlf ofakqdf zokkvm gelxkq oowgs
upfpk gfstjlv lxc rjd nhj sbq jpzsz zsjzp
favd nzqfdid nekfjsf mtjndu
sgdqx uvpuefv vhwrgd aivav gsqxd jdhfoq
llaf cthbgy njrpw fqgkx jzf xqkgf lnrfrm gkxqf
wzdwlc wisst alw kyjeur sjsqfcr tta bijnyn whfyoxl
dtjr baxkj lmnyrlg nrmyllg
mtgky xmwf zdko nnocxye gytkm ygp hixk xwmf
maudjy okgjga uadjmy dzfrk omd
azz ajdcqkd bcafn zaz dcjaqdk gylyzo
xzvfbf fopmfxu mvftgr mfupoxf coyhof talcc vpkslo

23
2017/d04/ex2/ex2.py Executable file
View file

@ -0,0 +1,23 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[list[str]]:
return [line.split() for line in input.splitlines()]
def validate_passphrase(passphrase: list[str]) -> bool:
return len(set("".join(sorted(w)) for w in passphrase)) == len(passphrase)
passphrases = parse(input)
return sum(map(validate_passphrase, passphrases))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

512
2017/d04/ex2/input Normal file
View file

@ -0,0 +1,512 @@
vxjtwn vjnxtw sxibvv mmws wjvtxn icawnd rprh
fhaa qwy vqbq gsswej lxr yzl wakcige mwjrl
bhnlow huqa gtbjc gvj wrkyr jgvmhj bgs umo ikbpdto
drczdf bglmf gsx flcf ojpj kzrwrho owbkl dgrnv bggjevc
ndncqdl lncaugj mfa lncaugj skt pkssyen rsb npjzf
kdd itdyhe pvljizn cgi
jgy pyhuq eecb phwkyl oeftyu pyhuq hecxgti tpadffm jgy
zvc qdk mlmyj kybbh lgbb fvfzcer frmaxa yzgw podt dbycoii afj
zfr msn mns leqem frz
golnm ltizhd dvwv xrizqhd omegnez nan yqajse lgef
gbej rvek aehiz bgje
yej cphl jtp swe axhljo ddwk obwsq mnewiwu klddd
ipiev henods rpn qfpg gjfdgs zcpt sswab eosdhn teeil
gzje ydu oiu jzge udy sqjeoo olxej
mgn gox tcifta vzc lxry gox gox mvila qdl jipjnw dvu
hxk xhk unhdmdz yomze povrt nbww bxu qqsqc rvuk tgffy twddm
fyx fyx nzkm fyx
ymnoc zogudq yncom tqrob sidvy dfuu ccjpiej yidvs
bxebny akknwxw jeyxqvj syl cedps akknwxw akknwxw zpvnf kuoon pnkejn wqjgc
kcebrkj zmuf ueewxhi mgyepbr nleviqc dez
argavx fqguii gebohvw klnrq rkqnl goevhbw
ywqi abwi eswph nlplbl pswhe lnqx fpgk lllnpb
abpb mpkw ampey yapme xnuyj
tmuaq asd bhbs sqmbsnw wsbnqsm ydwdncn rpa vrllkh
dnltf cck djy ydj
wywwl scezo clowuz dkgqaj dohyzcp
diimshr vlmsnlj whqb dkicau ckdaiu terp kgcii npqc vvzrqzv nol
wfpxe sqf tbb ruqpcq zfgb
kajykuz tsxgtys vuz kglmgg ihnnn plyjxj rcrvo mij plyjxj jqiur
pxs hmet dwgvd mvhkvn cjxg yvid vmhnkv kwxz rfemsua wdgvd okixk
lzwxas ddtyeh ivyama crrhxdt hedytd jfw
vjfv oyd fvjv kfwlj mradbx mckseee xradmb
llga yytxyvj lstspek lstspek lstspek
fabgf wgop fabgf bvsfoaw
grqnbvo tntomdw hizg tmotdwn
mau ufkw cxfi rhehj ebe xyv rhehj acxngo arl qtl rhehj
kbkto stqjtm tpcwshj saerkrt pffj dthp pfjf axc gwmmfdw glnqtdy xmskw
veff zqm hzhxap lgwnwq twsdk mqz xbbarbv cdx fhnwt qjcji bbvbrxa
fjw eds hofskl nkbsv des hvx xyn
qzort qzort qesz rtq oonk vwzlw wapoj ifr cta
pja hvy nhjg paj smtfe fmtse
xvi tcjj xvkjtab nqftt aumijl xkd cmilegf hvsmodx uuo igmcelf mslkq
mdhezgv lelzy kzfvsqu hvmvaxw pxiqjc hvmvaxw kzfvsqu
hsicsav csshrhx znojm eapi lhmzq bbwnz seao gfk azk
pup xtgjyzy wqt ijeektl
ktwh qdegzs btj pfwzzho
xdkmdm izqtjrr iqbke vtp
fmrbpdr zpccv tmtwx tmtwx tmtwx bys
ehphfgq idd ehphfgq ehphfgq uphe hvrc jcscne nbnslqy
xzqucgj fcih fljk barz lvln hcfi azrb
cmfmclv mfgvifw rnxgn jpg bsnq wnduzj ymsdx smdxy pqomf
rlqsm qrsml emts qsmcowv scmvwqo
tshzkpa zwtpda ftsiwo nil tpawdz kjpa ptzashk
mnep sfc swjawtd vnwud gyulluw zpa kmwyvln evd btnmoi dnwe
jwq scepq redoxmw rbdzsa wlkzso kxpm bttg vxuc moxwdre ijtdd rzsabd
wpvo dsjox amuwjm pls lgwksva ctakgpl rmsjj lzwwpr zzm udg
bji obbn tmwyc afpmkxr glvrd kahhgpq rna qkxyntp vmd mloshc
ymq rtnr nxjzm pqiddrn qmy vgxw ull
mmzk ikge zhtzhs xyo qwe lll gjjm icetq qgrr mzwqa knec
kxomfck idlh xrbowo nyetbnl qskh xuwkkxe upmmmf zhvuyp
srcwyhl czgr xmhuws jueyh xcuib xhsuwm bxuic
crkueh beyxopz xpyozbe dxgadw qktmce rjropjg
lbktun imdpcp fkssp fhcpt fehho jqdnt aoewa
jmun pynzjo trs ijwcc pelf oft pcsqdxg zvql
mneaaq vjrg jidlrzz phd mvxpivd ldkhu
sao xqw nrukn gatkz quscpsx vmz oscoeb
goi wzxhb rrk aylqqcd mlcbvvf ororn heptid kdu byevr
qsj lsbieef deez vzwdx hez iwd
lmgfb keqt mqbsuis ogrr errbi xiqe xsszacp
ato hmk zfjaj kmh plxup cida dqd pfwh nkbxvpr buajw pxkrvnb
cli bdwu vrwott vowtrt grle
zisgks ciuaqr zvk tcb kvz ugmtv
oegrojm wofpwp gnaocx rweyull ellhwow dtefylf dqsz oiw varr bcirpf oxusz
oydkmib oydkmib yefts gbl gbl
sruwjk pgkrp kea gppkr zdcky cfljh
obpxbax jhpcrj slcsa lgd fborz vvpaus wsrpsws ifijuzo
rixz jwh uhdaf hoacv hdfua
kntk qprmfow kntk tbmcjx
vnqe ooyxtb ixl hdmnpn orpz ykspl xromvj kowtq wmho gquos
ynk xjjqw sut lmtub bmtlu zdo dztlk bpkuul smhpx rbczg
zals csdbe sbj dibicq kdfwwt
coyy pjddlfc lwvhyms ldjdcfp ryubz kfwst dqjrjja jtv jjjaqrd
jaexhms iqoiln ewgyr exmnrr fsr lgmyy fdofhn
pjgyn hfoz zbcnz nczbz
ovntivq vcey vdrkse giu ohyaxy ionyy fvpn yvwrgrv qta
yelpz htbk njgeyub tggh mdthzp fwyux rduqli twlhfp pnh gywif ttn
yxhsbil vplsmmx rgtq grsf lyibxhs hctnkfr awg lmloz jroy lpgb wga
kzytass szyksat tyskasz ehmhhu
jkus hwjv ymnnkk yffugg cvtnits gbl lywkn szihcn dbrbalf rxqpbqh
koyfcef wkom mwok qgjrytl
slmhry lcr slmhry lcr
mvoxbt cfkz purnsui xar ouhtc thbx
xcdifw kvvxyrj knac qmypw bou tmukqy eusgaoo bktiu
ablgnhb axumg bwpxnjp zqpc vtw ghhoxu zqpc znfpvl ghhoxu jlg ntdk
vmvc cdkhrx cvz rvxk mmcuo udpcayd lsmm gufduzt linj
mgyeqkv hqionh rgnqgz kkc qrgnzg egkmqyv topdp
koa dimwx gjxa atlfdy
uuez ueuz zeuu ezo daq
ofpaw bgomvmt mqa dexpy mbipd epyzcoa nuwrh vwly xppz qkjrleo rwhnu
wok grxk lchvtg plrzr lwaax cfeu ijapws dmkdwc cfeu
zkd hysxxip hlydw wicsvy gbwoaw dapre ktjn dzg uri
blzh hblz qgmjceg fyf
vkhpn xnc ogva pjrh cxn hkpnv
aja cldzta tdcazl lorr fwmxxh knilf ges tdhp gnlo vihrl
ucpr peair nlbmc msfg
trv ppq bmo xqd vbui yegsr xqxawu fvuz aclhspo wnan
loiq fvg kare rmgq hir rzo ossd ziw renh ygtkjys vda
xmans kio alexs ujekfl vvf ddghn
fcxvsf bjuytet zrzsobo uhn mlfzhlq bjefs
zys htlqvky plno pbcqfuf fjwc vshkxrl lonp lyzmy dqmui vyyc glad
tlc krhcter krhcter bolk tlc opryl
idcii dverl uswb wusb zgax zhbt gjsnlso yhs
cti npri rcbxjdw ollj nirp ghfvxzh
blyhug aflnrrz zudyw ccnstq cyoju jxtqoj ntuknjq gunjiwy ycuoj igac cqctns
bul yehpnw jifjrhc ifetu ufrodp hqzpeqf hdvpc qtvgxg ibb wcxsitx xztshb
xzct scetn eoaufyo jtudgkx xrpgxip lpubtq juezstc nuc hokswh obkf ipbu
nfq lwpmn qltal xnphsqs zlrgf iewtrtd mqzsob duokpy kfbqs icg
vil zjz xkqrvni uay ystq
terrrnt lnfg clm lbs ptpiy ybcuup ayzjm pqugx lmc yppit mbf
dtajh vqivg vnblt fmn qxkw stiwna pclrrr fro khu wbslnqp tjyosu
uqlehn tjuiy obt uedct bbwiq uxndqn
hiqfovy xiimca zwne ivunvjk cmctzi mxnnrx dclib xzaoq ieztkg
shpr xuorihj chuwq poadbo mhtvex gymsp iltgl sypjfua fmyh sgiv
alv nxjt txnj bhact
vjvtrex obmrxk fgigs meixbc fggsi awi rxdjpeg
ypwo oicmbdw xbpeeyj uabzj cjvutvc oicmbdw immtmks
exijri hogl epr gzdqyur xiiejr pre ihzlgzu
rlh qfhx lrh qmvrx
kogq okhd mivmivb mivmivb okhd
taekt nhjaa znbaahn iaospxy jawwf
ytdvq ghtqwud jkiig mre kzmmjxu jba nwpykc
ktyzr aczd exgadhb uinrgac izazxky yyfe
yrifb qgc lsiuapg teyelxn ugezu
wdzkc ltx fkhncb hwrecp kfbchn sfcpc hjvq
rjdjyt ahwxh nvggsmx lmz oshd xbcik powse ahhxw yhiq gxmgsnv
qdr qjnam gag qjamn kooek mqnaj
pza gml opf ilfbblu kjp luilbfb rhfrzgp ixagj ofp
yphz runy dhull bozcsgk wfxekrd akgkbz urcphc
tfyxwol lhcl npik beug
szatel yfkve yfkve lzqhs
yjzqon pcjibu bdncmcl kczuymm pbmg nyn
rerqvs aoxucwi pmstl sstawu joqu abvcchg mvgjn mslpt vhmfkr utusuh
gqbec jjpqdh yeaiavi nledfi jhzwc vyxjpf momnm vnknjs nvgjzik ipm
psirt rispt lrkgma irtsp
jbbaph xvunete gsvnr mjd ifxhpry cpsx hmuokkx vhcm yth shrrl zbhd
gfa bcmlxtf sqyanrp cugg qxfvftz pbl ujsgc jajxltm gugc oil
xjuhyg aht vmyvzhh oby oyb ybo xbybgmx
atfk qjudfzz mky tfy
nxk yzy jqgg qxgjt bevvvv efi xcbw bohc zaqlqjq
hdc qpnx ygmtqw acvoa udboxw dhc klh mwgpk xfpuri
cycgbkq skwhyf skwhyf veaqss skwhyf
jnezf jowjt vsdu uck scgxd fvopomz vfajslp
djvi epgkyqn apzd cpm owm kpwih fsr adlhqu jicp pmc
erxlmhj wqxvofi ugj ttrmtsb
omku vmrgoy tdicbje ewml dfnwbap
gpih pyt ptsmzc gmdbu rqxkqmz objm nurxjz oozbere ztxug koth
jpnl jpnl dmeh qed
intdwv ksgw qwlzhq zpd lrl mwjl dozrjwq aujbet bsnf vhqyg
eqs uot qyz xor aem kmrh mrhk jqx tsbrf
irytjab mdzm qbb kkjt gofiwo xgbovg kyeyxqn tcks tljhx
zgejy qodgah nqavvx xnigdvt
eqve bizrxq lkhz yzwxgt nwe zfe sxypkz xnssept
bxqn lkfg yfxbszo sphwifz wnj crhbq dvokzw
vzn afatwye ogzvnu vnz rfjba xtugnj kpbgly ocsjd
xrc cxr rahv yvhk khyv bed ctgbuq cmqwpqa jlbg hpj vmesvw
jbshkya dgqw lfl mzcch jxsg czcmh ifruvlw ufwrlvi xcczlol cqqchmr
rbk mhn tnmqdc sxnnn kvoa mhn sxnnn mgemob ieiyajs
cqi ghxg ghxg ghxg
uqwdxn qli gdtkngp gnptdgk udxqwn
dmcczr dnjaqc qwdta rhrbi hkdwe qdjcan peic iulaz xns
tcmppb nzq ecy sitdud nft ecy afrbf wvnc vmfpzx tcmppb cgb
plitv efnpq mjqav nrxxo izg lpitv rwbzdo rdbzwo
day dntga adtng agndt hhvtd
yrg iudsh gyr ryg
qttyeew tco flq bszw jkzftc wdh efcwnp mja rfmju
moch prkze uslzyv plhjuy kxczyq qlmm hgq
xtg ypz izy ixg bvs xlqgj xcy sepza abiylsg
wxvsxn bqag jnlzgxq ikxwa dfd plqxl xlgqnjz nuqvoyb emhodso gaqb
bzjdsm xmxkj fhuqn gauyw ntl kjxmx zcxdr vrds
ofjcc uxyzlk ofjcc ofjcc
zwosex kkvwobl cpudsmb kes zklf bayuojr otqnyr udbbs
iqpvzh ybds piovrh oivprh voprih pov sfl
upns cpeelht xboyk itb hsxdmt dnwgfbw upns fygf kwdpxzm mli dyy
djwutl sikh shki ikhs gecd jqkon trqyw
prbbdf vdp bvvfjcg ydqb muxygg
vhpurzn psemqe xwqfk hrvonxu nxkxacq
xicmhss tnpja qiad woipfy uvadcq usljh hzgs jntvfv wzikk
mmupc twntp upcmm pumcm
qnisuzy lppnfd uiqr eyqbain uxlp eyrfwjo olgkrps sbikam zin vckr
nmokl skfni jcdfot njzqeaj nqzjjea
slmaxx offfzqp wudicrf nfn rwfcdui cwirufd
paffi murnjd oyj lbtjdqe babuas dtqh qkt stapzl yrqlp
eedc rig zmnfmn edec ecde
bcfdf edovdj lacx nzvze sordvxj ybs ujh zvvvp rzstejg ueosuq
xrrfsd okuvem znzlvmb jwzcb bfg bmuxbc qzwfry
pqgxybd cvgra acgn ocd ancg fvfcx fbb bfb zfzv
tmmv mpywyg fwl bnvcv lcnv flw
xxnfbro papc ianru beuzx apcp rnt
wuyhycj nrnc cka ebg rncn rvo wcyhjuy
thh cmoog hwf imqfp okzpxd
rzxiqt rtaiy ytria tyria
cjkmro myif myif xyirn aqxlol wlhwibi dhzsen pzwgm bfbz bufjs qwffg
mxhiui umiihx zomyll vfieccs
yyntf rjk iivgj mwh rjk
dsshx wsmaxhc xcwuelh rdsgtr wsmaxhc rgtsfj
rdh nwlxiwu xsjzbpr bsgps
ufyo vqtzkg kpeohu mxzt fyuo gawgaq youf
hzbhut bxsnjwb zuhhbt zhhtbu
pdz sgntypg ragev hrrji goitft yphnebs xjzoo sqf jsuzijq dsocb hcxg
pptsq woomypc woomypc woomypc
axcg wfbnpql ejqb cmnn nncm csvlc wraludb pkmp whtht tfpicer
moom oomm ommo vfqeii
xvrgpp rofl yxyrkb oage nypzau pwfnkn jxnhkw cyxsi clzb adwpuh
mfbz vdtt muzhm wvwwfl ttdv
cpqgvbu byc pgfrlkr aftl tqm zcqxi juu gnf ppovxh huoa
konpcp lzordid jqng lwxs nqgj gghkxmf kyn ngqj
iorhccj xfygc cnfr tysqc xpcyf vmjpitf nut zmrk mgbrtb tcblxwf dkadwrm
kov jtmp xoatesx qxkilp rmggpfx ltpxzwf vko reqms mqq nps
hjigmk fyqy wpuwe mwmso thsimfs okcmeyh mzqkez duzaq vzhyrm uyvpkox cwivpls
ukoerf korufe zhs ntwfz hugem vriyk enfaib hrrcdgf zllsk vkiyr
shkx khxs wntpjv qdevaw noqyht nwpvjt egh hgok mukdjfi law bzbvjz
dquk kczxsq tdu trnkjs wqtdc ybvcb
hlrotxn cumcjkm qwufgle ylm nejh hnje pvaigrx myl sfvsd
szmvisn aywic vsnimsz iufmybr
zjozr zojzr qmn ffrggdh wam dafvok
nxkvlhr posmf posmf posmf zhlzb
ywis kpqpyb qae zqxpuz pcj hbsfz ejlwa lajew znuom
qxsl ussivur dstd avojo
yoeagao egpaqm ymzf kkauy ivm illir wsvchne skmamvn nqxc
cldo ixzzy vhk nra zhypgab
qjdd ecxud tbuqq mpotbdk tjdpczn knncm tyy
rbfc fhhjf innia tsjbbbv fmtcuup rapvhqz ebpzt whdbms gvjoy lykl fquvcby
bihhfwi lhal udxz uwjwp dmb
fekxamy uophet yzvv rqj zawlp ldrv mdymkzy taauf
rcwxvmh edueui ltdyo xfghz dgjig senm ifj
qcu fii axmgijj ifi oixjfsg jxagijm
sdtyr rbdh yvnvq czzuig wro
lot xkto cmpiena nht ozcg aotcw xiegl cyaouj und lsclep cexn
pgihljk cmgmv sajhi zfvbqij ogwoc ajsih zmppe
jexwkdp dwpexjk mzjydfu bff rubgdb
yshfhx emkl hshxyf mkle
dxgti jdo tkwprv pbxbrqd oiz gsbdphd qotu utfdnq tzvve bqc
ovdf bshfxyl xspjpd vljdsm mgkd djlsvm mlsjdv
etyia eytai sfq qafj xzgp ewhsn snwhe lhqp
zjz mwh dorxm ges gexo rckwsa dltoq mmntha
hqkuj ypsjcxo dixbe rmvnhjh ovnr
edc iffaxc lolu xwrvpb gva vti vit
ceuxq xbwejr lzyvm rozseit cwe mham fivpwj qtv omaktaw
alzdrk tsxbuld mdbq pgbdtoo xwf vzalric nqe jqwlxsy cbtylu dtubxsl lqm
rqjmjcs exjpn kpilcgu ihcm lfadjm mlri hpd vqs cxqwqhu twxrtk
aeuvlcp aubvnw riedvz arypagp uuvg kliehx cokt ogh xsdw cdsyywv
ddwrgvp bscaq bbfv qrbutp
jpdg uey eyu uyarl zgbk qyhqq fdvlql zmwkp
kbt bkt lebhpfu smrzt xalw mmwa zmtzfry tkb
fcvcv oewfzu fvvcc mldww lwdmw
ejrltsu sqoyx wfvsdbp bfdspvw bfir jqhgrmt ofdmrjg ysq
jzwucwn erqjd eikq knpf cvk xvqnscy eei wvfjzmj xujq cqaim boev
jqhkmr ipjpj zwno ybu krhqjm zqfyyzb dyciy
ugwsw rpwteje qtvwi pwyhrzt hfcdfmc qbovk ibws
ffy kdder qjookz bfvmvvq yjzuaj fvxllfb pjyz jcezhye fimyydt qjookz qjookz
loupd nwsc yytvuqo ltcqxnf
iho ulvxguz fxbf iqu ofjtmvq xhs ybbusd kxg mebdnah ucttcf zufb
wzdb wumuhtv kef aavv buu xmjtlur faaccl wospwff bjasr eapfsi
jau qzszci ciu inagax
kui tqig fyovsp fvwol fyovsp mzth tcp nhoq
ajdla wtpj amylu jly tvq wjqef
ofqc einz bdze tows bdze eew
avwavzt aesrsjv lbmpi hllv chdbul ezelxn
imcprs cafb clfg rsjo iylqu nvk vkrq izezlnu vkqr tyhnv
rwj zboui reh buzio wuhpvid cpzy jrw tsbuiby hmxwqr ute
ixq luwbi uoiwsjh souz ysoubw uilbw ffwjvw ewzswoh hci zmfdaov whowzse
xrhgqf xrhgqf giyv giyv
toiqgzv gakg udgdlb wvi carrn pjyha muqclu
wuxthi srtszr ourab hpds bakvy fnk yefe yfee doowxcx
ijdc ujhvls xmy hwg yetsda qelbe nang xgywo wgh
bhm icq cnam dec enksf qfctz pwxoo bdf cnma xoowp rbls
jguzh fextz yax kesaunn waljo jltcza tfzxe dezs syi ebwxnks
flvq bzgd clvqw ahtyvu xbdyv wssxx boscm grgl nqcg
caskpli hqctxxc nwpyo wjlqfqf ebti dva
wmsz fzpd ikgeq gti ejftoou ezs cqef mybojc rgwz
mdaay yfppa pavl fuuvfkh hpod tpb dhxmia emdecm rbqcwbk vecyt
neha rmvl ndp vlrm dpn debghi vyhvc
bnp zkxdu iqqkesd abtlx hmjasdq kyvekr krt srrjyd oxmfev oot
dumlcqd ccm hyir oritdz madjjw
oakqrs advfmu verrc zkfdcn btndsp
onlkinl rdtm bscfxre bnu oumyrvv kgc zkj
tfxfsgm uwmic agswclg uofezgc
wpfdyjn kjlihk etbot fbu scm gwccce xgownte wig cuaijbo
bzbdk etozk qracb oftfoo lkooe
xupzw vmxwu sis wzpxu
gbz oqbgh jwgrru bzg kwmxcfc jrurgw
agyjnyc tuec imxlult omwiyjg fiwnoqx nhmnro qtg kbr agyjnyc
koiq llreotu elrtoul dubfvgy whq
htm lll crzppb gdjaae nsmxzh gnfvn obiuy ymspzbo iuboy
thm xlfrr pbxdfo mht tygi sapxgbv mmngzf dej
eus seu qmstw ues
yvfsw esut biblze kbjcpk estu xih qzki ezlbbi blzv
ohq ugc tqqeo jygvpwm vfs ldnfibp ycbpa sml rmime
kuuow gbg nzwdaf wiimtg lam oqmm
wsbwkdd hda nqk ticz mvt
gqbljyh zqugqs cjod sxwlqy qkfs wwvwvt dsojb qbhjlgy riusoa uosari
jkphfx dbt les jsvoij rnuw mxmmchu dol vto swn
qqxe vwvephr twdqlyg cvdu xjiych clooq vkwavl whvverp yuz vkwval
txtbudi tiutdbx wqhx tws utgbf amh hmf izsez ooz
egdube nhsxjs nxjshs xoy sjsxnh
egdziod diodegz ejxn zogedid uhhkr rnm cyvvuc uqbl
rbn pinwag sidwdwv jqdbe jlbemk blkeaqq ipfqbtn zkrbp
bdryz sbh wxvn mhot wemsfm oemkff
vxyn xvdwwo xhd vyca zxjaw vfkz xhg ofsphks dyq mmzzd
yjrqsjf iiesdh envwyx rmtbmiv ggzsg ukx bprfym qmyqc vag ymho hjtoh
fuxxrd wbweptd vkoffr wbweptd
gfwcez smetli yjyh pslpz qyokpsm qsy cxjymg wqfkf obuq awz
eqhm ceest kayf heqm
rdi dti vntcf ewkmpvf jjwoihc
sfq qlb xrm ocy vtnj zdznbal zvon stln zwnj wsgalvq vhphap
pya jay mgnyo pya xmapdn
hrwbj xhr gvwl ktq ktq gvwl
rzgqi hjwtthl kxhggbl wepc hgavj ctmqug
tzfwkc xeqfath iiuwq iiuwq dhwuvy
gibagy smq getjofc lum msq ulm xuxu bilrus ily
xlv ndrkch hdcknr nqltoze xvl
wmc vuzlrj mwc atp cvpx atv ujatz
hxpafgl ymjltv nvvpy ahycdk jhpdcks ettm lvqyw ertpivm dnezwxx usi kdhcay
vrh hqyomv mcq ilwjbkz yprjxad
ugv szfitxg zeluib pfj ijm zmiigxx gltxzz jzljhgh otskue
mxp bilj jlbi tce yfted zxsqas ftyed
ykasqv ehye kirmnl upmi dojwmw wzj ykasqv ifixn vreoypz
kerbgub nnroqk onkqnr gbebkur tjhl knjo ccsem yozvrcg
ygq evkoj wkn ffljhds scxeibh egsybeg mwvi vgjblj qda ywqpp
hocvpl ozgkxp xgmj ejzyxm
gernu kks lxe nxzv sypg xle goz
xoatis fjp wzlbo dzkonz jtutyj vdonj swro tqclemv xhomap ymeqkua vaxcw
mxcyjs ywyxndk wng vpftv nsuvu
jmiyyhh gwser shgcu jmyg cjzegc hmhe eopg kmkan
smdd dmds mgqhtkh qtamih haqmit skkcy
dnj rmggy rgymg uburbao rymgg
klcpjgq ons ajyv sqryt son pjlcgkq xlobdt
piw shonk tzi mcdumz noskh tebolw yaypn
ozm mvmjgtg nxj weommiq asnmhzq xjn uobztuo cqgjh utfb oydt ommiewq
qlwgsc vvpe xgft ahpjc zjtx iyof scwqlg dxgcokx ltrefj xyzq rwto
ggqdd dqgdg ggdqd kjkmmfp
htzjam fjbg iagc xls iagc iydtf ihxl boa iydtf
vhe nqj bwgdoi hhaoa qtulz
axvyja hpdkwee hnryj prou rgadv oubjdqg knjbc
caz xibj wqkzwe peioeya vmz hesy ftb
dudwcr gupj sjrtzc xsqbb hiet nujv bebcvsj eks uuzlcx gex
kywozi tfzuc mflssw hnxxxqt zzc tzfuc hkokuv mnjg lwkavjp lvpwjak xez
izgh zfv cingjt dkf cknite qox vfz zvf
ojpu dzk tehpgnt gntpteh
glxfxa uxq ajtles ahgzn ajlste zwgc mrpu adz wuunwhc zda
hdgdtn hnoyz aromkb qujfv yjgmn tbf atw
uyvsv oaopjv uyvemxk ldpp tthe iisjk txr hebmd yxevukm rkziao znt
ypdr mnwuzvw acpg kzwz ywbn wcrr umrnlbe lkult ljify azyhu mgqoo
abmpl omsd xmyl mxyl mgoq kracrf ufm ppwi zpggh
uxfdpv jnm vvc vchunhl ubv ktj mxolsxz
fcja eci edzrb nlvksaw lhf ycohh tfztt xso ceub tyv
rkwtp tcmmvv kufg cxui hdamg suuaej fgku cvjlv
oldbgy riadoyo djsi wca zxoeq pmemqap aijxa
nyy ruxcosx xisqoz yny jvzfpbe tlfdiaj ybd jifatdl zuzv
kxwdz qvrvx svllp ergmme
swjfuv eronk favcxfm acptbh pnbjn ciqcrlt rgvdnlt icgahb
ddza xxfn use obqka bfzwjp gmf bld fyvde mxdfdl
ame bmxbyf ame bmxbyf
rdgby pyfog dybrg gdryb lpztd
sntg impd uxgxai naoalb ntnk xgix
oadpmqj oso criln izih oos
ouzjq gtl ito xefqt phnv ouzjq hoyjjj
mlp rboq lpm roqb whvp
tghcw ggshevw dzsgj ggshevw kec ggshevw
kmwhb kfcb mbhkw gemz fdh
euve veue kplrq evue
hikfiw bcdktj hcnawja gjasvwc vcht igrzly rkxijxe ikfwhi dvmp
hvksis kafs ktcs sfyqzyt etctrgt vodwr wff tskc juobnm
dpcsodn ehwc pglywfl yhdp mdiyzx
ibog umftejh cfm pnxhna wqwx yabnk ygws dqw
dezz tqw qism rarfe fpmlab xvbau irwtfs wwmoyss yvn xetqp xtqep
pchqwk npsmd jefec qok uuc ucnpz rlkakn
kudh rjysb xrdbx bkbmjfo xrdbx
rogu ssdwsus voa ncw obkxsr
tflf hlevus scq rrbpat tau wxsq wxoblt
rzr lex kqdy whtj ffnys xlgkkff msjhy dimaq hrc wyde qkwf
ghtwd wernjpn tdgwh olrfvmr edq gxvp
rjirvf skhdgln aauit bipu mubjiwp kowz gyjfbjx cmgdqs
aftfpbv agajyy aqjll vsf twh robpys lebt eav yribup
sby ymkla sxkbfwl awmd nhb vlp
kizvjj ycjswr jkzjiv vuy jijzkv jcs
cwvch xzqfal tephz lqfzax cnkbdcr mql zflaxq
jjxzwl himpra ssjf bibfiui seeaq pzse
jogrn jogrn sqew jogrn oixgwr
khonpyw iiyxir vybhc ndnxxv kzlt ipmncn
okqkqu svbemi nfn ovd xgwy edd ujet nrrbv dde vdo
jobvf dus asvio vaosi sovia
knmz qbz nkmz zmkn
isbmopr unduey impobrs hea zswciev sopbmri duuj
ocs ntgnrdu kbvtzp cvyieu fiyn znmh lhrz ixtnzrj vktbpz lbpqx vzkpbt
muduhc sabc dlyoisz kuaz ogpyepw yuog ictiiqt
xjflsf nfklvml thfh uajnmby cichyj xxoqi lpime bxpyx
riahifn bohbgd obhdgb jni qzvkf ybp hjkkwq ytutd cakcsh smfdoe tuytd
iddku nccp zgtl yne ppzpqcx lwm
refpcz uqt uqt uqt
mtn czxkagb nmt caqacrg bcakxgz
itxjii uethxbj vpds bsqod diqax inv zrwt doepe
bfyaj nbvhg zmi buf
dtre dkwdr nrapm qtfth odvt bbcnae vxuk gqm enlg
ybt qcfozrk yzrh bfp euuozuz pzsdkxx mhi nbkzprb
vpuhqn gyx caint antci vfep incat kqdakdx
ddhi chgnjk ibg xbemitr mjtdph eovw
ngbtuvq qdttlsg dbqhhwk bkrqze qdttlsg qdttlsg
evn smvhi dgcmn xjo ascc ahbpj uvzc pwn tung
ksu thr omg onvsqzz rllakar ysfjtfj grxwyx oawix gpk suk
qvb iouav yhtndkd vuoia ouaiv
kud kofcip hcczrgc cvvxxlk rvyamwe duthdzr dftun
rgv ynw gph tmxwfup nwy
dnc trawj kwzbx trawj zvp
ogqxijy tbqtsg tbo vqinnlq jbvgl sfafh rve mcxqs ubh
qccr lpv puuvdyb tydaflf uxic
tlon tbfwkxg tlon tlon
iytiz qjlqaqw uixb lnt zwro uzgxqfi gklgnqs zwgoidw iifk wkwdo
tmvhxw tmvhxw tmvhxw fhiqpjy ejk kvysd
cmphg xjjz groiccd dvetuk xbwa zhm lyi ohhd neg bxaw yil
kdmzopy lxx bvhach goxmxu qbqvzcm qbbrhvb nrfom aixmio grpxz hbrqbbv lkucih
bnqn phqr uycuxc mopyyfh bbpesqm stgigq stggqi cwtjm asqhpl imvlxj lbmloo
pws iuvbvjr cwccm qbr srqnstz cjebq
bfh jobkcy gtbroe lpagq icmax jobyck fbh
ounqdo qrrr pwi alho rrqr beao rsioepe
vrccqge qvcgrce cbslkjs qnclw rvmjkw
aaxjns deupjs wtgxtp penad depbho tbrdt depbho qxg zhjxpgd
drqfo kbp jfa jaf
izn oczcitj cpae quvzqo iwwk jck idjdpm
ecort zgcvxx bvh vrprsf
fhubfvy ndcfjo kol hyufbfv hvpka
kpt zgajpc rjvsxa gayznjd
xeoixk peq kfu lqa mjnv mzvh bicl hlfk
wyt imdx lksy twy
xeptp ilxs qbsqzwn rsy slxi xtpep dsdkekl
rotvbt fuirp elos ciu nhx bxej trmtx ixn xbpc vrxtma
skcprn yns sao ghlq vftezvc aaryahy telt
fkaov gexa xijv yiksa xega dhgw okfva gxxs edkecag mqbqvrm nrzcqub
ljc jujxeof fdj gdzjzr mabbktu pmyrfv uspven zxry snt hrah
nhujhdr jdhrnuh midm bbavhpp cpjk zmpbasz eptrpou znq zqn
ywzfq wuu lfflon uuw rke qzwyf hjbms gakx
yqrq zsk jzn uuuzrml kzs lseupsg waynfh blech
gwyqej weyjqg uwuje uujwe
lxud rnwkc bgygkh csq rfvtos ystqp keb gkakodj uthcce eqxifl
elvj evj rfwo vvgkosh aarcgjs utsbh orwf jxcqvmh uowmktl qtgf
bqszre oxntty ombwiz mbiwzo
ccp iilcc tacf czk giwv erqi jgdfah wip xtrzhv wosvbyb
gymyw rwsxeg gvydr izyk spsonkg knospsg
djj tbr tbr tbr ice
yyzh zkykapw puydtik ysxc hjumhsd cuhhw dnnhida yyzh lnklymg
nhbcxsu ccrbbyw scbxunh ghxrkqh brcwcyb
latdaav sexa ipzuzjl ayusb etb fshh
giz akqd vjmabii arfuzgv efrww jxkvolg efrww vrnzgbx
jmcc vqy adkzj fqrkdo tjrczp ccmj cfponk rptzjc
jsviu sraw imsj fujm cdf xwqhl lhz ojejzuy trtqblg
ibz dulm muoq quom etvjzxn tuhrpp jfukac jqctqn qhgbae msgmcit ludm
zgx bpfa elhp rnyqtq wyceube nkeuxz
lzxfo vygpecv jszacku zfxlo
cpmv ysaaj xnp wbvqg hrsiuj venjxna yeqvwmk ftaga dcqxc jgapb rqdixp
xpbbe tyn hfdlu fto wrgzkou sxylv cqto wdv xqc pnu rapk
pkrxypl wnu oipq tzbhnc gpug tgzf ofjb
mvaz bwcv gll itgcye dessw szt gzimgeu bvmohh wbywyhc kzerxbr anjsive
lhvnrzs qkmjwy pnyciwp mgp jfdz ghvtf yusfzg upab
xbscukx aubulj snbcmc uscxkbx ddpucyg
hgv ollh yzpjmpy fcicyae vhg gvh
prd onyd iux oik xui
zipadig nvewx cir lbpcusx dljqy
ifyxzsc btmy lsu tmyb lus ldyzx
egmyxbe ieasvek dylmj qahtatr uyqgbk
mejjczw spj vaekp kdud
vwan mgenld mnlged vpfuil euoxlr rclkpi dfknyoa rhthij kcyxl qaxab crlpik
pqm eihogk iwml nuauxi ngilkoh jmu mbdi cqxz nblb rmuj zczdgp
pswbe mtzch wbeps fxtnc psa aioff pas
prwrpvz oadpqvz tgzrt giom pjyihh rxdir dmya xjolzxv
khdybe obqkjn kdq jkvmgwo enpat wyw qjbnko waid msest wwkoyts
yep liv ofmtpod imdd qyw
afnrx jgn gxarpb myltj ggrsajy mdaobjo vbtn vbtn zlziz eds
hqr kqu oub skoeqk icnfm cqvld aay bto
rga odaf exoosh pwevx zpbd plaa xoseoh
mbr gqu oxvchrt nqa larxmjx pfozej
ozuo ywubjbg xcua eblwqp nfdvw hmhen zkjfu gmhgp bsyi ktprtf
src vrysby srybvy znwjm hmypwdl gdmau pqe
cldr crhi lbaq fbuduyn hygbz uhida
qrxukq dygkp oaks soka oask
vpido ajgfq pwlv hezt fmg epwrxo rqvjke iovpd hhkjm
anxf ydl xnfa hqph olorp
exydcg onxjm psqlbv ehz boar hze qsblpv
mnzrvc ipj swg ijp sgw gdkntsd fzz grqwly
erpq qghpj fay gci uglm afy
jwbq hbxaub jpdilyt yvalrlk topl qup
eczonk ftcc paltirb owz tihhe dglxory wthvqcb qdnxm lirejh alyxsr
ooruaby gboyeu lkv arrz jcqyzl uxlfk fhmeony fcmh
wzr xjb pwmf okqj adwcedy lkidve uwekxf asbdzr biub
dikhur pxgh urdinjh wednf ulzdxs
iplf byt tyt qnnlba pzt bednml ljjtkvo tjovlkj uwms xat
htzk ltmfha xikeze atfmhl fchxhyz
lqala bqwgcul vetaa xuxjau zcb wtdmomu wfqmpq sief uyblyz ahv
aytvvo awm ojaaigg awm dbfaokz
abq npcyld fzbfku oia qss jkxldm wgtmki pasgxi dieix rpqnuac tecnfy
nmr qzfj qjfz lsz vnahex
djxoo jzlkh svy xige
tjlkkg glcuvmh fwzlhi ecun qlgulj hrfhyql qgdlf ofakqdf zokkvm gelxkq oowgs
upfpk gfstjlv lxc rjd nhj sbq jpzsz zsjzp
favd nzqfdid nekfjsf mtjndu
sgdqx uvpuefv vhwrgd aivav gsqxd jdhfoq
llaf cthbgy njrpw fqgkx jzf xqkgf lnrfrm gkxqf
wzdwlc wisst alw kyjeur sjsqfcr tta bijnyn whfyoxl
dtjr baxkj lmnyrlg nrmyllg
mtgky xmwf zdko nnocxye gytkm ygp hixk xwmf
maudjy okgjga uadjmy dzfrk omd
azz ajdcqkd bcafn zaz dcjaqdk gylyzo
xzvfbf fopmfxu mvftgr mfupoxf coyhof talcc vpkslo

27
2017/d05/ex1/ex1.py Executable file
View file

@ -0,0 +1,27 @@
#!/usr/bin/env python
import itertools
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[int]:
return [int(n) for n in input.splitlines()]
instructions = parse(input)
offset = 0
for i in itertools.count():
if offset < 0 or offset >= len(instructions):
return i
instructions[offset] += 1
offset += instructions[offset] - 1 # Account for previous increment
assert False # Sanity check
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1090
2017/d05/ex1/input Normal file

File diff suppressed because it is too large Load diff

28
2017/d05/ex2/ex2.py Executable file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env python
import itertools
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[int]:
return [int(n) for n in input.splitlines()]
instructions = parse(input)
offset = 0
for i in itertools.count():
if offset < 0 or offset >= len(instructions):
return i
delta = -1 if instructions[offset] >= 3 else 1
instructions[offset] += delta
offset += instructions[offset] - delta # Account for previous increment
assert False # Sanity check
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1090
2017/d05/ex2/input Normal file

File diff suppressed because it is too large Load diff

40
2017/d06/ex1/ex1.py Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
import itertools
import sys
MemoryBlocks = tuple[int, ...]
def solve(input: str) -> int:
def parse(input: str) -> MemoryBlocks:
return tuple(int(n) for n in input.split())
def redistribute(nums: MemoryBlocks) -> MemoryBlocks:
res = list(nums)
i = res.index(max(res)) # Quick and hasty `argmax`
n, res[i] = res[i], 0
common, remain = n // len(res), n % len(res)
for j in range(i + 1, i + remain + 1):
res[j % len(res)] += 1
for j in range(len(res)):
res[j] += common
return tuple(res)
blocks = parse(input)
seen: set[MemoryBlocks] = set()
for i in itertools.count():
if blocks in seen:
return i
seen.add(blocks)
blocks = redistribute(blocks)
assert False # Sanity check
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d06/ex1/input Normal file
View file

@ -0,0 +1 @@
2 8 8 5 4 2 3 1 5 5 1 2 15 13 5 14

40
2017/d06/ex2/ex2.py Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
import itertools
import sys
MemoryBlocks = tuple[int, ...]
def solve(input: str) -> int:
def parse(input: str) -> MemoryBlocks:
return tuple(int(n) for n in input.split())
def redistribute(nums: MemoryBlocks) -> MemoryBlocks:
res = list(nums)
i = res.index(max(res)) # Quick and hasty `argmax`
n, res[i] = res[i], 0
common, remain = n // len(res), n % len(res)
for j in range(i + 1, i + remain + 1):
res[j % len(res)] += 1
for j in range(len(res)):
res[j] += common
return tuple(res)
blocks = parse(input)
count: dict[MemoryBlocks, int] = {}
for i in itertools.count():
if blocks in count:
return i - count[blocks]
count[blocks] = i
blocks = redistribute(blocks)
assert False # Sanity check
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d06/ex2/input Normal file
View file

@ -0,0 +1 @@
2 8 8 5 4 2 3 1 5 5 1 2 15 13 5 14

42
2017/d07/ex1/ex1.py Executable file
View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
import sys
from typing import NamedTuple
class ProgramYell(NamedTuple):
weight: int
children: set[str]
Tower = dict[str, ProgramYell]
def solve(input: str) -> str:
def parse_line(line: str) -> tuple[str, ProgramYell]:
name, rest = line.split(" ", 1)
weight, rest = rest.split(")")
children = set(rest.removeprefix(" -> ").split(", ")) if rest else set()
return name, ProgramYell(int(weight[1:]), children)
def parse(input: str) -> Tower:
return {name: yell for name, yell in map(parse_line, input.splitlines())}
def find_base(tower: Tower) -> str:
candidates = set(tower.keys())
for yell in tower.values():
candidates -= yell.children
assert len(candidates) == 1
return candidates.pop()
tower = parse(input)
return find_base(tower)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1241
2017/d07/ex1/input Normal file

File diff suppressed because it is too large Load diff

73
2017/d07/ex2/ex2.py Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env python
import sys
from collections import Counter
from typing import NamedTuple
class ProgramYell(NamedTuple):
weight: int
children: set[str]
Tower = dict[str, ProgramYell]
def solve(input: str) -> int:
def parse_line(line: str) -> tuple[str, ProgramYell]:
name, rest = line.split(" ", 1)
weight, rest = rest.split(")")
children = set(rest.removeprefix(" -> ").split(", ")) if rest else set()
return name, ProgramYell(int(weight[1:]), children)
def parse(input: str) -> Tower:
return {name: yell for name, yell in map(parse_line, input.splitlines())}
def find_base(tower: Tower) -> str:
candidates = set(tower.keys())
for yell in tower.values():
candidates -= yell.children
assert len(candidates) == 1
return candidates.pop()
def compute_weights(tower: Tower, base: str) -> dict[str, int]:
def helper(base: str) -> int:
total = (
sum(helper(child) for child in tower[base].children)
+ tower[base].weight
)
res[base] = total
return total
res: dict[str, int] = {}
helper(base)
return res
def fix_balance(tower: Tower) -> int:
base = find_base(tower)
weights = compute_weights(tower, base)
balanced_weight = -1 # Will be updated to the correct value afterwards
while True:
children = tower[base].children
subtowers = Counter(weights[child] for child in children)
if len(subtowers) == 1:
assert balanced_weight != -1 # Sanity check
return balanced_weight - sum(weights[child] for child in children)
assert len(subtowers) == 2 # Sanity check
balanced_weight, unbalanced_weight = (v for v, _ in subtowers.most_common())
base = next(
child for child in children if weights[child] == unbalanced_weight
)
tower = parse(input)
return fix_balance(tower)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1241
2017/d07/ex2/input Normal file

File diff suppressed because it is too large Load diff

71
2017/d08/ex1/ex1.py Executable file
View file

@ -0,0 +1,71 @@
#!/usr/bin/env python
import enum
import operator
import sys
from collections import defaultdict
from typing import NamedTuple
class Operation(enum.StrEnum):
INC = "inc"
DEC = "dec"
class Comparator(enum.StrEnum):
GT = ">"
GE = ">="
LT = "<"
LE = "<="
EQ = "=="
NE = "!="
def __call__(self, lhs: int, rhs: int) -> bool:
return getattr(operator, self.name.lower())(lhs, rhs)
class Condition(NamedTuple):
target: str
comp: Comparator
value: int
def eval(self, registers: dict[str, int]) -> bool:
return self.comp(registers[self.target], self.value)
class Instruction(NamedTuple):
target: str
op: Operation
amount: int
condition: Condition
def solve(input: str) -> int:
def parse_line(line: str) -> Instruction:
target, op, amount, _, comp_target, comp_op, comp_value = line.split()
return Instruction(
target,
Operation(op),
int(amount),
Condition(comp_target, Comparator(comp_op), int(comp_value)),
)
def parse(input: str) -> list[Instruction]:
return [parse_line(line) for line in input.splitlines()]
program = parse(input)
regs: dict[str, int] = defaultdict(int)
for instr in program:
if not instr.condition.eval(regs):
continue
regs[instr.target] += instr.amount * (1 if instr.op == Operation.INC else -1)
return max(regs.values())
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1000
2017/d08/ex1/input Normal file

File diff suppressed because it is too large Load diff

74
2017/d08/ex2/ex2.py Executable file
View file

@ -0,0 +1,74 @@
#!/usr/bin/env python
import enum
import itertools
import operator
import sys
from collections import defaultdict
from typing import NamedTuple
class Operation(enum.StrEnum):
INC = "inc"
DEC = "dec"
class Comparator(enum.StrEnum):
GT = ">"
GE = ">="
LT = "<"
LE = "<="
EQ = "=="
NE = "!="
def __call__(self, lhs: int, rhs: int) -> bool:
return getattr(operator, self.name.lower())(lhs, rhs)
class Condition(NamedTuple):
target: str
comp: Comparator
value: int
def eval(self, registers: dict[str, int]) -> bool:
return self.comp(registers[self.target], self.value)
class Instruction(NamedTuple):
target: str
op: Operation
amount: int
condition: Condition
def solve(input: str) -> int:
def parse_line(line: str) -> Instruction:
target, op, amount, _, comp_target, comp_op, comp_value = line.split()
return Instruction(
target,
Operation(op),
int(amount),
Condition(comp_target, Comparator(comp_op), int(comp_value)),
)
def parse(input: str) -> list[Instruction]:
return [parse_line(line) for line in input.splitlines()]
program = parse(input)
regs: dict[str, int] = defaultdict(int)
max_reg = 0
for instr in program:
if not instr.condition.eval(regs):
continue
regs[instr.target] += instr.amount * (1 if instr.op == Operation.INC else -1)
max_reg = max(itertools.chain(regs.values(), [max_reg]))
return max_reg
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1000
2017/d08/ex2/input Normal file

File diff suppressed because it is too large Load diff

62
2017/d09/ex1/ex1.py Executable file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env python
import sys
from typing import NamedTuple
class Group(NamedTuple):
children: list["Group"]
def solve(input: str) -> int:
def parse_group(input: str) -> tuple[Group, str]:
garbage = False
cancel = False
stack: list[Group] = []
for i, c in enumerate(input):
if cancel:
assert garbage # Sanity check
cancel = False
continue
if garbage:
if c == "!":
cancel = True
elif c == ">":
garbage = False
continue
if c == "<":
garbage = True
continue
if c == "{":
stack.append(Group([]))
continue
if c == "}":
top = stack.pop()
if stack:
stack[-1].children.append(top)
continue
return top, input[i + 1 :]
assert False # Sanity check
def parse(input: str) -> Group:
group, input = parse_group(input)
assert not input # Sanity check
return group
def compute_score(group: Group) -> int:
def helper(group: Group, depth: int) -> int:
return depth + sum(helper(child, depth + 1) for child in group.children)
return helper(group, 1)
groups = parse(input.strip())
return compute_score(groups)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d09/ex1/input Normal file

File diff suppressed because one or more lines are too long

59
2017/d09/ex2/ex2.py Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env python
import sys
from typing import NamedTuple
class Group(NamedTuple):
children: list["Group"]
def solve(input: str) -> int:
def parse_group(input: str) -> tuple[Group, str, int]:
garbage = False
cancel = False
stack: list[Group] = []
total_garbage = 0
for i, c in enumerate(input):
if cancel:
assert garbage # Sanity check
cancel = False
continue
if garbage:
if c == "!":
cancel = True
elif c == ">":
garbage = False
else:
total_garbage += 1
continue
if c == "<":
garbage = True
continue
if c == "{":
stack.append(Group([]))
continue
if c == "}":
top = stack.pop()
if stack:
stack[-1].children.append(top)
continue
return top, input[i + 1 :], total_garbage
assert False # Sanity check
def parse(input: str) -> tuple[Group, int]:
groups, input, total_garbage = parse_group(input)
assert not input # Sanity check
return groups, total_garbage
_, total_garbage = parse(input.strip())
return total_garbage
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d09/ex2/input Normal file

File diff suppressed because one or more lines are too long

46
2017/d10/ex1/ex1.py Executable file
View file

@ -0,0 +1,46 @@
#!/usr/bin/env python
import copy
import sys
def solve(input: str) -> int:
def parse(input: str) -> list[int]:
return [int(n) for n in input.split(",")]
def run_round(lengths: list[int], circle: list[int]) -> list[int]:
circle = copy.deepcopy(circle)
cur_pos = 0
skip_size = 0
for n in lengths:
# Invalid length
if n > len(circle):
continue
# Reverse
for i, j in zip(
range(cur_pos, cur_pos + n // 2),
# Avoid off-by-one by going further than necessary
range(cur_pos + n - 1, cur_pos, -1),
):
i %= len(circle)
j %= len(circle)
circle[i], circle[j] = circle[j], circle[i]
# Move
cur_pos += n + skip_size
# Increase
skip_size += 1
return circle
lengths = parse(input)
circle = list(range(256))
circle = run_round(lengths, circle)
return circle[0] * circle[1]
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d10/ex1/input Normal file
View file

@ -0,0 +1 @@
83,0,193,1,254,237,187,40,88,27,2,255,149,29,42,100

55
2017/d10/ex2/ex2.py Executable file
View file

@ -0,0 +1,55 @@
#!/usr/bin/env python
import functools
import itertools
import operator
import sys
def solve(input: str) -> str:
def parse(input: str) -> list[int]:
return [ord(c) for c in input.strip()]
def compute_sparse_hash(lengths: list[int]) -> list[int]:
circle = list(range(256))
cur_pos, skip_size = 0, 0
for _ in range(64):
for n in lengths:
# Invalid length
assert n < len(circle) # Sanity check
# Reverse
for i, j in zip(
range(cur_pos, cur_pos + n // 2),
# Avoid off-by-one by going further than necessary
range(cur_pos + n - 1, cur_pos, -1),
):
i %= len(circle)
j %= len(circle)
circle[i], circle[j] = circle[j], circle[i]
# Move
cur_pos += n + skip_size
# Increase
skip_size += 1
return circle
def compute_dense_hash(sparse_hash: list[int]) -> list[int]:
assert len(sparse_hash) == 256 # Sanity check
return [
functools.reduce(operator.xor, chunk)
for chunk in itertools.batched(sparse_hash, 16)
]
lengths = parse(input)
lengths += [17, 31, 73, 47, 23] # Additional lengths
sparse_hash = compute_sparse_hash(lengths)
dense_hash = compute_dense_hash(sparse_hash)
return "".join(f"{n:02x}" for n in dense_hash)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d10/ex2/input Normal file
View file

@ -0,0 +1 @@
83,0,193,1,254,237,187,40,88,27,2,255,149,29,42,100

62
2017/d11/ex1/ex1.py Executable file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env python
import enum
import sys
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
class Direction(enum.StrEnum):
NORTH_WEST = "nw"
NORTH = "n"
NORTH_EAST = "ne"
SOUTH_EAST = "se"
SOUTH = "s"
SOUTH_WEST = "sw"
# https://www.redblobgames.com/grids/hexagons/#coordinates-axial
def apply(self, p: Point) -> Point:
# (x, y) <=> (q, r)
match self:
case Direction.NORTH_WEST:
dx, dy = -1, 0
case Direction.NORTH:
dx, dy = 0, -1
case Direction.NORTH_EAST:
dx, dy = 1, -1
case Direction.SOUTH_EAST:
dx, dy = 1, 0
case Direction.SOUTH:
dx, dy = 0, 1
case Direction.SOUTH_WEST:
dx, dy = -1, 1
return Point(p.x + dx, p.y + dy)
def solve(input: str) -> int:
def parse(input: str) -> list[Direction]:
return [Direction(dir) for dir in input.strip().split(",")]
# https://www.redblobgames.com/grids/hexagons/#distances-axial
def hex_dist(a: Point, b: Point) -> int:
dx, dy = a.x - b.x, a.y - b.y
return (abs(dx) + abs(dx + dy) + abs(dy)) // 2
directions = parse(input)
pos = Point(0, 0)
for dir in directions:
pos = dir.apply(pos)
return hex_dist(Point(0, 0), pos)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d11/ex1/input Normal file

File diff suppressed because one or more lines are too long

66
2017/d11/ex2/ex2.py Executable file
View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
import enum
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
class Direction(enum.StrEnum):
NORTH_WEST = "nw"
NORTH = "n"
NORTH_EAST = "ne"
SOUTH_EAST = "se"
SOUTH = "s"
SOUTH_WEST = "sw"
# https://www.redblobgames.com/grids/hexagons/#coordinates-axial
def apply(self, p: Point) -> Point:
# (x, y) <=> (q, r)
match self:
case Direction.NORTH_WEST:
dx, dy = -1, 0
case Direction.NORTH:
dx, dy = 0, -1
case Direction.NORTH_EAST:
dx, dy = 1, -1
case Direction.SOUTH_EAST:
dx, dy = 1, 0
case Direction.SOUTH:
dx, dy = 0, 1
case Direction.SOUTH_WEST:
dx, dy = -1, 1
return Point(p.x + dx, p.y + dy)
def solve(input: str) -> int:
def parse(input: str) -> list[Direction]:
return [Direction(dir) for dir in input.strip().split(",")]
# https://www.redblobgames.com/grids/hexagons/#distances-axial
def hex_dist(a: Point, b: Point) -> int:
dx, dy = a.x - b.x, a.y - b.y
return (abs(dx) + abs(dx + dy) + abs(dy)) // 2
def walk(directions: list[Direction]) -> Iterator[Point]:
pos = Point(0, 0)
for dir in directions:
pos = dir.apply(pos)
yield pos
directions = parse(input)
return max(hex_dist(p, Point(0, 0)) for p in walk(directions))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d11/ex2/input Normal file

File diff suppressed because one or more lines are too long

37
2017/d12/ex1/ex1.py Executable file
View file

@ -0,0 +1,37 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
def parse_line(input: str) -> tuple[int, set[int]]:
origin, others = input.split(" <-> ")
return int(origin), {int(n) for n in others.split(", ")}
def parse(input: str) -> dict[int, set[int]]:
return {n: children for n, children in map(parse_line, input.splitlines())}
def reachable(graph: dict[int, set[int]]) -> int:
queue = [0]
seen: set[int] = set()
while queue:
n = queue.pop()
if n in seen:
continue
seen.add(n)
queue.extend(graph[n])
return len(seen)
graph = parse(input)
return reachable(graph)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

2000
2017/d12/ex1/input Normal file

File diff suppressed because it is too large Load diff

71
2017/d12/ex2/ex2.py Executable file
View file

@ -0,0 +1,71 @@
#!/usr/bin/env python
import collections
import sys
class UnionFind:
_parent: list[int]
_rank: list[int]
def __init__(self, size: int):
# Each node is in its own set, making it its own parent...
self._parent = list(range(size))
# ... And its rank 0
self._rank = [0] * size
def find(self, elem: int) -> int:
while (parent := self._parent[elem]) != elem:
# Replace each parent link by a link to the grand-parent
elem, self._parent[elem] = parent, self._parent[parent]
return elem
def union(self, lhs: int, rhs: int) -> int:
lhs = self.find(lhs)
rhs = self.find(rhs)
# Bail out early if they already belong to the same set
if lhs == rhs:
return lhs
# Always keep `lhs` as the taller tree
if self._rank[lhs] < self._rank[rhs]:
lhs, rhs = rhs, lhs
# Merge the smaller tree into the taller one
self._parent[rhs] = lhs
# Update the rank when merging trees of approximately the same size
if self._rank[lhs] == self._rank[rhs]:
self._rank[lhs] += 1
return lhs
def sets(self) -> dict[int, set[int]]:
res: dict[int, set[int]] = collections.defaultdict(set)
for elem in range(len(self._parent)):
res[self.find(elem)].add(elem)
return dict(res)
def solve(input: str) -> int:
def parse_line(input: str) -> tuple[int, set[int]]:
origin, others = input.split(" <-> ")
return int(origin), {int(n) for n in others.split(", ")}
def parse(input: str) -> dict[int, set[int]]:
return {n: children for n, children in map(parse_line, input.splitlines())}
def count_groups(graph: dict[int, set[int]]) -> int:
uf = UnionFind(len(graph))
for n, children in graph.items():
for child in children:
uf.union(n, child)
return len(uf.sets())
graph = parse(input)
return count_groups(graph)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

2000
2017/d12/ex2/input Normal file

File diff suppressed because it is too large Load diff

34
2017/d13/ex1/ex1.py Executable file
View file

@ -0,0 +1,34 @@
#!/usr/bin/env python
import sys
def solve(input: str) -> int:
def parse(input: str) -> dict[int, int]:
return {
depth: range
for depth, range in (map(int, l.split(": ")) for l in input.splitlines())
}
def would_catch(depth: int, range: int) -> bool:
cycle_length = (range - 1) * 2
return depth % cycle_length == 0
def compute_severity(firewall: dict[int, int]) -> int:
return sum(
depth * range
for depth, range in firewall.items()
if would_catch(depth, range)
)
firewall = parse(input)
return compute_severity(firewall)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

44
2017/d13/ex1/input Normal file
View file

@ -0,0 +1,44 @@
0: 3
1: 2
2: 4
4: 4
6: 5
8: 6
10: 8
12: 8
14: 6
16: 6
18: 8
20: 8
22: 6
24: 12
26: 9
28: 12
30: 8
32: 14
34: 12
36: 8
38: 14
40: 12
42: 12
44: 12
46: 14
48: 12
50: 14
52: 12
54: 10
56: 14
58: 12
60: 14
62: 14
66: 10
68: 14
74: 14
76: 12
78: 14
80: 20
86: 18
92: 14
94: 20
96: 18
98: 17

35
2017/d13/ex2/ex2.py Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env python
import itertools
import sys
def solve(input: str) -> int:
def parse(input: str) -> dict[int, int]:
return {
depth: range
for depth, range in (map(int, l.split(": ")) for l in input.splitlines())
}
def would_catch(depth: int, range: int, offset: int) -> bool:
cycle_length = (range - 1) * 2
return (depth + offset) % cycle_length == 0
def compute_delay(firewall: dict[int, int]) -> int:
for i in itertools.count():
if any(would_catch(depth, range, i) for depth, range in firewall.items()):
continue
return i
assert False # Sanity check
firewall = parse(input)
return compute_delay(firewall)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

44
2017/d13/ex2/input Normal file
View file

@ -0,0 +1,44 @@
0: 3
1: 2
2: 4
4: 4
6: 5
8: 6
10: 8
12: 8
14: 6
16: 6
18: 8
20: 8
22: 6
24: 12
26: 9
28: 12
30: 8
32: 14
34: 12
36: 8
38: 14
40: 12
42: 12
44: 12
46: 14
48: 12
50: 14
52: 12
54: 10
56: 14
58: 12
60: 14
62: 14
66: 10
68: 14
74: 14
76: 12
78: 14
80: 20
86: 18
92: 14
94: 20
96: 18
98: 17

57
2017/d14/ex1/ex1.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python
import functools
import itertools
import operator
import sys
def solve(input: str) -> int:
def knot_hash(byte_string: str) -> str:
def compute_sparse_hash(lengths: list[int]) -> list[int]:
circle = list(range(256))
cur_pos, skip_size = 0, 0
for _ in range(64):
for n in lengths:
# Invalid length
assert n < len(circle) # Sanity check
# Reverse
for i, j in zip(
range(cur_pos, cur_pos + n // 2),
# Avoid off-by-one by going further than necessary
range(cur_pos + n - 1, cur_pos, -1),
):
i %= len(circle)
j %= len(circle)
circle[i], circle[j] = circle[j], circle[i]
# Move
cur_pos += n + skip_size
# Increase
skip_size += 1
return circle
def compute_dense_hash(sparse_hash: list[int]) -> list[int]:
assert len(sparse_hash) == 256 # Sanity check
return [
functools.reduce(operator.xor, chunk)
for chunk in itertools.batched(sparse_hash, 16)
]
lengths = [ord(c) for c in byte_string]
lengths += [17, 31, 73, 47, 23] # Additional lengths
sparse_hash = compute_sparse_hash(lengths)
dense_hash = compute_dense_hash(sparse_hash)
return "".join(f"{n:02x}" for n in dense_hash)
input = input.strip()
hashes = [int(knot_hash(f"{input}-{i}"), 16) for i in range(128)]
return sum(n.bit_count() for n in hashes)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d14/ex1/input Normal file
View file

@ -0,0 +1 @@
hxtvlmkl

128
2017/d14/ex2/ex2.py Executable file
View file

@ -0,0 +1,128 @@
#!/usr/bin/env python
import collections
import functools
import itertools
import operator
import sys
class UnionFind:
_parent: list[int]
_rank: list[int]
def __init__(self, size: int):
# Each node is in its own set, making it its own parent...
self._parent = list(range(size))
# ... And its rank 0
self._rank = [0] * size
def find(self, elem: int) -> int:
while (parent := self._parent[elem]) != elem:
# Replace each parent link by a link to the grand-parent
elem, self._parent[elem] = parent, self._parent[parent]
return elem
def union(self, lhs: int, rhs: int) -> int:
lhs = self.find(lhs)
rhs = self.find(rhs)
# Bail out early if they already belong to the same set
if lhs == rhs:
return lhs
# Always keep `lhs` as the taller tree
if self._rank[lhs] < self._rank[rhs]:
lhs, rhs = rhs, lhs
# Merge the smaller tree into the taller one
self._parent[rhs] = lhs
# Update the rank when merging trees of approximately the same size
if self._rank[lhs] == self._rank[rhs]:
self._rank[lhs] += 1
return lhs
def sets(self) -> dict[int, set[int]]:
res: dict[int, set[int]] = collections.defaultdict(set)
for elem in range(len(self._parent)):
res[self.find(elem)].add(elem)
return dict(res)
def solve(input: str) -> int:
def knot_hash(byte_string: str) -> str:
def compute_sparse_hash(lengths: list[int]) -> list[int]:
circle = list(range(256))
cur_pos, skip_size = 0, 0
for _ in range(64):
for n in lengths:
# Invalid length
assert n < len(circle) # Sanity check
# Reverse
for i, j in zip(
range(cur_pos, cur_pos + n // 2),
# Avoid off-by-one by going further than necessary
range(cur_pos + n - 1, cur_pos, -1),
):
i %= len(circle)
j %= len(circle)
circle[i], circle[j] = circle[j], circle[i]
# Move
cur_pos += n + skip_size
# Increase
skip_size += 1
return circle
def compute_dense_hash(sparse_hash: list[int]) -> list[int]:
assert len(sparse_hash) == 256 # Sanity check
return [
functools.reduce(operator.xor, chunk)
for chunk in itertools.batched(sparse_hash, 16)
]
lengths = [ord(c) for c in byte_string]
lengths += [17, 31, 73, 47, 23] # Additional lengths
sparse_hash = compute_sparse_hash(lengths)
dense_hash = compute_dense_hash(sparse_hash)
return "".join(f"{n:02x}" for n in dense_hash)
def count_regions(hashes: list[int]) -> int:
def occupied(row: int, bit: int) -> bool:
return (hashes[row] & 1 << bit) != 0
def key(row: int, bit: int) -> int:
return row * 128 + bit
def unkey(key: int) -> tuple[int, int]:
return key // 128, key % 128
uf = UnionFind(128 * 128)
for i in range(128):
for bit in range(128):
if not occupied(i, bit):
continue
for ni, nbit in (
(i - 1, bit),
(i, bit - 1),
(i + 1, bit),
(i, bit + 1),
):
if ni < 0 or ni >= 128:
continue
if nbit < 0 or nbit >= 128:
continue
if not occupied(ni, nbit):
continue
uf.union(key(i, bit), key(ni, nbit))
# We created a UnionFind over *all* squares, only count *occupied* squares
return sum(occupied(*unkey(root)) for root in uf.sets())
input = input.strip()
hashes = [int(knot_hash(f"{input}-{i}"), 16) for i in range(128)]
return count_regions(hashes)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d14/ex2/input Normal file
View file

@ -0,0 +1 @@
hxtvlmkl

40
2017/d15/ex1/ex1.py Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
import functools
import itertools
import sys
from collections.abc import Iterator
def solve(input: str) -> int:
def parse(input: str) -> tuple[int, int]:
a, b = input.splitlines()
return int(a.split()[-1]), int(b.split()[-1])
def generate(seed: int, factor: int) -> int:
seed *= factor
return seed % 2147483647
def judge(a: int, b: int) -> bool:
mask = (1 << 16) - 1
return (a & mask) == (b & mask)
def iter_judgements(seed_a: int, seed_b: int) -> Iterator[bool]:
generate_a = functools.partial(generate, factor=16807)
generate_b = functools.partial(generate, factor=48271)
while True:
seed_a, seed_b = generate_a(seed_a), generate_b(seed_b)
yield judge(seed_a, seed_b)
seed_a, seed_b = parse(input)
return sum(itertools.islice(iter_judgements(seed_a, seed_b), 40000000))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

2
2017/d15/ex1/input Normal file
View file

@ -0,0 +1,2 @@
Generator A starts with 699
Generator B starts with 124

43
2017/d15/ex2/ex2.py Executable file
View file

@ -0,0 +1,43 @@
#!/usr/bin/env python
import functools
import itertools
import sys
from collections.abc import Iterator
def solve(input: str) -> int:
def parse(input: str) -> tuple[int, int]:
a, b = input.splitlines()
return int(a.split()[-1]), int(b.split()[-1])
def generate(seed: int, factor: int, criteria: int) -> int:
while True:
seed *= factor
seed %= 2147483647
if (seed % criteria) == 0:
return seed
def judge(a: int, b: int) -> bool:
mask = (1 << 16) - 1
return (a & mask) == (b & mask)
def iter_judgements(seed_a: int, seed_b: int) -> Iterator[bool]:
generate_a = functools.partial(generate, factor=16807, criteria=4)
generate_b = functools.partial(generate, factor=48271, criteria=8)
while True:
seed_a, seed_b = generate_a(seed_a), generate_b(seed_b)
yield judge(seed_a, seed_b)
seed_a, seed_b = parse(input)
return sum(itertools.islice(iter_judgements(seed_a, seed_b), 5000000))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

2
2017/d15/ex2/input Normal file
View file

@ -0,0 +1,2 @@
Generator A starts with 699
Generator B starts with 124

66
2017/d16/ex1/ex1.py Executable file
View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
import sys
from typing import NamedTuple
class Spin(NamedTuple):
n: int
class Exchange(NamedTuple):
a: int
b: int
class Partner(NamedTuple):
a: str
b: str
Move = Spin | Exchange | Partner
Programs = tuple[str, ...]
def solve(input: str) -> str:
def parse_move(input: str) -> Move:
if input[0] == "s":
return Spin(int(input[1:]))
if input[0] == "x":
return Exchange(*map(int, input[1:].split("/")))
if input[0] == "p":
return Partner(*input[1:].split("/"))
assert False # Sanity check
def parse(input: str) -> list[Move]:
return [parse_move(move) for move in input.strip().split(",")]
def apply_move(programs: Programs, move: Move) -> Programs:
match move:
case Spin(n):
return programs[-n:] + programs[:-n]
case Exchange(a, b):
tmp = list(programs)
tmp[a], tmp[b] = tmp[b], tmp[a]
return tuple(tmp)
case Partner(a, b):
ia, ib = programs.index(a), programs.index(b)
tmp = list(programs)
tmp[ia], tmp[ib] = tmp[ib], tmp[ia]
return tuple(tmp)
moves = parse(input)
programs = tuple(chr(ord("a") + i) for i in range(16))
for move in moves:
programs = apply_move(programs, move)
return "".join(programs)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d16/ex1/input Normal file

File diff suppressed because one or more lines are too long

82
2017/d16/ex2/ex2.py Executable file
View file

@ -0,0 +1,82 @@
#!/usr/bin/env python
import sys
from typing import NamedTuple
class Spin(NamedTuple):
n: int
class Exchange(NamedTuple):
a: int
b: int
class Partner(NamedTuple):
a: str
b: str
Move = Spin | Exchange | Partner
Programs = tuple[str, ...]
def solve(input: str) -> str:
def parse_move(input: str) -> Move:
if input[0] == "s":
return Spin(int(input[1:]))
if input[0] == "x":
return Exchange(*map(int, input[1:].split("/")))
if input[0] == "p":
return Partner(*input[1:].split("/"))
assert False # Sanity check
def parse(input: str) -> list[Move]:
return [parse_move(move) for move in input.strip().split(",")]
def apply_move(programs: Programs, move: Move) -> Programs:
match move:
case Spin(n):
return programs[-n:] + programs[:-n]
case Exchange(a, b):
tmp = list(programs)
tmp[a], tmp[b] = tmp[b], tmp[a]
return tuple(tmp)
case Partner(a, b):
ia, ib = programs.index(a), programs.index(b)
tmp = list(programs)
tmp[ia], tmp[ib] = tmp[ib], tmp[ia]
return tuple(tmp)
def do_dance(programs: Programs, moves: list[Move]) -> Programs:
t = 0
cache = {(programs, 0): 0}
TOTAL_MOVES = 1000000000 * len(moves)
while t < TOTAL_MOVES:
programs = apply_move(programs, moves[t % len(moves)])
t += 1
key = (programs, t % len(moves))
if (previous_t := cache.get(key)) is not None:
cycle_length = t - previous_t
num_cycles = (TOTAL_MOVES - t) // cycle_length
t += num_cycles * cycle_length
else:
cache[key] = t
return programs
moves = parse(input)
programs = tuple(chr(ord("a") + i) for i in range(16))
programs = do_dance(programs, moves)
return "".join(programs)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d16/ex2/input Normal file

File diff suppressed because one or more lines are too long

25
2017/d17/ex1/ex1.py Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env python
import collections
import sys
def solve(input: str) -> int:
def parse(input: str) -> int:
return int(input.strip())
lock = collections.deque([0])
step = parse(input)
for i in range(1, 2017 + 1):
lock.rotate(-step)
lock.append(i)
return lock[0]
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d17/ex1/input Normal file
View file

@ -0,0 +1 @@
377

25
2017/d17/ex2/ex2.py Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/env python
import collections
import sys
def solve(input: str) -> int:
def parse(input: str) -> int:
return int(input.strip())
lock = collections.deque([0])
step = parse(input)
for i in range(1, 50000000 + 1):
lock.rotate(-step)
lock.append(i)
return lock[lock.index(0) + 1]
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1
2017/d17/ex2/input Normal file
View file

@ -0,0 +1 @@
377

76
2017/d18/ex1/ex1.py Executable file
View file

@ -0,0 +1,76 @@
#!/usr/bin/env python
import collections
import enum
import sys
from typing import NamedTuple
class Op(enum.StrEnum):
SND = "snd"
SET = "set"
ADD = "add"
MUL = "mul"
MOD = "mod"
RCV = "rcv"
JGZ = "jgz"
class Instruction(NamedTuple):
op: Op
x: str
y: str | None = None
@classmethod
def from_str(cls, input: str) -> "Instruction":
op, *rest = input.split()
return cls(Op(op), *rest)
def solve(input: str) -> int:
def parse(input: str) -> list[Instruction]:
return [Instruction.from_str(line) for line in input.splitlines()]
def resolve(y: str | None, registers: dict[str, int]) -> int:
assert y is not None # Sanity check
try:
return int(y)
except ValueError:
return registers[y]
instructions = parse(input)
registers: dict[str, int] = collections.defaultdict(int)
ip = 0
freq: int | None = None
while True:
assert 0 <= ip < len(instructions) # Sanity check
instr = instructions[ip]
ip += 1
match instr.op:
case Op.SND:
freq = resolve(instr.x, registers)
case Op.SET:
registers[instr.x] = resolve(instr.y, registers)
case Op.ADD:
registers[instr.x] += resolve(instr.y, registers)
case Op.MUL:
registers[instr.x] *= resolve(instr.y, registers)
case Op.MOD:
registers[instr.x] %= resolve(instr.y, registers)
case Op.RCV:
if resolve(instr.x, registers) != 0:
assert freq is not None
return freq
case Op.JGZ:
if resolve(instr.x, registers) > 0:
ip += resolve(instr.y, registers) - 1 # Account auto-increment
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

41
2017/d18/ex1/input Normal file
View file

@ -0,0 +1,41 @@
set i 31
set a 1
mul p 17
jgz p p
mul a 2
add i -1
jgz i -2
add a -1
set i 127
set p 826
mul p 8505
mod p a
mul p 129749
add p 12345
mod p a
set b p
mod b 10000
snd b
add i -1
jgz i -9
jgz a 3
rcv b
jgz b -1
set f 0
set i 126
rcv a
rcv b
set p a
mul p -1
add p b
jgz p 4
snd a
set a b
jgz 1 3
snd b
set f 1
add i -1
jgz i -11
snd a
jgz f -16
jgz a -19

121
2017/d18/ex2/ex2.py Executable file
View file

@ -0,0 +1,121 @@
#!/usr/bin/env python
import collections
import dataclasses
import enum
import sys
from typing import NamedTuple
class Op(enum.StrEnum):
SND = "snd"
SET = "set"
ADD = "add"
MUL = "mul"
MOD = "mod"
RCV = "rcv"
JGZ = "jgz"
class Instruction(NamedTuple):
op: Op
x: str
y: str | None = None
@classmethod
def from_str(cls, input: str) -> "Instruction":
op, *rest = input.split()
return cls(Op(op), *rest)
@dataclasses.dataclass
class Program:
instructions: list[Instruction]
id: dataclasses.InitVar[int]
registers: dict[str, int] = dataclasses.field(init=False)
ip: int = dataclasses.field(init=False, default=0)
receive_queue: collections.deque[int] = dataclasses.field(
init=False, default_factory=collections.deque
)
send_queue: collections.deque[int] = dataclasses.field(
init=False, default_factory=collections.deque
)
values_sent: int = dataclasses.field(init=False, default=0)
def __post_init__(self, id: int) -> None:
self.registers = collections.defaultdict(int)
self.registers["p"] = id
def _resolve(self, y: str | None) -> int:
assert y is not None # Sanity check
try:
return int(y)
except ValueError:
return self.registers[y]
def execute(self) -> None:
while True:
assert 0 <= self.ip < len(self.instructions) # Sanity check
instr = self.instructions[self.ip]
match instr.op:
case Op.SND:
self.send_queue.append(self._resolve(instr.x))
self.values_sent += 1
case Op.SET:
self.registers[instr.x] = self._resolve(instr.y)
case Op.ADD:
self.registers[instr.x] += self._resolve(instr.y)
case Op.MUL:
self.registers[instr.x] *= self._resolve(instr.y)
case Op.MOD:
self.registers[instr.x] %= self._resolve(instr.y)
case Op.RCV:
if not self.receive_queue:
return # Block and wait for a value to be sent
self.registers[instr.x] = self.receive_queue.popleft()
case Op.JGZ:
if self._resolve(instr.x) > 0:
self.ip += self._resolve(instr.y) - 1 # Account auto-increment
self.ip += 1
@property
def is_terminated(self) -> bool:
# Has the program jumped outside the instructions
return self.ip < 0 or self.ip >= len(self.instructions)
@property
def is_blocked(self) -> bool:
if self.is_terminated:
return True
# Is it blocked on a `RCV`
return self.instructions[self.ip].op == Op.RCV and not self.receive_queue
def solve(input: str) -> int:
def parse(input: str) -> list[Instruction]:
return [Instruction.from_str(line) for line in input.splitlines()]
instructions = parse(input)
p0, p1 = Program(instructions, id=0), Program(instructions, id=1)
while True:
if p0.is_blocked and p1.is_blocked:
return p1.values_sent
p0.execute()
p1.execute()
p0.receive_queue.extend(p1.send_queue)
p1.send_queue.clear()
p1.receive_queue.extend(p0.send_queue)
p0.send_queue.clear()
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

41
2017/d18/ex2/input Normal file
View file

@ -0,0 +1,41 @@
set i 31
set a 1
mul p 17
jgz p p
mul a 2
add i -1
jgz i -2
add a -1
set i 127
set p 826
mul p 8505
mod p a
mul p 129749
add p 12345
mod p a
set b p
mod b 10000
snd b
add i -1
jgz i -9
jgz a 3
rcv b
jgz b -1
set f 0
set i 126
rcv a
rcv b
set p a
mul p -1
add p b
jgz p 4
snd a
set a b
jgz 1 3
snd b
set f 1
add i -1
jgz i -11
snd a
jgz f -16
jgz a -19

73
2017/d19/ex1/ex1.py Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env python
import enum
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
class Direction(enum.Enum):
UP = Point(-1, 0)
DOWN = Point(1, 0)
LEFT = Point(0, -1)
RIGHT = Point(0, 1)
def apply(self, p: Point) -> Point:
dx, dy = self.value
return Point(p.x + dx, p.y + dy)
def turns(self) -> Iterator["Direction"]:
match self:
case Direction.UP | Direction.DOWN:
turns = (Direction.LEFT, Direction.RIGHT)
case Direction.LEFT | Direction.RIGHT:
turns = (Direction.UP, Direction.DOWN)
yield from turns
def solve(input: str) -> str:
def parse(input: str) -> dict[Point, str]:
return {
Point(x, y): c
for x, line in enumerate(input.splitlines())
for y, c in enumerate(line)
if c != " "
}
def packet_spell(map: dict[Point, str]) -> str:
letters: list[str] = []
# Travel starts downward, from outside the map before the first line
pos = min(map.keys(), key=lambda p: p.x)
dir = Direction.DOWN
while True:
if (letter := map[pos]) not in ("+", "|", "-"):
letters.append(letter)
new_dir = dir
new_pos = dir.apply(pos)
if new_pos not in map:
for new_dir in dir.turns():
if (new_pos := new_dir.apply(pos)) in map:
break
else:
# Must be the end of the line, stop looping
return "".join(letters)
dir = new_dir
pos = new_pos
map = parse(input)
return packet_spell(map)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

201
2017/d19/ex1/input Normal file
View file

@ -0,0 +1,201 @@
|
+---+ +-------------------------------+ +---+ +---------+ +---------------------------|-------------------------------------------------------------------------+ +-----+
| | | | | | | | | | | | |
| +-----|---------+ +---------------------|---|-----|-------------|---------------------------|-------------------------------------------------------------------------+ | +-------+
| | | | | | | | | | | | |
| +---+ +---------+ | | | | +-------------------------------------------------------------------------------------------------------+ A-+ +-----------------------+
| | | | | | | | | | | | | | | | | |
| | | | | | +---------------------|-----|---------|-----------+ | +-----------------------------------------------+ |
| | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +---------|-----------|-------------------|---------------------|-----------------------------------------|-----------|-------------+
| R | | | | | | | | | | | | | | | | | | | |
| | | | +-------|---------------------------|-------------|-----------|-------------------|---------------------|-------------+ +-----------|-----|-----|-----+ +-------+
| | | | | | | | | | | | | | | | | | | | | | | |
| +---------|-------+ | | | | | +-|---------+ +-|---|-----+ | +-----------------|---------------------|-------+ | | +-|-----|-|---|-----------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+-------------------|-----|-|-|-------|-------|---------|-----+ | | | | | | +-----------------|---------------------------------------------|---------|---------|---|-----------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-----+ +---|---|-----|---|-----------------|-----------------|-----------|-|-------------------------------------+ | | | +---------|-|---+ +-|---------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-+ | | | | | | | | | | | | | +---------------------|-----------------------------|-----|-------------------|-|---+ | |
| | | | | | | | | | | | | | | | | | | | | | | |
| +---------------------+ | | | | | | | | | +-|-----------------------------------------|-------|-------------------------|-|-------|-------+ +-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +---------+ | | | | | | | | | | | | | | | | | | | | | | +---------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+---+ | | | +-+ | | | | +-----+ | +-|---------------+ | | +-|-------|-------------------|-+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | W | |
+-------|-|-|-|-+ | | | | | +-------------|-------------------|-|-|-------|-|-------------------------------------|-----------|-----------------+ +-|-----------|-----------------+ |
| | | | | | | | | | | | | | | | | | | | | | | H | | | | | | | | | | | |
| | +-|-------+ | | | | | | | | | | | | | | +---------|---------------------|-------|-----|---------------------------------|-|---------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-----|-|---+ | | | +---+ | | +-|-----------------------|-----|-------+ | | | | | | | | | | +-|-|-------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | +-------------------|-------|-----|---------+ | | +---------------+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +-+ | | | | | | | | +-------------|-----------------|-+ | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +-----------------------------------------|-----|-------|---------|---------|-----------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|-|-|-+ | | | | +-|-|-------|-------------------------------|-|---|-----|-|---------|---------|-----------|-------|-+ | | | | | | +-+ | | | | +-+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|---------|-+ | +---------|-|---|-+ | | +-------+ +-------|-|---------|---------------------|-----------|-----------------------------------|---+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-------------------------------------------|-----|-|-------|---+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | +---------|---|-----|-------------------------------------|-----------|---------------------|-|---|-|---------|-----|---------------|-----+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-----|-|---|-|-|---|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|-|-|---|---|-|-|-------+ | | | | | +-----+ | | | | | | +---------------------+ | | | | | | | +-------------|-|---------|---|-----------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | +-----------|-----------------------|-|---------------------|---------------------|-----------+ +-----------|---------+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+-------|-|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-------+ | | | | | | | | | +---------|-------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | +---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-|-|-----|---|-|-|-|-------------------------------------|-|-------------------------------|---------|-|-|-----|-|-------------+ | | | | | | | +-------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+---------|---+ | | | | | | | +-----+ | | | | | | | +-|-|-------------------|---------|---|-----|---|-----|-----------------------+ | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +---|---------------------------------------|---+ | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-----|-|---------|-|---------------|-----------------------|-|---------|-|-|-------------------|-+ | | | | | | | | | | | | | | | | | | +-+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+---------------|-----|---------------|---|---|---------+ +-----+ | | | +-----|-|-------|-+ +---------------|-|-|---|-|---------|---------------------|-|-----------|-----|-----|---|-+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-|-------|-|---|---|-------|---------|-------------------|-|---------|-------------------------------|-----|-|-|-|---------------------------|---------|-----|---|-----|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-|---|---|-|-+ | | | +-----|-|-------|---------------------|-+ | | | +-----------|-------|---------|-|-----|-|-------|-------+ | | +-+ | +-|-|-----|-+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-+ | | | | | | | | | | | | | | | | +-----|-----------------|-|---|-----|-----------|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | U | | | | | | |
| | | | | | | | | | | | | +-----|-|-------|-----------|-----------------------------------------|---+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +-----|-|---|-|---|-----|-----------|-----|-------|---|-|---|-|-|-----------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|---|-|-----------|---|-|-|-------|-|-----|-------|-------------------|----------------E--+ | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | +-------|---|---------------|-------|-----|---+ | | | +-|-------|---|-|-|---|-|-|-----------------------------|---|-----|-----|-------+ +---|-------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | +---|---|-|-|-|---|---|-----|---------------------------|-|-------|---|---+ | +---|---|-|-------|-----|-|-+ | | | +-----+ | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|-----------------------------|-|-|---------------|-------|-----|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | +-----------------|-----------|-----------|-----------------------|-------|-|-|-----------------------+ | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | +---------------|-------------|---|---|-|---------|-|---------------|---|-|-----|-------------------|-----------|---|---|---------|-+ +-|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-|-----|-----|---|---|---------|-|-----------------|---------------|-------------|-------------|-|---|---------|-----|-----------------------------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---------|-----|-----|-----------------------------------|---|-|---|---------|-+ | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | +---|---------|-|-|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-|-----|---|-|---|---|-|---------------+ | | +-|-------|-------|-----------+ +-|-|-|-|---|-------|-|---|---------------------|-------+ | | +---+ | | +-|-----|---+ | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-----------|-|-|---------|-|---|---|-----|-|---------------|-----+ | | | | | +-|-|-----+ +-|-|-|---|-|---+ | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|-+ | +-------+ | | +-----------|-|-------------------------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +---|---------+ | | +-|-|-|-------|-----|-|-----------|-------------|-|---|---|-----+ | | | | | | | | | | | | +---|---|-+ | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | N | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | +-|-----|---|-+ | | +-----|---|-------------|-|-------+ | | +---|---|-|-----|-----------------------------|---|-|--D|---|-----|---+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +---|---|-|-----|-|-|-|-----|-|---|-----------|-|-----|-|-----|-|-----|---|-------|---------------|-------|-|---------|-------------------|---------|-----|---|---|-|---|-----|---|-+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | +-------|-|-----|-|-|-----------|-|-+ | | | | | | | | | | +-------|---------+ | | | | | | +-------+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-------|---+ | | | | | | | | | | | | | | | | | | | | | | | +-+ +-|-----|-----|---+ | | | | | | +-------|---------|---------+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +---|-------+ | +-----------|-------|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|---+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-|-|-----|-------|-|-|-----|-----------|-+ | | | | | | | | +-|-------+ | | +---------------+ | +-+ | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-----------|-------|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|-------------|---+ | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-------|-----|---|-------------|-|---|---|---------|---|---|-|-----+ | | +---------|-|---|-|-----|-------------------|-------|-------+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | +---|-|-----|---------------|-|---------|---|---|---------|-|---------------------|-----|---|-------+ | | | | | | +-|---|-+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|-------+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | +-|-------|---|---|---|---------|-----+ | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-|-+ | | | | | | | | | | | | | | | | | | | | | | | | +-----------------|-----|---------|-----------------------------|---------|-------------|---|-|---|-|-----+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | +-----------------|-------------|---------|-----+ | | +---------------|---|---|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-------------|-|-|-----|---|---|-|-|---------|---|---------|---------------------------|-----|-----|---------|---------|-------------------|---------|---------+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +---------|-+ | +-----|-|-|---|-|-|---+ | | | | | | | | +---------------------------|-------------------|-------------+ +---------|----------Y--+ | | | | +---|-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | +-|---|-----------|---------|---------|---|---------|---|-----+ +---|-|-----|-----|---------+ | | +-----------------------------+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | +-----|-|-----|---|-------|-|---|-----|-----------------------------|---------------------------------|---|-------------------------------------|-----+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +-|---|-------|-------|-|-----|---|-----|---------+ | | | | +-------------+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|---|-------|-------|---|-----|-|-------|-|-|-|---------------|-|-----|-----|---------------|-|-----------|-------|-----------|-------------|---|-----------|-------------------------------+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +---------|-------|---|-|-|-|---------|-|-----|---|-----|---|---|-----------------|---|-------------|---------------+ | | | | +-+ | | | +-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|-|---+ | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|-----------------|---------------------------------------------|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | +---+ | | | | +---+ | | | | | | | +---|-----------+ | | | | +-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----------|-|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|---|-------------|---|---|-|---------------+ | | | | | | | | | | | | | | | +---|-----------------|-----+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-------|-----|-|-|---|-|---+ +---|-|-------|-|---------|-|-----------|---------------|-|---+ | | | | | | | | +---|-------|-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-+ | | +-|-----------|-|-----|---|---------+ | | | | | | | | | | | | | | | | +---------------|-----------------|-+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | +---|-|---|-|---|-----|-|-----------------------|---|-----|-------|-------|-----------|---------|-------------------|-----+ | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | +-----------------------------------|-----------+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-----|-----|---|O------------------|-|---|-|---+ | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-|---------------|-----|---|-----------|-----|-|---+ | | | | | | | | | | | | | +-----|-----|-----------+ +-----+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-----------|-----+ | | | | | | | | | | +-----------|-----------|-------------------------|-----------------------------|-----------------|-------------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-------------|-------|-----|-|-|-----------------|-|-----------------------------------|-----|---|-----|---------|-----------------------------|-----------|---------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +-----------------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-+ +-----+ +---------|-----|-------------------|-----------|-----------------+ | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-----------+ | | +-|-|-----------|-----+ | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-|-+ | +-|-+ | | | | | | | | | | | | | | | | | +---|-----+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | +-----+ +---------|-----------|-------|---------|-------+ | | | +-+ | +-------------------------|-------------|---|-----------|---------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | +-----+ | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-+ | | | +-----------------------|-----------|-------|---------|-------+ +-|---+ +-----------+ | | | +-------------------------|-+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +---|-------|-+ | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | |
+-------|-------------|-------------|-------------------|---------|---------+ | | | +-----------|-----+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | |
+-|-+ | +---|-+ | | +-----------------|---------+ | +---------+ | | | | | | | | |
| | | | | | | | | | | | | | | | | | | |
| +---+ +---------+ | +---------------------------------------+ | +---------------+ | | | | | | | +-------------------+
| | | | | | | | | | | | | | | | | |
+-+ +-----+ +---------------------|---------|-----------+ +-------------------|-------------------------------+ +-+ | | |
| | | | | | | | | |
| +-------------------+ | | +-----------+ |
| | | | | |
+-------------------------------------------------------+ +---------------------------------+ +-------------------------------------------------------+

75
2017/d19/ex2/ex2.py Executable file
View file

@ -0,0 +1,75 @@
#!/usr/bin/env python
import enum
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
class Direction(enum.Enum):
UP = Point(-1, 0)
DOWN = Point(1, 0)
LEFT = Point(0, -1)
RIGHT = Point(0, 1)
def apply(self, p: Point) -> Point:
dx, dy = self.value
return Point(p.x + dx, p.y + dy)
def turns(self) -> Iterator["Direction"]:
match self:
case Direction.UP | Direction.DOWN:
turns = (Direction.LEFT, Direction.RIGHT)
case Direction.LEFT | Direction.RIGHT:
turns = (Direction.UP, Direction.DOWN)
yield from turns
def solve(input: str) -> int:
def parse(input: str) -> dict[Point, str]:
return {
Point(x, y): c
for x, line in enumerate(input.splitlines())
for y, c in enumerate(line)
if c != " "
}
def packet_walk(map: dict[Point, str]) -> int:
letters: list[str] = []
# Travel starts downward, from outside the map before the first line
pos = min(map.keys(), key=lambda p: p.x)
dir = Direction.DOWN
steps = 0
while True:
if (letter := map[pos]) not in ("+", "|", "-"):
letters.append(letter)
new_dir = dir
new_pos = dir.apply(pos)
steps += 1
if new_pos not in map:
for new_dir in dir.turns():
if (new_pos := new_dir.apply(pos)) in map:
break
else:
# Must be the end of the line, stop looping
return steps
dir = new_dir
pos = new_pos
map = parse(input)
return packet_walk(map)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

201
2017/d19/ex2/input Normal file
View file

@ -0,0 +1,201 @@
|
+---+ +-------------------------------+ +---+ +---------+ +---------------------------|-------------------------------------------------------------------------+ +-----+
| | | | | | | | | | | | |
| +-----|---------+ +---------------------|---|-----|-------------|---------------------------|-------------------------------------------------------------------------+ | +-------+
| | | | | | | | | | | | |
| +---+ +---------+ | | | | +-------------------------------------------------------------------------------------------------------+ A-+ +-----------------------+
| | | | | | | | | | | | | | | | | |
| | | | | | +---------------------|-----|---------|-----------+ | +-----------------------------------------------+ |
| | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +---------|-----------|-------------------|---------------------|-----------------------------------------|-----------|-------------+
| R | | | | | | | | | | | | | | | | | | | |
| | | | +-------|---------------------------|-------------|-----------|-------------------|---------------------|-------------+ +-----------|-----|-----|-----+ +-------+
| | | | | | | | | | | | | | | | | | | | | | | |
| +---------|-------+ | | | | | +-|---------+ +-|---|-----+ | +-----------------|---------------------|-------+ | | +-|-----|-|---|-----------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+-------------------|-----|-|-|-------|-------|---------|-----+ | | | | | | +-----------------|---------------------------------------------|---------|---------|---|-----------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-----+ +---|---|-----|---|-----------------|-----------------|-----------|-|-------------------------------------+ | | | +---------|-|---+ +-|---------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-+ | | | | | | | | | | | | | +---------------------|-----------------------------|-----|-------------------|-|---+ | |
| | | | | | | | | | | | | | | | | | | | | | | |
| +---------------------+ | | | | | | | | | +-|-----------------------------------------|-------|-------------------------|-|-------|-------+ +-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +---------+ | | | | | | | | | | | | | | | | | | | | | | +---------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+---+ | | | +-+ | | | | +-----+ | +-|---------------+ | | +-|-------|-------------------|-+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | W | |
+-------|-|-|-|-+ | | | | | +-------------|-------------------|-|-|-------|-|-------------------------------------|-----------|-----------------+ +-|-----------|-----------------+ |
| | | | | | | | | | | | | | | | | | | | | | | H | | | | | | | | | | | |
| | +-|-------+ | | | | | | | | | | | | | | +---------|---------------------|-------|-----|---------------------------------|-|---------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-----|-|---+ | | | +---+ | | +-|-----------------------|-----|-------+ | | | | | | | | | | +-|-|-------------+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | +-------------------|-------|-----|---------+ | | +---------------+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +-+ | | | | | | | | +-------------|-----------------|-+ | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +-----------------------------------------|-----|-------|---------|---------|-----------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|-|-|-+ | | | | +-|-|-------|-------------------------------|-|---|-----|-|---------|---------|-----------|-------|-+ | | | | | | +-+ | | | | +-+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|---------|-+ | +---------|-|---|-+ | | +-------+ +-------|-|---------|---------------------|-----------|-----------------------------------|---+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-------------------------------------------|-----|-|-------|---+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | +---------|---|-----|-------------------------------------|-----------|---------------------|-|---|-|---------|-----|---------------|-----+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-----|-|---|-|-|---|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|-|-|---|---|-|-|-------+ | | | | | +-----+ | | | | | | +---------------------+ | | | | | | | +-------------|-|---------|---|-----------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | +-----------|-----------------------|-|---------------------|---------------------|-----------+ +-----------|---------+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+-------|-|-|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-------+ | | | | | | | | | +---------|-------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | +---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-|-|-----|---|-|-|-|-------------------------------------|-|-------------------------------|---------|-|-|-----|-|-------------+ | | | | | | | +-------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+---------|---+ | | | | | | | +-----+ | | | | | | | +-|-|-------------------|---------|---|-----|---|-----|-----------------------+ | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +---|---------------------------------------|---+ | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-----|-|---------|-|---------------|-----------------------|-|---------|-|-|-------------------|-+ | | | | | | | | | | | | | | | | | | +-+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+---------------|-----|---------------|---|---|---------+ +-----+ | | | +-----|-|-------|-+ +---------------|-|-|---|-|---------|---------------------|-|-----------|-----|-----|---|-+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-|-------|-|---|---|-------|---------|-------------------|-|---------|-------------------------------|-----|-|-|-|---------------------------|---------|-----|---|-----|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-|---|---|-|-+ | | | +-----|-|-------|---------------------|-+ | | | +-----------|-------|---------|-|-----|-|-------|-------+ | | +-+ | +-|-|-----|-+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-+ | | | | | | | | | | | | | | | | +-----|-----------------|-|---|-----|-----------|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | U | | | | | | |
| | | | | | | | | | | | | +-----|-|-------|-----------|-----------------------------------------|---+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +-----|-|---|-|---|-----|-----------|-----|-------|---|-|---|-|-|-----------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|---|-|-----------|---|-|-|-------|-|-----|-------|-------------------|----------------E--+ | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | +-------|---|---------------|-------|-----|---+ | | | +-|-------|---|-|-|---|-|-|-----------------------------|---|-----|-----|-------+ +---|-------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | +---|---|-|-|-|---|---|-----|---------------------------|-|-------|---|---+ | +---|---|-|-------|-----|-|-+ | | | +-----+ | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|-----------------------------|-|-|---------------|-------|-----|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | +-----------------|-----------|-----------|-----------------------|-------|-|-|-----------------------+ | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | +---------------|-------------|---|---|-|---------|-|---------------|---|-|-----|-------------------|-----------|---|---|---------|-+ +-|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-|-----|-----|---|---|---------|-|-----------------|---------------|-------------|-------------|-|---|---------|-----|-----------------------------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---------|-----|-----|-----------------------------------|---|-|---|---------|-+ | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | +---|---------|-|-|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-|---|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-|-----|---|-|---|---|-|---------------+ | | +-|-------|-------|-----------+ +-|-|-|-|---|-------|-|---|---------------------|-------+ | | +---+ | | +-|-----|---+ | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-----------|-|-|---------|-|---|---|-----|-|---------------|-----+ | | | | | +-|-|-----+ +-|-|-|---|-|---+ | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|-+ | +-------+ | | +-----------|-|-------------------------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +---|---------+ | | +-|-|-|-------|-----|-|-----------|-------------|-|---|---|-----+ | | | | | | | | | | | | +---|---|-+ | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | N | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | +-|-----|---|-+ | | +-----|---|-------------|-|-------+ | | +---|---|-|-----|-----------------------------|---|-|--D|---|-----|---+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +---|---|-|-----|-|-|-|-----|-|---|-----------|-|-----|-|-----|-|-----|---|-------|---------------|-------|-|---------|-------------------|---------|-----|---|---|-|---|-----|---|-+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | +-------|-|-----|-|-|-----------|-|-+ | | | | | | | | | | +-------|---------+ | | | | | | +-------+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-------|---+ | | | | | | | | | | | | | | | | | | | | | | | +-+ +-|-----|-----|---+ | | | | | | +-------|---------|---------+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +---|-------+ | +-----------|-------|-----+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|---+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-|-|-----|-------|-|-|-----|-----------|-+ | | | | | | | | +-|-------+ | | +---------------+ | +-+ | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-----------|-------|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|-------------|---+ | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +---|-------|-----|---|-------------|-|---|---|---------|---|---|-|-----+ | | +---------|-|---|-|-----|-------------------|-------|-------+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | +---|-|-----|---------------|-|---------|---|---|---------|-|---------------------|-----|---|-------+ | | | | | | +-|---|-+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----|-------+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | +-|-------|---|---|---|---------|-----+ | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-|-+ | | | | | | | | | | | | | | | | | | | | | | | | +-----------------|-----|---------|-----------------------------|---------|-------------|---|-|---|-|-----+ | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | +-----------------|-------------|---------|-----+ | | +---------------|---|---|-+ | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-------------|-|-|-----|---|---|-|-|---------|---|---------|---------------------------|-----|-----|---------|---------|-------------------|---------|---------+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +---------|-+ | +-----|-|-|---|-|-|---+ | | | | | | | | +---------------------------|-------------------|-------------+ +---------|----------Y--+ | | | | +---|-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | +-|---|-----------|---------|---------|---|---------|---|-----+ +---|-|-----|-----|---------+ | | +-----------------------------+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | +-----|-|-----|---|-------|-|---|-----|-----------------------------|---------------------------------|---|-------------------------------------|-----+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | +-|---|-------|-------|-|-----|---|-----|---------+ | | | | +-------------+ | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|---|-------|-------|---|-----|-|-------|-|-|-|---------------|-|-----|-----|---------------|-|-----------|-------|-----------|-------------|---|-----------|-------------------------------+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +---------|-------|---|-|-|-|---------|-|-----|---|-----|---|---|-----------------|---|-------------|---------------+ | | | | +-+ | | | +-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|-|---+ | | | | | | | | | | | | | | | | | | | | | | | | | | | +---|-----------------|---------------------------------------------|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | +---+ | | | | +---+ | | | | | | | +---|-----------+ | | | | +-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-|-+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | +-----------|-|---+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-|---|-------------|---|---|-|---------------+ | | | | | | | | | | | | | | | +---|-----------------|-----+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | +-------|-----|-|-|---|-|---+ +---|-|-------|-|---------|-|-----------|---------------|-|---+ | | | | | | | | +---|-------|-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-+ | | +-|-----------|-|-----|---|---------+ | | | | | | | | | | | | | | | | +---------------|-----------------|-+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | +---|-|---|-|---|-----|-|-----------------------|---|-----|-------|-------|-----------|---------|-------------------|-----+ | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | +-----------------------------------|-----------+ | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-----|-----|---|O------------------|-|---|-|---+ | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-|---------------|-----|---|-----------|-----|-|---+ | | | | | | | | | | | | | +-----|-----|-----------+ +-----+ |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-----------|-----+ | | | | | | | | | | +-----------|-----------|-------------------------|-----------------------------|-----------------|-------------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | +-------------|-------|-----|-|-|-----------------|-|-----------------------------------|-----|---|-----|---------|-----------------------------|-----------|---------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +-----------------+ | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +-+ +-----+ +---------|-----|-------------------|-----------|-----------------+ | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-----------+ | | +-|-|-----------|-----+ | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | +-|-+ | +-|-+ | | | | | | | | | | | | | | | | | +---|-----+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | +-----+ +---------|-----------|-------|---------|-------+ | | | +-+ | +-------------------------|-------------|---|-----------|---------------------+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | +-----+ | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | |
| +-+ | | | +-----------------------|-----------|-------|---------|-------+ +-|---+ +-----------+ | | | +-------------------------|-+ | | |
| | | | | | | | | | | | | | | | | | | | | | | | | |
| | | +---|-------|-+ | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | |
+-------|-------------|-------------|-------------------|---------|---------+ | | | +-----------|-----+ | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | |
+-|-+ | +---|-+ | | +-----------------|---------+ | +---------+ | | | | | | | | |
| | | | | | | | | | | | | | | | | | | |
| +---+ +---------+ | +---------------------------------------+ | +---------------+ | | | | | | | +-------------------+
| | | | | | | | | | | | | | | | | |
+-+ +-----+ +---------------------|---------|-----------+ +-------------------|-------------------------------+ +-+ | | |
| | | | | | | | | |
| +-------------------+ | | +-----------+ |
| | | | | |
+-------------------------------------------------------+ +---------------------------------+ +-------------------------------------------------------+

52
2017/d20/ex1/ex1.py Executable file
View file

@ -0,0 +1,52 @@
#!/usr/bin/env python
import sys
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
z: int
class Particle(NamedTuple):
pos: Point
vel: Point
acc: Point
@classmethod
def from_str(cls, input: str) -> "Particle":
p, v, a = input.split(", ")
return cls(
Point(*map(int, p[3:-1].split(","))),
Point(*map(int, v[3:-1].split(","))),
Point(*map(int, a[3:-1].split(","))),
)
def solve(input: str) -> int:
def parse(input: str) -> list[Particle]:
return [Particle.from_str(line) for line in input.splitlines()]
def dist(point: Point, other: Point) -> int:
return sum(abs(a - b) for a, b in zip(point, other))
particles = parse(input)
orig = Point(0, 0, 0)
# Lowest acceleration will be closest to origin as time tends to infinity
# Same logic for velocity and position
closest_particle = min(
particles,
key=lambda p: (dist(p.acc, orig), dist(p.vel, orig), dist(p.pos, orig)),
)
return particles.index(closest_particle)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1000
2017/d20/ex1/input Normal file

File diff suppressed because it is too large Load diff

57
2017/d20/ex2/ex2.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env python
import collections
import sys
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
z: int
class Particle(NamedTuple):
pos: Point
vel: Point
acc: Point
@classmethod
def from_str(cls, input: str) -> "Particle":
p, v, a = input.split(", ")
return cls(
Point(*map(int, p[3:-1].split(","))),
Point(*map(int, v[3:-1].split(","))),
Point(*map(int, a[3:-1].split(","))),
)
def tick(self) -> "Particle":
pos, vel, acc = self
vel = Point(*((v + a) for v, a in zip(vel, acc)))
pos = Point(*((p + v) for p, v in zip(pos, vel)))
return Particle(pos, vel, acc)
def solve(input: str) -> int:
def parse(input: str) -> list[Particle]:
return [Particle.from_str(line) for line in input.splitlines()]
def tick(particles: list[Particle]) -> list[Particle]:
particles = [p.tick() for p in particles]
positions = collections.Counter(p.pos for p in particles)
return [p for p in particles if positions[p.pos] == 1]
particles = parse(input)
# Guesstimate that 1000 iterations is enough to process all colisions
for _ in range(1000):
particles = tick(particles)
return len(particles)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

1000
2017/d20/ex2/input Normal file

File diff suppressed because it is too large Load diff

88
2017/d21/ex1/ex1.py Executable file
View file

@ -0,0 +1,88 @@
#!/usr/bin/env python
import itertools
import sys
from collections.abc import Iterator
# 2x2 *and* 3x3 grid
Grid = tuple[tuple[bool, ...], ...]
START = ".#./..#/###"
def solve(input: str) -> int:
def parse_pattern(input: str) -> Grid:
return tuple(tuple(c == "#" for c in line) for line in input.split("/"))
def parse(input: str) -> dict[Grid, Grid]:
return {
start: end
for start, end in (
map(parse_pattern, line.split(" => ")) for line in input.splitlines()
)
}
def permutations(grid: Grid) -> set[Grid]:
def iter_rotated(grid: Grid) -> Iterator[Grid]:
for _ in range(4):
yield grid
grid = tuple(
tuple(grid[len(grid) - y - 1][x] for y in range(len(grid[0])))
for x in range(len(grid))
)
def iter_flipped(grid: Grid) -> Iterator[Grid]:
yield grid
yield grid[::-1]
yield tuple(line[::-1] for line in grid)
return {
flip for rotated in iter_rotated(grid) for flip in iter_flipped(rotated)
}
def normalize_rules(raw_rules: dict[Grid, Grid]) -> dict[Grid, Grid]:
res: dict[Grid, Grid] = {}
for pattern, grid in raw_rules.items():
for perm in permutations(pattern):
res[perm] = grid
return res
def enhance(rules: dict[Grid, Grid], rounds: int) -> list[list[bool]]:
def step(grid: list[list[bool]]) -> list[list[bool]]:
is_even = len(grid) % 2 == 0
step_size = 2 if is_even else 3
next_size = len(grid) * (step_size + 1) // step_size
res = [[False for _ in range(next_size)] for _ in range(next_size)]
for x, y in itertools.product(range(len(grid) // step_size), repeat=2):
elem = tuple(
tuple(
grid[x * step_size + dx][y * step_size + dy]
for dy in range(step_size)
)
for dx in range(step_size)
)
new_grid = rules[elem]
for dx, line in enumerate(new_grid):
for dy, p in enumerate(line):
res[x * len(new_grid) + dx][y * len(line) + dy] = p
return res
grid = [[p for p in line] for line in parse_pattern(START)]
for _ in range(rounds):
grid = step(grid)
return grid
raw_rules = parse(input)
norm_rules = normalize_rules(raw_rules)
art = enhance(norm_rules, 5)
return sum(itertools.chain.from_iterable(art))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

108
2017/d21/ex1/input Normal file
View file

@ -0,0 +1,108 @@
../.. => #.#/#../...
#./.. => #.#/#.#/.#.
##/.. => #../.##/##.
.#/#. => ..#/..#/..#
##/#. => ##./.#./#..
##/## => .../.#./.#.
.../.../... => ..#./##.#/#.##/##.#
#../.../... => #.##/..../##../###.
.#./.../... => ##.#/###./#.##/#.#.
##./.../... => ##.#/#.##/.#../##.#
#.#/.../... => ...#/..#./.#.#/.###
###/.../... => ..../#..#/#.##/##..
.#./#../... => .#../.#.#/..#./.###
##./#../... => ..##/#.##/#.../#.#.
..#/#../... => .##./#.##/.#../##..
#.#/#../... => #.../.##./...#/###.
.##/#../... => #.##/..##/.#.#/##..
###/#../... => #..#/...#/..#./...#
.../.#./... => .###/.#../..#./####
#../.#./... => ####/#.../.###/##..
.#./.#./... => ####/#..#/####/#..#
##./.#./... => .#../..##/..##/#..#
#.#/.#./... => .#.#/#.##/#.#./.#.#
###/.#./... => #.##/#.../###./#..#
.#./##./... => ###./#.../..../.###
##./##./... => #.##/###./...#/###.
..#/##./... => .#.#/###./..#./#...
#.#/##./... => #.#./##../##../..##
.##/##./... => ..../..#./.##./.#.#
###/##./... => #.../.#../#.#./#..#
.../#.#/... => ##../#.##/.##./.##.
#../#.#/... => #.#./##.#/.###/.###
.#./#.#/... => ..../####/####/.#.#
##./#.#/... => #.##/.###/##../#...
#.#/#.#/... => ###./..##/#.#./####
###/#.#/... => .##./..../###./....
.../###/... => ###./.##./##../.###
#../###/... => .#../#.../###./...#
.#./###/... => #.#./#.#./####/###.
##./###/... => ...#/##../###./#.#.
#.#/###/... => .#.#/#.#./..#./.##.
###/###/... => ..../#.##/...#/##..
..#/.../#.. => ...#/#.##/#..#/..##
#.#/.../#.. => ..#./##.#/.#.#/..##
.##/.../#.. => ..##/##../#.#./#.##
###/.../#.. => #.##/###./...#/.##.
.##/#../#.. => ##../#.##/##.#/##..
###/#../#.. => #.##/##../.##./.#.#
..#/.#./#.. => #..#/##../.###/#.#.
#.#/.#./#.. => .###/#.##/#.#./####
.##/.#./#.. => #.#./#.../#.##/...#
###/.#./#.. => .##./.#.#/#.#./.#.#
.##/##./#.. => .###/.#.#/...#/#.#.
###/##./#.. => .###/#.##/#.##/#.#.
#../..#/#.. => #.../##../.##./###.
.#./..#/#.. => #.../#.##/#.../###.
##./..#/#.. => ####/..../##.#/.###
#.#/..#/#.. => ..##/##.#/#.##/#..#
.##/..#/#.. => ..#./##.#/#.#./..##
###/..#/#.. => ..##/...#/#..#/#..#
#../#.#/#.. => #.../..../#.../#.##
.#./#.#/#.. => ##../####/.#.#/##..
##./#.#/#.. => .#../..../#.../.##.
..#/#.#/#.. => .#../.#.#/.#.#/..#.
#.#/#.#/#.. => ..#./#.##/#.#./..##
.##/#.#/#.. => #.##/..##/...#/####
###/#.#/#.. => .##./.#.#/###./#..#
#../.##/#.. => ..##/.###/.#../##.#
.#./.##/#.. => #.##/.##./.##./.###
##./.##/#.. => .##./.#../..../..##
#.#/.##/#.. => ..../#.#./##.#/###.
.##/.##/#.. => #..#/..../##.#/..#.
###/.##/#.. => ####/##.#/#..#/##..
#../###/#.. => #.#./###./.###/#...
.#./###/#.. => ##.#/#..#/#.##/..#.
##./###/#.. => ..#./...#/..##/...#
..#/###/#.. => .#.#/..../..##/..##
#.#/###/#.. => #..#/..#./.#../..#.
.##/###/#.. => .#.#/..../#..#/...#
###/###/#.. => #.##/##../.#../....
.#./#.#/.#. => ..../####/.###/.#.#
##./#.#/.#. => #.##/...#/####/####
#.#/#.#/.#. => ..#./##../..../#...
###/#.#/.#. => ####/#.##/###./...#
.#./###/.#. => ...#/..#./...#/..#.
##./###/.#. => .##./#.../.#.#/.###
#.#/###/.#. => ..../..../.#.#/#.##
###/###/.#. => ..#./###./##.#/....
#.#/..#/##. => .###/.#../..#./####
###/..#/##. => #.##/..#./#..#/....
.##/#.#/##. => #.../##../####/.##.
###/#.#/##. => ###./..#./..#./##..
#.#/.##/##. => #.../##../##.#/#.##
###/.##/##. => ..#./#..#/#.##/####
.##/###/##. => .#.#/.###/...#/.#..
###/###/##. => ####/..../.#.#/...#
#.#/.../#.# => ##.#/#..#/.##./...#
###/.../#.# => #.#./.#../...#/...#
###/#../#.# => .#.#/.#../##../##..
#.#/.#./#.# => ###./#.../####/.#.#
###/.#./#.# => ##../#.#./..##/##.#
###/##./#.# => ####/..../###./.##.
#.#/#.#/#.# => ...#/.##./##../.###
###/#.#/#.# => ..#./.##./##.#/.#..
#.#/###/#.# => ...#/..../..#./...#
###/###/#.# => #.#./#.#./##../....
###/#.#/### => #.../##.#/.#../..#.
###/###/### => ##../..#./##../..#.

88
2017/d21/ex2/ex2.py Executable file
View file

@ -0,0 +1,88 @@
#!/usr/bin/env python
import itertools
import sys
from collections.abc import Iterator
# 2x2 *and* 3x3 grid
Grid = tuple[tuple[bool, ...], ...]
START = ".#./..#/###"
def solve(input: str) -> int:
def parse_pattern(input: str) -> Grid:
return tuple(tuple(c == "#" for c in line) for line in input.split("/"))
def parse(input: str) -> dict[Grid, Grid]:
return {
start: end
for start, end in (
map(parse_pattern, line.split(" => ")) for line in input.splitlines()
)
}
def permutations(grid: Grid) -> set[Grid]:
def iter_rotated(grid: Grid) -> Iterator[Grid]:
for _ in range(4):
yield grid
grid = tuple(
tuple(grid[len(grid) - y - 1][x] for y in range(len(grid[0])))
for x in range(len(grid))
)
def iter_flipped(grid: Grid) -> Iterator[Grid]:
yield grid
yield grid[::-1]
yield tuple(line[::-1] for line in grid)
return {
flip for rotated in iter_rotated(grid) for flip in iter_flipped(rotated)
}
def normalize_rules(raw_rules: dict[Grid, Grid]) -> dict[Grid, Grid]:
res: dict[Grid, Grid] = {}
for pattern, grid in raw_rules.items():
for perm in permutations(pattern):
res[perm] = grid
return res
def enhance(rules: dict[Grid, Grid], rounds: int) -> list[list[bool]]:
def step(grid: list[list[bool]]) -> list[list[bool]]:
is_even = len(grid) % 2 == 0
step_size = 2 if is_even else 3
next_size = len(grid) * (step_size + 1) // step_size
res = [[False for _ in range(next_size)] for _ in range(next_size)]
for x, y in itertools.product(range(len(grid) // step_size), repeat=2):
elem = tuple(
tuple(
grid[x * step_size + dx][y * step_size + dy]
for dy in range(step_size)
)
for dx in range(step_size)
)
new_grid = rules[elem]
for dx, line in enumerate(new_grid):
for dy, p in enumerate(line):
res[x * len(new_grid) + dx][y * len(line) + dy] = p
return res
grid = [[p for p in line] for line in parse_pattern(START)]
for _ in range(rounds):
grid = step(grid)
return grid
raw_rules = parse(input)
norm_rules = normalize_rules(raw_rules)
art = enhance(norm_rules, 18)
return sum(itertools.chain.from_iterable(art))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

108
2017/d21/ex2/input Normal file
View file

@ -0,0 +1,108 @@
../.. => #.#/#../...
#./.. => #.#/#.#/.#.
##/.. => #../.##/##.
.#/#. => ..#/..#/..#
##/#. => ##./.#./#..
##/## => .../.#./.#.
.../.../... => ..#./##.#/#.##/##.#
#../.../... => #.##/..../##../###.
.#./.../... => ##.#/###./#.##/#.#.
##./.../... => ##.#/#.##/.#../##.#
#.#/.../... => ...#/..#./.#.#/.###
###/.../... => ..../#..#/#.##/##..
.#./#../... => .#../.#.#/..#./.###
##./#../... => ..##/#.##/#.../#.#.
..#/#../... => .##./#.##/.#../##..
#.#/#../... => #.../.##./...#/###.
.##/#../... => #.##/..##/.#.#/##..
###/#../... => #..#/...#/..#./...#
.../.#./... => .###/.#../..#./####
#../.#./... => ####/#.../.###/##..
.#./.#./... => ####/#..#/####/#..#
##./.#./... => .#../..##/..##/#..#
#.#/.#./... => .#.#/#.##/#.#./.#.#
###/.#./... => #.##/#.../###./#..#
.#./##./... => ###./#.../..../.###
##./##./... => #.##/###./...#/###.
..#/##./... => .#.#/###./..#./#...
#.#/##./... => #.#./##../##../..##
.##/##./... => ..../..#./.##./.#.#
###/##./... => #.../.#../#.#./#..#
.../#.#/... => ##../#.##/.##./.##.
#../#.#/... => #.#./##.#/.###/.###
.#./#.#/... => ..../####/####/.#.#
##./#.#/... => #.##/.###/##../#...
#.#/#.#/... => ###./..##/#.#./####
###/#.#/... => .##./..../###./....
.../###/... => ###./.##./##../.###
#../###/... => .#../#.../###./...#
.#./###/... => #.#./#.#./####/###.
##./###/... => ...#/##../###./#.#.
#.#/###/... => .#.#/#.#./..#./.##.
###/###/... => ..../#.##/...#/##..
..#/.../#.. => ...#/#.##/#..#/..##
#.#/.../#.. => ..#./##.#/.#.#/..##
.##/.../#.. => ..##/##../#.#./#.##
###/.../#.. => #.##/###./...#/.##.
.##/#../#.. => ##../#.##/##.#/##..
###/#../#.. => #.##/##../.##./.#.#
..#/.#./#.. => #..#/##../.###/#.#.
#.#/.#./#.. => .###/#.##/#.#./####
.##/.#./#.. => #.#./#.../#.##/...#
###/.#./#.. => .##./.#.#/#.#./.#.#
.##/##./#.. => .###/.#.#/...#/#.#.
###/##./#.. => .###/#.##/#.##/#.#.
#../..#/#.. => #.../##../.##./###.
.#./..#/#.. => #.../#.##/#.../###.
##./..#/#.. => ####/..../##.#/.###
#.#/..#/#.. => ..##/##.#/#.##/#..#
.##/..#/#.. => ..#./##.#/#.#./..##
###/..#/#.. => ..##/...#/#..#/#..#
#../#.#/#.. => #.../..../#.../#.##
.#./#.#/#.. => ##../####/.#.#/##..
##./#.#/#.. => .#../..../#.../.##.
..#/#.#/#.. => .#../.#.#/.#.#/..#.
#.#/#.#/#.. => ..#./#.##/#.#./..##
.##/#.#/#.. => #.##/..##/...#/####
###/#.#/#.. => .##./.#.#/###./#..#
#../.##/#.. => ..##/.###/.#../##.#
.#./.##/#.. => #.##/.##./.##./.###
##./.##/#.. => .##./.#../..../..##
#.#/.##/#.. => ..../#.#./##.#/###.
.##/.##/#.. => #..#/..../##.#/..#.
###/.##/#.. => ####/##.#/#..#/##..
#../###/#.. => #.#./###./.###/#...
.#./###/#.. => ##.#/#..#/#.##/..#.
##./###/#.. => ..#./...#/..##/...#
..#/###/#.. => .#.#/..../..##/..##
#.#/###/#.. => #..#/..#./.#../..#.
.##/###/#.. => .#.#/..../#..#/...#
###/###/#.. => #.##/##../.#../....
.#./#.#/.#. => ..../####/.###/.#.#
##./#.#/.#. => #.##/...#/####/####
#.#/#.#/.#. => ..#./##../..../#...
###/#.#/.#. => ####/#.##/###./...#
.#./###/.#. => ...#/..#./...#/..#.
##./###/.#. => .##./#.../.#.#/.###
#.#/###/.#. => ..../..../.#.#/#.##
###/###/.#. => ..#./###./##.#/....
#.#/..#/##. => .###/.#../..#./####
###/..#/##. => #.##/..#./#..#/....
.##/#.#/##. => #.../##../####/.##.
###/#.#/##. => ###./..#./..#./##..
#.#/.##/##. => #.../##../##.#/#.##
###/.##/##. => ..#./#..#/#.##/####
.##/###/##. => .#.#/.###/...#/.#..
###/###/##. => ####/..../.#.#/...#
#.#/.../#.# => ##.#/#..#/.##./...#
###/.../#.# => #.#./.#../...#/...#
###/#../#.# => .#.#/.#../##../##..
#.#/.#./#.# => ###./#.../####/.#.#
###/.#./#.# => ##../#.#./..##/##.#
###/##./#.# => ####/..../###./.##.
#.#/#.#/#.# => ...#/.##./##../.###
###/#.#/#.# => ..#./.##./##.#/.#..
#.#/###/#.# => ...#/..../..#./...#
###/###/#.# => #.#./#.#./##../....
###/#.#/### => #.../##.#/.#../..#.
###/###/### => ##../..#./##../..#.

76
2017/d22/ex1/ex1.py Executable file
View file

@ -0,0 +1,76 @@
#!/usr/bin/env python
import dataclasses
import enum
import sys
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
class Direction(enum.Enum):
UP = Point(-1, 0)
DOWN = Point(1, 0)
LEFT = Point(0, -1)
RIGHT = Point(0, 1)
def left(self) -> "Direction":
x, y = self.value
return Direction(Point(-y, x))
def right(self) -> "Direction":
x, y = self.value
return Direction(Point(y, -x))
def apply(self, p: Point) -> Point:
dx, dy = self.value
return Point(p.x + dx, p.y + dy)
@dataclasses.dataclass
class Carrier:
pos: Point
dir: Direction
def burst(self, infected: set[Point]) -> bool:
infect = False
if self.pos in infected:
self.dir = self.dir.right()
infected.remove(self.pos)
else:
self.dir = self.dir.left()
infected.add(self.pos)
infect = True
self.pos = self.dir.apply(self.pos)
return infect
def solve(input: str) -> int:
def parse(input: str) -> set[Point]:
return {
Point(x, y)
for x, line in enumerate(input.splitlines())
for y, c in enumerate(line)
if c == "#"
}
infected = parse(input)
middle = len(input.splitlines()) // 2
carrier = Carrier(Point(middle, middle), Direction.UP)
total = 0
for _ in range(10000):
total += carrier.burst(infected)
return total
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

25
2017/d22/ex1/input Normal file
View file

@ -0,0 +1,25 @@
#..#...#.#.#..#.#...##.##
.....##.#....#.#......#.#
..#.###.#.#######.###.#.#
.......#.##.###.###..##.#
#....#...#.###....##.....
#.....##.#########..#.#.#
.####.##..#...###.##...#.
#....#..#.###.##.#..##.#.
#####.#.#..#.##..#...####
##.#.#..#.#....###.######
.##.#...#...##.#.##..####
...#..##.#.....#.#..####.
#.##.###..#######.#..#.#.
##....##....##.#..#.##..#
##.#.#.#.##...##.....#...
.#####..#.#....#.#######.
####....###.###.#.#..#..#
.###...#.###..#..#.#####.
#.###..#.#######.#.#####.
.##.#.###.##.##.#.#...#..
######.###.#.#.##.####..#
##..####.##..##.#...##...
...##.##...#..#..##.####.
#.....##.##.#..##.##....#
#.#..####.....#....#.###.

96
2017/d22/ex2/ex2.py Executable file
View file

@ -0,0 +1,96 @@
#!/usr/bin/env python
import collections
import dataclasses
import enum
import sys
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
class Direction(enum.Enum):
UP = Point(-1, 0)
DOWN = Point(1, 0)
LEFT = Point(0, -1)
RIGHT = Point(0, 1)
def left(self) -> "Direction":
x, y = self.value
return Direction(Point(-y, x))
def right(self) -> "Direction":
x, y = self.value
return Direction(Point(y, -x))
def flip(self) -> "Direction":
x, y = self.value
return Direction(Point(-x, -y))
def apply(self, p: Point) -> Point:
dx, dy = self.value
return Point(p.x + dx, p.y + dy)
class State(enum.StrEnum):
CLEAN = "."
WEAKENED = "W"
FLAGGED = "F"
INFECTED = "#"
@dataclasses.dataclass
class Carrier:
pos: Point
dir: Direction
def burst(self, infected: dict[Point, State]) -> bool:
infect = False
match infected[self.pos]:
case State.CLEAN:
self.dir = self.dir.left()
infected[self.pos] = State.WEAKENED
case State.WEAKENED:
infected[self.pos] = State.INFECTED
infect = True
case State.FLAGGED:
self.dir = self.dir.flip()
infected[self.pos] = State.CLEAN
case State.INFECTED:
self.dir = self.dir.right()
infected[self.pos] = State.FLAGGED
self.pos = self.dir.apply(self.pos)
return infect
def solve(input: str) -> int:
def parse(input: str) -> set[Point]:
return {
Point(x, y)
for x, line in enumerate(input.splitlines())
for y, c in enumerate(line)
if c == "#"
}
infected: dict[Point, State] = collections.defaultdict(lambda: State.CLEAN)
for p in parse(input):
infected[p] = State.INFECTED
middle = len(input.splitlines()) // 2
carrier = Carrier(Point(middle, middle), Direction.UP)
total = 0
for _ in range(10000000):
total += carrier.burst(infected)
return total
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

25
2017/d22/ex2/input Normal file
View file

@ -0,0 +1,25 @@
#..#...#.#.#..#.#...##.##
.....##.#....#.#......#.#
..#.###.#.#######.###.#.#
.......#.##.###.###..##.#
#....#...#.###....##.....
#.....##.#########..#.#.#
.####.##..#...###.##...#.
#....#..#.###.##.#..##.#.
#####.#.#..#.##..#...####
##.#.#..#.#....###.######
.##.#...#...##.#.##..####
...#..##.#.....#.#..####.
#.##.###..#######.#..#.#.
##....##....##.#..#.##..#
##.#.#.#.##...##.....#...
.#####..#.#....#.#######.
####....###.###.#.#..#..#
.###...#.###..#..#.#####.
#.###..#.#######.#.#####.
.##.#.###.##.##.#.#...#..
######.###.#.#.##.####..#
##..####.##..##.#...##...
...##.##...#..#..##.####.
#.....##.##.#..##.##....#
#.#..####.....#....#.###.

67
2017/d23/ex1/ex1.py Executable file
View file

@ -0,0 +1,67 @@
#!/usr/bin/env python
import enum
import sys
from typing import NamedTuple
class Op(enum.StrEnum):
SET = "set"
SUB = "sub"
MUL = "mul"
JNZ = "jnz"
class Instruction(NamedTuple):
op: Op
x: str
y: str
@classmethod
def from_str(cls, input: str) -> "Instruction":
op, *rest = input.split()
return cls(Op(op), *rest)
def solve(input: str) -> int:
def parse(input: str) -> list[Instruction]:
return [Instruction.from_str(line) for line in input.splitlines()]
def resolve(y: str | None, registers: dict[str, int]) -> int:
assert y is not None # Sanity check
try:
return int(y)
except ValueError:
return registers[y]
instructions = parse(input)
registers = {chr(ord("a") + i): 0 for i in range(8)}
ip = 0
total_muls = 0
while True:
if ip < 0 or ip >= len(instructions):
break
instr = instructions[ip]
ip += 1
match instr.op:
case Op.SET:
registers[instr.x] = resolve(instr.y, registers)
case Op.SUB:
registers[instr.x] -= resolve(instr.y, registers)
case Op.MUL:
registers[instr.x] *= resolve(instr.y, registers)
total_muls += 1
case Op.JNZ:
if resolve(instr.x, registers) != 0:
ip += resolve(instr.y, registers) - 1 # Account auto-increment
return total_muls
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

32
2017/d23/ex1/input Normal file
View file

@ -0,0 +1,32 @@
set b 81
set c b
jnz a 2
jnz 1 5
mul b 100
sub b -100000
set c b
sub c -17000
set f 1
set d 2
set e 2
set g d
mul g e
sub g b
jnz g 2
set f 0
sub e -1
set g e
sub g b
jnz g -8
sub d -1
set g d
sub g b
jnz g -13
jnz f 2
sub h -1
set g b
sub g c
jnz g 2
jnz 1 3
sub b -17
jnz 1 -23

55
2017/d23/ex2/ex2.py Executable file
View file

@ -0,0 +1,55 @@
#!/usr/bin/env python
import enum
import math
import sys
from typing import NamedTuple
class Op(enum.StrEnum):
SET = "set"
SUB = "sub"
MUL = "mul"
JNZ = "jnz"
class Instruction(NamedTuple):
op: Op
x: str
y: str
@classmethod
def from_str(cls, input: str) -> "Instruction":
op, *rest = input.split()
return cls(Op(op), *rest)
def solve(input: str) -> int:
def parse(input: str) -> list[Instruction]:
return [Instruction.from_str(line) for line in input.splitlines()]
def is_prime(n: int) -> bool:
if n % 2 == 0:
return False
for i in range(3, math.isqrt(n), 2):
if n % i == 0:
return False
return True
instructions = parse(input)
start = int(instructions[0].y) * 100 + 100000
end = start + 17000
total = 0
for n in range(start, end + 1, 17):
total += not is_prime(n)
return total
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

32
2017/d23/ex2/input Normal file
View file

@ -0,0 +1,32 @@
set b 81
set c b
jnz a 2
jnz 1 5
mul b 100
sub b -100000
set c b
sub c -17000
set f 1
set d 2
set e 2
set g d
mul g e
sub g b
jnz g 2
set f 0
sub e -1
set g e
sub g b
jnz g -8
sub d -1
set g d
sub g b
jnz g -13
jnz f 2
sub h -1
set g b
sub g c
jnz g 2
jnz 1 3
sub b -17
jnz 1 -23

49
2017/d24/ex1/ex1.py Executable file
View file

@ -0,0 +1,49 @@
#!/usr/bin/env python
import functools
import sys
from typing import NamedTuple
class Component(NamedTuple):
left: int
right: int
@classmethod
def from_str(cls, input: str) -> "Component":
return cls(*map(int, input.split("/")))
def remaining_port(self, connection: int) -> int:
if connection == self.left:
return self.right
elif connection == self.right:
return self.left
assert False # Sanity check
def solve(input: str) -> int:
def parse(input: str) -> list[Component]:
return [Component.from_str(line) for line in input.splitlines()]
@functools.cache
def strongest_bridge(start: int, components: frozenset[Component]) -> int:
candidates = {c for c in components if start in c}
if not candidates:
return 0
return max(
sum(c) + strongest_bridge(c.remaining_port(start), components - {c})
for c in candidates
)
components = parse(input)
assert len(set(components)) == len(components) # Sanity check
return strongest_bridge(0, frozenset(components))
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

57
2017/d24/ex1/input Normal file
View file

@ -0,0 +1,57 @@
25/13
4/43
42/42
39/40
17/18
30/7
12/12
32/28
9/28
1/1
16/7
47/43
34/16
39/36
6/4
3/2
10/49
46/50
18/25
2/23
3/21
5/24
46/26
50/19
26/41
1/50
47/41
39/50
12/14
11/19
28/2
38/47
5/5
38/34
39/39
17/34
42/16
32/23
13/21
28/6
6/20
1/30
44/21
11/28
14/17
33/33
17/43
31/13
11/21
31/39
0/9
13/50
10/14
16/10
3/24
7/0
50/50

74
2017/d24/ex2/ex2.py Executable file
View file

@ -0,0 +1,74 @@
#!/usr/bin/env python
import itertools
import sys
from collections.abc import Iterator
from typing import NamedTuple
class Component(NamedTuple):
left: int
right: int
@classmethod
def from_str(cls, input: str) -> "Component":
return cls(*map(int, input.split("/")))
def remaining_port(self, connection: int) -> int:
if connection == self.left:
return self.right
elif connection == self.right:
return self.left
assert False # Sanity check
class Bridge(NamedTuple):
components: tuple[Component, ...]
head: int
@property
def length(self):
return len(self.components)
@property
def strength(self):
return sum(itertools.chain.from_iterable(self.components))
def add(self, c: Component) -> "Bridge":
assert self.head in c # Sanity check
return Bridge(self.components + (c,), c.remaining_port(self.head))
def solve(input: str) -> int:
def parse(input: str) -> list[Component]:
return [Component.from_str(line) for line in input.splitlines()]
def longest_bridge(components: set[Component]) -> Bridge:
def build_bridges(
bridge: Bridge, components: set[Component]
) -> Iterator[Bridge]:
candidates = {c for c in components if bridge.head in c}
if not candidates:
yield bridge
return
for c in candidates:
yield from build_bridges(bridge.add(c), components - {c})
return max(
build_bridges(Bridge((), 0), components),
key=lambda b: (b.length, b.strength),
)
components = parse(input)
assert len(set(components)) == len(components) # Sanity check
bridge = longest_bridge(set(components))
return bridge.strength
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

57
2017/d24/ex2/input Normal file
View file

@ -0,0 +1,57 @@
25/13
4/43
42/42
39/40
17/18
30/7
12/12
32/28
9/28
1/1
16/7
47/43
34/16
39/36
6/4
3/2
10/49
46/50
18/25
2/23
3/21
5/24
46/26
50/19
26/41
1/50
47/41
39/50
12/14
11/19
28/2
38/47
5/5
38/34
39/39
17/34
42/16
32/23
13/21
28/6
6/20
1/30
44/21
11/28
14/17
33/33
17/43
31/13
11/21
31/39
0/9
13/50
10/14
16/10
3/24
7/0
50/50

73
2017/d25/ex1/ex1.py Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env python
import collections
import enum
import sys
from typing import NamedTuple
class Direction(enum.StrEnum):
LEFT = "left"
RIGHT = "right"
def apply(self, pos: int) -> int:
return pos + 1 if self == Direction.RIGHT else pos - 1
class Rules(NamedTuple):
zero_write: bool
zero_dir: Direction
zero_transition: str
one_write: bool
one_dir: Direction
one_transition: str
@classmethod
def from_str(cls, input: str) -> "Rules":
lines = input.splitlines()
return cls(
zero_write=bool(int(lines[1][-2])),
zero_dir=Direction(lines[2][:-1].split()[-1]),
zero_transition=lines[3][-2],
one_write=bool(int(lines[5][-2])),
one_dir=Direction(lines[6][:-1].split()[-1]),
one_transition=lines[7][-2],
)
def apply(self, tape: dict[int, bool], pos: int) -> tuple[str, int]:
if tape[pos]:
tape[pos] = self.one_write
return self.one_transition, self.one_dir.apply(pos)
else:
tape[pos] = self.zero_write
return self.zero_transition, self.zero_dir.apply(pos)
def solve(input: str) -> int:
def parse_rules(input: str) -> tuple[str, Rules]:
assert input.startswith("In state ") # Sanity check
state, lines = input.split("\n", 1)
return state[-2], Rules.from_str(lines)
def parse(input: str) -> tuple[str, int, dict[str, Rules]]:
first, *rest = input.split("\n\n")
raw_state, raw_checksum = first.splitlines()
rules = {state: rules for state, rules in map(parse_rules, rest)}
return raw_state[-2], int(raw_checksum.split()[-2]), rules
state, iterations, rules = parse(input)
pos = 0
tape: dict[int, bool] = collections.defaultdict(bool)
for _ in range(iterations):
state, pos = rules[state].apply(tape, pos)
return sum(tape.values())
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()

62
2017/d25/ex1/input Normal file
View file

@ -0,0 +1,62 @@
Begin in state A.
Perform a diagnostic checksum after 12683008 steps.
In state A:
If the current value is 0:
- Write the value 1.
- Move one slot to the right.
- Continue with state B.
If the current value is 1:
- Write the value 0.
- Move one slot to the left.
- Continue with state B.
In state B:
If the current value is 0:
- Write the value 1.
- Move one slot to the left.
- Continue with state C.
If the current value is 1:
- Write the value 0.
- Move one slot to the right.
- Continue with state E.
In state C:
If the current value is 0:
- Write the value 1.
- Move one slot to the right.
- Continue with state E.
If the current value is 1:
- Write the value 0.
- Move one slot to the left.
- Continue with state D.
In state D:
If the current value is 0:
- Write the value 1.
- Move one slot to the left.
- Continue with state A.
If the current value is 1:
- Write the value 1.
- Move one slot to the left.
- Continue with state A.
In state E:
If the current value is 0:
- Write the value 0.
- Move one slot to the right.
- Continue with state A.
If the current value is 1:
- Write the value 0.
- Move one slot to the right.
- Continue with state F.
In state F:
If the current value is 0:
- Write the value 1.
- Move one slot to the right.
- Continue with state E.
If the current value is 1:
- Write the value 1.
- Move one slot to the right.
- Continue with state A.

9
2017/d25/ex2/ex2.py Executable file
View file

@ -0,0 +1,9 @@
#!/usr/bin/env python
def main() -> None:
print("There is no part two...")
if __name__ == "__main__":
main()

62
2017/d25/ex2/input Normal file
View file

@ -0,0 +1,62 @@
Begin in state A.
Perform a diagnostic checksum after 12683008 steps.
In state A:
If the current value is 0:
- Write the value 1.
- Move one slot to the right.
- Continue with state B.
If the current value is 1:
- Write the value 0.
- Move one slot to the left.
- Continue with state B.
In state B:
If the current value is 0:
- Write the value 1.
- Move one slot to the left.
- Continue with state C.
If the current value is 1:
- Write the value 0.
- Move one slot to the right.
- Continue with state E.
In state C:
If the current value is 0:
- Write the value 1.
- Move one slot to the right.
- Continue with state E.
If the current value is 1:
- Write the value 0.
- Move one slot to the left.
- Continue with state D.
In state D:
If the current value is 0:
- Write the value 1.
- Move one slot to the left.
- Continue with state A.
If the current value is 1:
- Write the value 1.
- Move one slot to the left.
- Continue with state A.
In state E:
If the current value is 0:
- Write the value 0.
- Move one slot to the right.
- Continue with state A.
If the current value is 1:
- Write the value 0.
- Move one slot to the right.
- Continue with state F.
In state F:
If the current value is 0:
- Write the value 1.
- Move one slot to the right.
- Continue with state E.
If the current value is 1:
- Write the value 1.
- Move one slot to the right.
- Continue with state A.