Compare commits
480 commits
eb9c25af5a
...
d62a8befcd
Author | SHA1 | Date | |
---|---|---|---|
Bruno BELANYI | d62a8befcd | ||
Bruno BELANYI | 43650ade44 | ||
Bruno BELANYI | 94befa4d1b | ||
Bruno BELANYI | 601b40e7d4 | ||
Bruno BELANYI | c02a05a0ff | ||
Bruno BELANYI | fb13cf95c3 | ||
Bruno BELANYI | 8424bbb2bb | ||
Bruno BELANYI | ee84fa576d | ||
Bruno BELANYI | df75f1c5d2 | ||
Bruno BELANYI | 5ebf620992 | ||
Bruno BELANYI | fa6c3351b0 | ||
Bruno BELANYI | 7b0a967765 | ||
Bruno BELANYI | 1a6bc7c2c7 | ||
Bruno BELANYI | 314e894367 | ||
Bruno BELANYI | f07d58e9f2 | ||
Bruno BELANYI | a1c64e606e | ||
Bruno BELANYI | 789b19ad0c | ||
Bruno BELANYI | fa9ba51cd4 | ||
Bruno BELANYI | 27e5a815ba | ||
Bruno BELANYI | 23fb211e92 | ||
Bruno BELANYI | 0605f5e47f | ||
Bruno BELANYI | bd30ae97ed | ||
Bruno BELANYI | ba345ca59d | ||
Bruno BELANYI | e4c930c2fa | ||
Bruno BELANYI | 8e31abf2b2 | ||
Bruno BELANYI | 4ccebd33ab | ||
Bruno BELANYI | 5a11d5ca5c | ||
Bruno BELANYI | 49dc83b67f | ||
Bruno BELANYI | 03f8a5567b | ||
Bruno BELANYI | b1bfdee330 | ||
Bruno BELANYI | aedb2c4c14 | ||
Bruno BELANYI | d4aa8d246f | ||
Bruno BELANYI | b806f8dc39 | ||
Bruno BELANYI | ce0bfe769f | ||
Bruno BELANYI | bfe11a50f7 | ||
Bruno BELANYI | 7bbf3d0261 | ||
Bruno BELANYI | faf382cb44 | ||
Bruno BELANYI | 0e237d6752 | ||
Bruno BELANYI | 1adbc956ac | ||
Bruno BELANYI | 2869e96841 | ||
Bruno BELANYI | d5bf9f3c9f | ||
Bruno BELANYI | 36f84c4324 | ||
Bruno BELANYI | 6c0e372228 | ||
Bruno BELANYI | d35af3ede7 | ||
Bruno BELANYI | e253096a7e | ||
Bruno BELANYI | 9407e73b44 | ||
Bruno BELANYI | f1c8a7693b | ||
Bruno BELANYI | 26d37fbe0e | ||
Bruno BELANYI | d39bc20a21 | ||
Bruno BELANYI | c0c824513e | ||
Bruno BELANYI | 58eaa4ea5d | ||
Bruno BELANYI | e7892e9014 | ||
Bruno BELANYI | 6a3c87ef2e | ||
Bruno BELANYI | 48175ec659 | ||
Bruno BELANYI | 7349222bee | ||
Bruno BELANYI | 28faa62410 | ||
Bruno BELANYI | fa6fcf635b | ||
Bruno BELANYI | 1ac549afe3 | ||
Bruno BELANYI | 65cc5b2e7c | ||
Bruno BELANYI | 30d45a6021 | ||
Bruno BELANYI | 73884e9936 | ||
Bruno BELANYI | 396aaf22ac | ||
Bruno BELANYI | 9168b6850d | ||
Bruno BELANYI | d471d8f643 | ||
Bruno BELANYI | 4309339016 | ||
Bruno BELANYI | 151630332e | ||
Bruno BELANYI | 974524b1f1 | ||
Bruno BELANYI | bc41afab0f | ||
Bruno BELANYI | 7c7df880ed | ||
Bruno BELANYI | ffd47cdea7 | ||
Bruno BELANYI | 7c29d7d889 | ||
Bruno BELANYI | 01ecc496a5 | ||
Bruno BELANYI | 9fa50a7aad | ||
Bruno BELANYI | 140cf8549d | ||
Bruno BELANYI | 59e2d4abcf | ||
Bruno BELANYI | d4078c91bf | ||
Bruno BELANYI | 9b4506da33 | ||
Bruno BELANYI | bb9dff359d | ||
Bruno BELANYI | 6917623406 | ||
Bruno BELANYI | 6b8dbbd938 | ||
Bruno BELANYI | 10fb8ca2d1 | ||
Bruno BELANYI | 1081a4fc8d | ||
Bruno BELANYI | 60da30ee6c | ||
Bruno BELANYI | 7d4377d6a2 | ||
Bruno BELANYI | ffb2c5346b | ||
Bruno BELANYI | 052d0116fd | ||
Bruno BELANYI | 2583ad84d6 | ||
Bruno BELANYI | 018cc4a904 | ||
Bruno BELANYI | 8292a5f323 | ||
Bruno BELANYI | d84554d965 | ||
Bruno BELANYI | 1490fe1309 | ||
Bruno BELANYI | 20d7292d10 | ||
Bruno BELANYI | 146529433c | ||
Bruno BELANYI | c2167dbfc9 | ||
Bruno BELANYI | 05f80dc3de | ||
Bruno BELANYI | 3aa39588ed | ||
Bruno BELANYI | 6ebbcdeb11 | ||
Bruno BELANYI | 355b4f457b | ||
Bruno BELANYI | 7a7691c891 | ||
Bruno BELANYI | 5b94cedebc | ||
Bruno BELANYI | d0c97d8793 | ||
Bruno BELANYI | 771b7f7d25 | ||
Bruno BELANYI | 8d8f2b1fb1 | ||
Bruno BELANYI | 85d39b0f8a | ||
Bruno BELANYI | d392ae4f4a | ||
Bruno BELANYI | 9a3109466b | ||
Bruno BELANYI | a843028f15 | ||
Bruno BELANYI | bc91ad5dad | ||
Bruno BELANYI | d20e79e2b0 | ||
Bruno BELANYI | 5254f96e15 | ||
Bruno BELANYI | 83bbd2c36c | ||
Bruno BELANYI | 3389478097 | ||
Bruno BELANYI | 0f1454045d | ||
Bruno BELANYI | aa26b73644 | ||
Bruno BELANYI | 384d9dcd50 | ||
Bruno BELANYI | e796cc3342 | ||
Bruno BELANYI | 0bed52bf64 | ||
Bruno BELANYI | 23a88b18af | ||
Bruno BELANYI | bf7ed284c9 | ||
Bruno BELANYI | 15a33215f3 | ||
Bruno BELANYI | 17f2ffb0ef | ||
Bruno BELANYI | 786f88c001 | ||
Bruno BELANYI | 6055c7ac23 | ||
Bruno BELANYI | c3a9572407 | ||
Bruno BELANYI | c7f7e2a590 | ||
Bruno BELANYI | 8d2b7be327 | ||
Bruno BELANYI | 815b5a028f | ||
Bruno BELANYI | 2c0fbf53c3 | ||
Bruno BELANYI | c7ffb3be10 | ||
Bruno BELANYI | 5cd4f7dfd7 | ||
Bruno BELANYI | 97222c32ab | ||
Bruno BELANYI | b1ef193da9 | ||
Bruno BELANYI | d8b22599cf | ||
Bruno BELANYI | 43d4b031f5 | ||
Bruno BELANYI | 5fc8c07cfd | ||
Bruno BELANYI | eb007342f2 | ||
Bruno BELANYI | ca6a3885b0 | ||
Bruno BELANYI | d2aad80116 | ||
Bruno BELANYI | d2fd3abe24 | ||
Bruno BELANYI | 4b7ee749a0 | ||
Bruno BELANYI | cc4910cca9 | ||
Bruno BELANYI | 10d563b357 | ||
Bruno BELANYI | 7f36b288e3 | ||
Bruno BELANYI | 22b823e283 | ||
Bruno BELANYI | 9b7ecb60a8 | ||
Bruno BELANYI | 9c35ca0630 | ||
Bruno BELANYI | 18f87be63c | ||
Bruno BELANYI | 58f530c3d1 | ||
Bruno BELANYI | a996fee1d7 | ||
Bruno BELANYI | 336a67a2ca | ||
Bruno BELANYI | 7b56fdd706 | ||
Bruno BELANYI | ff1de34ee5 | ||
Bruno BELANYI | 8db6023086 | ||
Bruno BELANYI | 1551c5ad8e | ||
Bruno BELANYI | 0cf1acfecf | ||
Bruno BELANYI | 529a66e33b | ||
Bruno BELANYI | aba5dfc57b | ||
Bruno BELANYI | 51527eee9d | ||
Bruno BELANYI | 532fb31b03 | ||
Bruno BELANYI | 258472ef6a | ||
Bruno BELANYI | 50dd65e63b | ||
Bruno BELANYI | 004a632125 | ||
Bruno BELANYI | a3951a5a47 | ||
Bruno BELANYI | cd577dc37d | ||
Bruno BELANYI | 354d6087a6 | ||
Bruno BELANYI | c01254a5ca | ||
Bruno BELANYI | 96b1ebeb61 | ||
Bruno BELANYI | 9285442688 | ||
Bruno BELANYI | 340b0b4c67 | ||
Bruno BELANYI | 420d37b25f | ||
Bruno BELANYI | d1037cd7e5 | ||
Bruno BELANYI | 48b9633dfb | ||
Bruno BELANYI | 9bbb3e0066 | ||
Bruno BELANYI | 7d160342d9 | ||
Bruno BELANYI | 6deca8b1d3 | ||
Bruno BELANYI | d793a7441c | ||
Bruno BELANYI | e75cb939d7 | ||
Bruno BELANYI | 7dbf22de6b | ||
Bruno BELANYI | 8d8feac390 | ||
Bruno BELANYI | 35fad0bd82 | ||
Bruno BELANYI | e995443027 | ||
Bruno BELANYI | 4c09d5caa5 | ||
Bruno BELANYI | 73ea22bb58 | ||
Bruno BELANYI | aba16a2556 | ||
Bruno BELANYI | 6dc7baa4a8 | ||
Bruno BELANYI | 2ea00cec0a | ||
Bruno BELANYI | 50dfee46e6 | ||
Bruno BELANYI | 624ccdd863 | ||
Bruno BELANYI | 157522996f | ||
Bruno BELANYI | 64a9d16216 | ||
Bruno BELANYI | affe5cd89b | ||
Bruno BELANYI | 742de9ade3 | ||
Bruno BELANYI | 197c7060db | ||
Bruno BELANYI | 30ff9c5266 | ||
Bruno BELANYI | edeae4d9f4 | ||
Bruno BELANYI | ef2a4c0700 | ||
Bruno BELANYI | 6c496ec591 | ||
Bruno BELANYI | b79109ed37 | ||
Bruno BELANYI | 439a4362d1 | ||
Bruno BELANYI | ed2497a67c | ||
Bruno BELANYI | 0df109da5b | ||
Bruno BELANYI | 06fee9ad24 | ||
Bruno BELANYI | 80ee0fddb5 | ||
Bruno BELANYI | 7054b00043 | ||
Bruno BELANYI | 99d677590f | ||
Bruno BELANYI | a9e68c07d6 | ||
Bruno BELANYI | c5861c0b22 | ||
Bruno BELANYI | 4efa9d74e3 | ||
Bruno BELANYI | f65d22ece5 | ||
Bruno BELANYI | 2fa3ffadeb | ||
Bruno BELANYI | afb38fba2c | ||
Bruno BELANYI | 4447a4da44 | ||
Bruno BELANYI | 18d91fee78 | ||
Bruno BELANYI | f4cd01f6a0 | ||
Bruno BELANYI | ed49448d04 | ||
Bruno BELANYI | 4a691b8dd2 | ||
Bruno BELANYI | 0d3efefaa5 | ||
Bruno BELANYI | f42b43d8bc | ||
Bruno BELANYI | 637c597525 | ||
Bruno BELANYI | d04c77d40c | ||
Bruno BELANYI | 42979f727b | ||
Bruno BELANYI | 0daf3f7e03 | ||
Bruno BELANYI | 14cfc776b7 | ||
Bruno BELANYI | 17f903385c | ||
Bruno BELANYI | ce432cf461 | ||
Bruno BELANYI | 2dfd17a6de | ||
Bruno BELANYI | 0e47d63758 | ||
Bruno BELANYI | 2975f1f898 | ||
Bruno BELANYI | ead3395a83 | ||
Bruno BELANYI | d4d6bbe742 | ||
Bruno BELANYI | da979f53d0 | ||
Bruno BELANYI | 52da7aafe9 | ||
Bruno BELANYI | 62f0a786c2 | ||
Bruno BELANYI | 7a502bdc9c | ||
Bruno BELANYI | a83f108eeb | ||
Bruno BELANYI | ab3bbd0005 | ||
Bruno BELANYI | da2a08ffbe | ||
Bruno BELANYI | 45d5954659 | ||
Bruno BELANYI | a33665b459 | ||
Bruno BELANYI | 61d721c57e | ||
Bruno BELANYI | 950af51d0d | ||
Bruno BELANYI | 4f5357a388 | ||
Bruno BELANYI | a34dccc5d6 | ||
Bruno BELANYI | 15d5b0ddad | ||
Bruno BELANYI | 54c92ff0fe | ||
Bruno BELANYI | 0889e490ee | ||
Bruno BELANYI | 9403676d36 | ||
Bruno BELANYI | 6aaefd6d6f | ||
Bruno BELANYI | e4e9042c0f | ||
Bruno BELANYI | 918aa91aba | ||
Bruno BELANYI | fcce87c199 | ||
Bruno BELANYI | 8c09efb227 | ||
Bruno BELANYI | a4b81dac45 | ||
Bruno BELANYI | 7c0034e8af | ||
Bruno BELANYI | 2730bcf359 | ||
Bruno BELANYI | 1ed52f1113 | ||
Bruno BELANYI | 5ad6df511b | ||
Bruno BELANYI | df55bc9993 | ||
Bruno BELANYI | 006e9e3ac6 | ||
Bruno BELANYI | 39c5d2e59a | ||
Bruno BELANYI | 0532cbeac3 | ||
Bruno BELANYI | 07d150e796 | ||
Bruno BELANYI | b9860d1f32 | ||
Bruno BELANYI | f314b9d753 | ||
Bruno BELANYI | 9f4688d8c0 | ||
Bruno BELANYI | bf519c8eab | ||
Bruno BELANYI | d4907958ac | ||
Bruno BELANYI | 53489b62d6 | ||
Bruno BELANYI | 00e984420c | ||
Bruno BELANYI | 4e7552b34e | ||
Bruno BELANYI | c2cb30c7df | ||
Bruno BELANYI | 60f8aca9dd | ||
Bruno BELANYI | bf6881bacb | ||
Bruno BELANYI | 85630222fc | ||
Bruno BELANYI | 295309a0f7 | ||
Bruno BELANYI | 43621f22b2 | ||
Bruno BELANYI | 75a9a4710c | ||
Bruno BELANYI | d06866158f | ||
Bruno BELANYI | 137a98e936 | ||
Bruno BELANYI | 20f7e96cc5 | ||
Bruno BELANYI | b5824be5ba | ||
Bruno BELANYI | 7c89ca9499 | ||
Bruno BELANYI | 77741100e6 | ||
Bruno BELANYI | 2ec356e556 | ||
Bruno BELANYI | 7e63d778f4 | ||
Bruno BELANYI | 5eda15460b | ||
Bruno BELANYI | fa4ea4511a | ||
Bruno BELANYI | 6cc0dc453b | ||
Bruno BELANYI | 8cb61c6323 | ||
Bruno BELANYI | b00e4768fc | ||
Bruno BELANYI | fb40ea0517 | ||
Bruno BELANYI | 660748c6ab | ||
Bruno BELANYI | 245e9dc998 | ||
Bruno BELANYI | a3d1c6b0a9 | ||
Bruno BELANYI | 09ea244442 | ||
Bruno BELANYI | 9f8ab70690 | ||
Bruno BELANYI | 003071a57b | ||
Bruno BELANYI | 2c11ec6866 | ||
Bruno BELANYI | 1d61133661 | ||
Bruno BELANYI | 9624c49a35 | ||
Bruno BELANYI | d1122ab561 | ||
Bruno BELANYI | ef8d402a3d | ||
Bruno BELANYI | 95ae7df24e | ||
Bruno BELANYI | 94788946a3 | ||
Bruno BELANYI | 94b43da45c | ||
Bruno BELANYI | fe0d20ad03 | ||
Bruno BELANYI | 82b8354edc | ||
Bruno BELANYI | ec1558efe2 | ||
Bruno BELANYI | 2646a1609d | ||
Bruno BELANYI | 05afd2ea64 | ||
Bruno BELANYI | 74e43afa72 | ||
Bruno BELANYI | dcd66ec6f4 | ||
Bruno BELANYI | 87a8b8a3d3 | ||
Bruno BELANYI | 9159553e6b | ||
Bruno BELANYI | 75b16e08b1 | ||
Bruno BELANYI | 0547c87c24 | ||
Bruno BELANYI | e69a451189 | ||
Bruno BELANYI | 079e7358de | ||
Bruno BELANYI | 68a8ae07fa | ||
Bruno BELANYI | 40cf84e081 | ||
Bruno BELANYI | 856efa526e | ||
Bruno BELANYI | c9f0b0b1ba | ||
Bruno BELANYI | f5c1b03ddd | ||
Bruno BELANYI | cbdbc36563 | ||
Bruno BELANYI | c4b6536598 | ||
Bruno BELANYI | d0e1d5b427 | ||
Bruno BELANYI | e9c449ee09 | ||
Bruno BELANYI | b7e3101d3a | ||
Bruno BELANYI | 9be6801527 | ||
Bruno BELANYI | b49e09cf9f | ||
Bruno BELANYI | 21fd56d96d | ||
Bruno BELANYI | 56fe76bbaf | ||
Bruno BELANYI | 9f0f9be2d1 | ||
Bruno BELANYI | d412cac964 | ||
Bruno BELANYI | 6551796830 | ||
Bruno BELANYI | 2302d6e0ae | ||
Bruno BELANYI | 9eb34faac0 | ||
Bruno BELANYI | a550355ebe | ||
Bruno BELANYI | 87376fc0ee | ||
Bruno BELANYI | 10e84ed48f | ||
Bruno BELANYI | 49a934f8f6 | ||
Bruno BELANYI | 1d4ec885a4 | ||
Bruno BELANYI | f39187ba8a | ||
Bruno BELANYI | 3b049944e2 | ||
Bruno BELANYI | 874ab7acad | ||
Bruno BELANYI | 8dd7c465de | ||
Bruno BELANYI | b438c7f822 | ||
Bruno BELANYI | c2a38319af | ||
Bruno BELANYI | ed3fa75fb9 | ||
Bruno BELANYI | 8f8d4e6b85 | ||
Bruno BELANYI | 2eb9429f69 | ||
Bruno BELANYI | 69f0ba61c0 | ||
Bruno BELANYI | 85ed83d9a8 | ||
Bruno BELANYI | 275234df8d | ||
Bruno BELANYI | 773150f281 | ||
Bruno BELANYI | e59c6d4d1b | ||
Bruno BELANYI | 2c67bb79bd | ||
Bruno BELANYI | 61b0b76019 | ||
Bruno BELANYI | a84e93e8a0 | ||
Bruno BELANYI | 7177c0f2b2 | ||
Bruno BELANYI | 9d60496ca5 | ||
Bruno BELANYI | fc7ea5bc2b | ||
Bruno BELANYI | 1f2d646838 | ||
Bruno BELANYI | 1c07b0c59e | ||
Bruno BELANYI | 81780a4b72 | ||
Bruno BELANYI | eccc4f3583 | ||
Bruno BELANYI | a34941dbd9 | ||
Bruno BELANYI | c2d2c14696 | ||
Bruno BELANYI | 2c31559722 | ||
Bruno BELANYI | 0edcccdd02 | ||
Bruno BELANYI | 139f3db14f | ||
Bruno BELANYI | 0947c9eb77 | ||
Bruno BELANYI | e4a0d61ebc | ||
Bruno BELANYI | 26fc4a365e | ||
Bruno BELANYI | 1425fd5c4c | ||
Bruno BELANYI | d86e1f8701 | ||
Bruno BELANYI | 56aea0db79 | ||
Bruno BELANYI | 1f36ec0cd1 | ||
Bruno BELANYI | 386c912dbe | ||
Bruno BELANYI | ed5cdb1a95 | ||
Bruno BELANYI | b24b690a61 | ||
Bruno BELANYI | ec31ee08e7 | ||
Bruno BELANYI | efe0bb2b4b | ||
Bruno BELANYI | e8bda4380d | ||
Bruno BELANYI | c81bc2c5d8 | ||
Bruno BELANYI | e07ca6ed2e | ||
Bruno BELANYI | 1aa6199879 | ||
Bruno BELANYI | bc0ee515ba | ||
Bruno BELANYI | e6396d4606 | ||
Bruno BELANYI | d6d7c4cd0c | ||
Bruno BELANYI | 6c160a5350 | ||
Bruno BELANYI | c0bd3a54d0 | ||
Bruno BELANYI | bdcd821ea5 | ||
Bruno BELANYI | 09be17972e | ||
Bruno BELANYI | 56e70c444d | ||
Bruno BELANYI | 45571a06d3 | ||
Bruno BELANYI | 57a50ec803 | ||
Bruno BELANYI | 32597cd01a | ||
Bruno BELANYI | 39d5509da5 | ||
Bruno BELANYI | 83e4e426ab | ||
Bruno BELANYI | f8afee351c | ||
Bruno BELANYI | 586e95d353 | ||
Bruno BELANYI | cdbfc2b973 | ||
Bruno BELANYI | a76a244779 | ||
Bruno BELANYI | 721750965b | ||
Bruno BELANYI | b9bed5c506 | ||
Bruno BELANYI | 8efe93e278 | ||
Bruno BELANYI | 3fbdb62a6d | ||
Bruno BELANYI | f9852eac25 | ||
Bruno BELANYI | ddf4217147 | ||
Bruno BELANYI | 3ad3b9df5d | ||
Bruno BELANYI | 5c8bee8741 | ||
Bruno BELANYI | 09b8e80ca2 | ||
Bruno BELANYI | ebeebbe5ea | ||
Bruno BELANYI | 30fe0f5786 | ||
Bruno BELANYI | a268eb1f1e | ||
Bruno BELANYI | 04329c9fd3 | ||
Bruno BELANYI | 28ee1e006d | ||
Bruno BELANYI | 4f8c876f2d | ||
Bruno BELANYI | 84ea3e2325 | ||
Bruno BELANYI | a1578499a1 | ||
Bruno BELANYI | a5e4bf1715 | ||
Bruno BELANYI | 186c3981c2 | ||
Bruno BELANYI | ec30c78511 | ||
Bruno BELANYI | 70d7ffc8c6 | ||
Bruno BELANYI | 27995b2bb9 | ||
Bruno BELANYI | f416b7c366 | ||
Bruno BELANYI | a895dc761a | ||
Bruno BELANYI | 576769e648 | ||
Bruno BELANYI | 9e0b69d56e | ||
Bruno BELANYI | 8ad65f864f | ||
Bruno BELANYI | 36dfeb9fc2 | ||
Bruno BELANYI | c1047501a6 | ||
Bruno BELANYI | 3217af1859 | ||
Bruno BELANYI | 90cc65bb3a | ||
Bruno BELANYI | 65cb0c224b | ||
Bruno BELANYI | 947a6e9970 | ||
Bruno BELANYI | 68df040691 | ||
Bruno BELANYI | f4bd381a1a | ||
Bruno BELANYI | e85fa35b30 | ||
Bruno BELANYI | eebd801537 | ||
Bruno BELANYI | bb41df8709 | ||
Bruno BELANYI | 223851a430 | ||
Bruno BELANYI | 8713082ed6 | ||
Bruno BELANYI | 3c10941835 | ||
Bruno BELANYI | b2ea586869 | ||
Bruno BELANYI | d6d0f1a94f | ||
Bruno BELANYI | ca46ca6de8 | ||
Bruno BELANYI | 699792cf12 | ||
Bruno BELANYI | 3f55e37b82 | ||
Bruno BELANYI | 8de251a301 | ||
Bruno BELANYI | 5f776c6880 | ||
Bruno BELANYI | 1242388be7 | ||
Bruno BELANYI | 59af5aae07 | ||
Bruno BELANYI | 47f702ec2e | ||
Bruno BELANYI | cf42aaa2b0 | ||
Bruno BELANYI | 72a07f9ac4 | ||
Bruno BELANYI | 3106914906 | ||
Bruno BELANYI | ad8a08e494 | ||
Bruno BELANYI | fc2aa2df6d | ||
Bruno BELANYI | c5e3cac6ed | ||
Bruno BELANYI | b15c967b8d | ||
Bruno BELANYI | 8335513623 | ||
Bruno BELANYI | 1b5bd3faf5 | ||
Bruno BELANYI | a37ef81ec3 | ||
Bruno BELANYI | df3542b7d8 | ||
Bruno BELANYI | 77bcb1e560 | ||
Bruno BELANYI | cb6025af46 | ||
Bruno BELANYI | 74847ab4d8 | ||
Bruno BELANYI | 24062ea43a | ||
Bruno BELANYI | e411c20e5a | ||
Bruno BELANYI | 5d88e60832 | ||
Bruno BELANYI | 4b549d4b23 | ||
Bruno BELANYI | e12a9c9333 | ||
Bruno BELANYI | 35cf0da3dc | ||
Bruno BELANYI | 7b27a4a2fa | ||
Bruno BELANYI | ab3a8a8247 | ||
Bruno BELANYI | 67a5bb9695 | ||
Bruno BELANYI | 00ec65e9b0 | ||
Bruno BELANYI | 59fafe6140 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Generated by Nix
|
||||
/.pre-commit-config.yaml
|
108
2019/d03/ex2/ex2.py
Executable file
108
2019/d03/ex2/ex2.py
Executable file
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from fractions import Fraction
|
||||
from typing import List, NamedTuple, Optional
|
||||
|
||||
|
||||
class Point(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
class Line(NamedTuple):
|
||||
p1: Point
|
||||
p2: Point
|
||||
|
||||
|
||||
def manhattan_dist(p1: Point, p2: Point = Point(0, 0)) -> int:
|
||||
dx = p2.x - p1.x if p1.x < p2.x else p1.x - p2.x
|
||||
dy = p2.y - p1.y if p1.y < p2.y else p1.y - p2.y
|
||||
return dx + dy
|
||||
|
||||
|
||||
def intersect(l1: Line, l2: Line) -> Optional[Point]:
|
||||
(x1, y1), (x2, y2) = l1.p1, l1.p2
|
||||
(x3, y3), (x4, y4) = l2.p1, l2.p2
|
||||
|
||||
den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)
|
||||
|
||||
if den == 0: # Parallel lines
|
||||
return None
|
||||
|
||||
t = Fraction((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4), den)
|
||||
if t < 0 or t > 1: # Out of l1
|
||||
return None
|
||||
|
||||
u = -Fraction((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3), den)
|
||||
if u < 0 or u > 1: # Out of l2
|
||||
return None
|
||||
|
||||
dx = t * (x2 - x1)
|
||||
dy = t * (y2 - y1)
|
||||
|
||||
assert int(dx) == dx and int(dy) == dy # Sanity checks
|
||||
|
||||
ix = x1 + int(dx)
|
||||
iy = y1 + int(dy)
|
||||
return Point(ix, iy)
|
||||
|
||||
|
||||
def is_on(p: Point, l: Line) -> bool:
|
||||
# Assume that l is horizontal or vertical
|
||||
if l.p1.x == l.p2.x:
|
||||
if l.p1.y < l.p2.y:
|
||||
return p.x == l.p1.x and l.p1.y <= p.y <= l.p2.y
|
||||
elif l.p2.y < l.p1.y:
|
||||
return p.x == l.p1.x and l.p2.y <= p.y <= l.p1.y
|
||||
elif l.p1.y == l.p2.y:
|
||||
if l.p1.x < l.p2.x:
|
||||
return p.y == l.p1.y and l.p1.x <= p.x <= l.p2.x
|
||||
elif l.p2.x < l.p1.x:
|
||||
return p.y == l.p1.y and l.p2.x <= p.x <= l.p1.x
|
||||
assert False # Sanity checks
|
||||
|
||||
|
||||
def parse_line(directions: str) -> List[Line]:
|
||||
prev = Point(0, 0)
|
||||
ans = []
|
||||
for inst in directions.split(","):
|
||||
direction, length = inst[0], int(inst[1:])
|
||||
new_x, new_y = prev
|
||||
if direction == "U":
|
||||
new_y += length
|
||||
elif direction == "R":
|
||||
new_x += length
|
||||
if direction == "D":
|
||||
new_y -= length
|
||||
elif direction == "L":
|
||||
new_x -= length
|
||||
new = Point(new_x, new_y)
|
||||
ans.append(Line(prev, new))
|
||||
prev = new
|
||||
return ans
|
||||
|
||||
|
||||
def compute_delay(p: Point, lines: List[Line]) -> int:
|
||||
dist = 0
|
||||
for l in lines:
|
||||
if is_on(p, l):
|
||||
return dist + manhattan_dist(l.p1, p)
|
||||
dist += manhattan_dist(l.p1, l.p2)
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def main() -> None:
|
||||
wire1, wire2 = tuple(parse_line(l) for l in sys.stdin)
|
||||
intersections = [intersect(l1, l2) for l1 in wire1 for l2 in wire2]
|
||||
print(
|
||||
min(
|
||||
compute_delay(x, wire1) + compute_delay(x, wire2)
|
||||
for x in intersections
|
||||
if x is not None and x != Point(0, 0) # Discard origin
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
34
2019/d04/ex1/ex1.py
Executable file
34
2019/d04/ex1/ex1.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from typing import Iterator
|
||||
|
||||
|
||||
def is_valid_password(p: int) -> bool:
|
||||
digits = str(p)
|
||||
|
||||
def has_adjacent_digit():
|
||||
for a, b in zip(digits, digits[1:]):
|
||||
if a == b:
|
||||
return True
|
||||
return False
|
||||
|
||||
def digits_never_decrease():
|
||||
return all(a == b for a, b in zip(sorted(digits), digits))
|
||||
|
||||
return has_adjacent_digit() and digits_never_decrease()
|
||||
|
||||
|
||||
def compute_pass(begin: int, end: int) -> Iterator[int]:
|
||||
for p in range(begin, end + 1):
|
||||
if is_valid_password(p):
|
||||
yield p
|
||||
|
||||
|
||||
def main() -> None:
|
||||
begin = 264793
|
||||
end = 803935
|
||||
print(sum(1 for p in compute_pass(begin, end)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
35
2019/d04/ex2/ex2.py
Executable file
35
2019/d04/ex2/ex2.py
Executable file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from typing import Iterator
|
||||
|
||||
|
||||
def is_valid_password(p: int) -> bool:
|
||||
digits = str(p)
|
||||
|
||||
def has_unique_adjacent_digit():
|
||||
counts = {d: 0 for d in range(10)}
|
||||
for a, b in zip(digits, digits[1:]):
|
||||
if a == b:
|
||||
counts[int(a)] += 1
|
||||
return any(count == 1 for count in counts.values())
|
||||
|
||||
def digits_never_decrease():
|
||||
return all(a == b for a, b in zip(sorted(digits), digits))
|
||||
|
||||
return has_unique_adjacent_digit() and digits_never_decrease()
|
||||
|
||||
|
||||
def compute_pass(begin: int, end: int) -> Iterator[int]:
|
||||
for p in range(begin, end + 1):
|
||||
if is_valid_password(p):
|
||||
yield p
|
||||
|
||||
|
||||
def main() -> None:
|
||||
begin = 264793
|
||||
end = 803935
|
||||
print(sum(1 for p in compute_pass(begin, end)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
101
2019/d05/ex1/ex1.py
Executable file
101
2019/d05/ex1/ex1.py
Executable file
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
def do_addition(instr: Instruction, memory: List[int]) -> int:
|
||||
lhs, rhs, dest = memory[instr.address + 1 : instr.address + 4]
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = memory[lhs]
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = memory[rhs]
|
||||
assert instr.p3_mode != ParameterMode.IMMEDIATE # Sanity check
|
||||
memory[dest] = lhs + rhs
|
||||
|
||||
return 4 # Length of the instruction
|
||||
|
||||
|
||||
def do_multiplication(instr: Instruction, memory: List[int]) -> int:
|
||||
lhs, rhs, dest = memory[instr.address + 1 : instr.address + 4]
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = memory[lhs]
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = memory[rhs]
|
||||
assert instr.p3_mode != ParameterMode.IMMEDIATE # Sanity check
|
||||
memory[dest] = lhs * rhs
|
||||
|
||||
return 4 # Length of the instruction
|
||||
|
||||
|
||||
def do_input(instr: Instruction, memory: List[int]) -> int:
|
||||
value = int(input())
|
||||
param = memory[instr.address + 1]
|
||||
|
||||
assert instr.p1_mode == ParameterMode.POSITION # Sanity check
|
||||
memory[param] = value
|
||||
|
||||
return 2 # Length of the instruction
|
||||
|
||||
|
||||
def do_output(instr: Instruction, memory: List[int]) -> int:
|
||||
value = memory[instr.address + 1]
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
value = memory[value]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
print(value)
|
||||
|
||||
return 2 # Length of the instruction
|
||||
|
||||
|
||||
def run_op(memory: List[int]) -> None:
|
||||
index = 0
|
||||
while True:
|
||||
instr = lookup_ops(index, memory)
|
||||
if instr.op == 99: # Halt
|
||||
return
|
||||
elif instr.op == 1: # Sum
|
||||
index += do_addition(instr, memory)
|
||||
elif instr.op == 2: # Multiplication
|
||||
index += do_multiplication(instr, memory)
|
||||
elif instr.op == 3: # Load from input
|
||||
index += do_input(instr, memory)
|
||||
elif instr.op == 4: # Store to output
|
||||
index += do_output(instr, memory)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
with open("input") as mem_f:
|
||||
memory = [int(n) for n in mem_f.read().split(",")]
|
||||
run_op(memory)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d05/ex1/input
Normal file
1
2019/d05/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,225,1,225,6,6,1100,1,238,225,104,0,1002,114,46,224,1001,224,-736,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,223,1,166,195,224,1001,224,-137,224,4,224,102,8,223,223,101,5,224,224,1,223,224,223,1001,169,83,224,1001,224,-90,224,4,224,102,8,223,223,1001,224,2,224,1,224,223,223,101,44,117,224,101,-131,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1101,80,17,225,1101,56,51,225,1101,78,89,225,1102,48,16,225,1101,87,78,225,1102,34,33,224,101,-1122,224,224,4,224,1002,223,8,223,101,7,224,224,1,223,224,223,1101,66,53,224,101,-119,224,224,4,224,102,8,223,223,1001,224,5,224,1,223,224,223,1102,51,49,225,1101,7,15,225,2,110,106,224,1001,224,-4539,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1102,88,78,225,102,78,101,224,101,-6240,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1107,226,677,224,102,2,223,223,1006,224,329,101,1,223,223,1108,226,677,224,1002,223,2,223,1005,224,344,101,1,223,223,8,226,677,224,102,2,223,223,1006,224,359,1001,223,1,223,1007,226,677,224,1002,223,2,223,1005,224,374,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,389,1001,223,1,223,1108,677,226,224,1002,223,2,223,1006,224,404,1001,223,1,223,1007,226,226,224,1002,223,2,223,1005,224,419,1001,223,1,223,1107,677,226,224,1002,223,2,223,1006,224,434,101,1,223,223,108,677,677,224,1002,223,2,223,1005,224,449,1001,223,1,223,1107,677,677,224,102,2,223,223,1005,224,464,1001,223,1,223,108,226,226,224,1002,223,2,223,1006,224,479,1001,223,1,223,1008,226,226,224,102,2,223,223,1005,224,494,101,1,223,223,108,677,226,224,102,2,223,223,1005,224,509,1001,223,1,223,8,677,226,224,1002,223,2,223,1006,224,524,101,1,223,223,7,226,677,224,1002,223,2,223,1006,224,539,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,554,1001,223,1,223,7,226,226,224,1002,223,2,223,1006,224,569,101,1,223,223,107,677,677,224,102,2,223,223,1006,224,584,101,1,223,223,1108,677,677,224,102,2,223,223,1006,224,599,1001,223,1,223,1008,677,226,224,1002,223,2,223,1005,224,614,1001,223,1,223,8,677,677,224,1002,223,2,223,1006,224,629,1001,223,1,223,107,226,677,224,1002,223,2,223,1006,224,644,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,659,101,1,223,223,107,226,226,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226
|
199
2019/d05/ex2/ex2.py
Executable file
199
2019/d05/ex2/ex2.py
Executable file
|
@ -0,0 +1,199 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from dataclasses import dataclass
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
return
|
||||
elif instr.op == 1: # Sum
|
||||
self.do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self.do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self.do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self.do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self.do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self.do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self.do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self.do_equal_to(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def do_addition(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = lhs + rhs
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = lhs * rhs
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def do_input(self, instr: Instruction) -> None:
|
||||
value = int(input())
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
assert instr.p1_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[param] = value
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def do_output(self, instr: Instruction) -> None:
|
||||
value = self.memory[instr.address + 1]
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
value = self.memory[value]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
print(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond, value = self.memory[instr.address + 1 : instr.address + 3]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
cond = self.memory[cond]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
value = self.memory[value]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond, value = self.memory[instr.address + 1 : instr.address + 3]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
cond = self.memory[cond]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
value = self.memory[value]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def do_less_than(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = 1 if lhs < rhs else 0
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = 1 if lhs == rhs else 0
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
with open("input") as mem_f:
|
||||
memory = [int(n) for n in mem_f.read().split(",")]
|
||||
computer = Computer(memory)
|
||||
computer.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d05/ex2/input
Normal file
1
2019/d05/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,225,1,225,6,6,1100,1,238,225,104,0,1002,114,46,224,1001,224,-736,224,4,224,1002,223,8,223,1001,224,3,224,1,223,224,223,1,166,195,224,1001,224,-137,224,4,224,102,8,223,223,101,5,224,224,1,223,224,223,1001,169,83,224,1001,224,-90,224,4,224,102,8,223,223,1001,224,2,224,1,224,223,223,101,44,117,224,101,-131,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1101,80,17,225,1101,56,51,225,1101,78,89,225,1102,48,16,225,1101,87,78,225,1102,34,33,224,101,-1122,224,224,4,224,1002,223,8,223,101,7,224,224,1,223,224,223,1101,66,53,224,101,-119,224,224,4,224,102,8,223,223,1001,224,5,224,1,223,224,223,1102,51,49,225,1101,7,15,225,2,110,106,224,1001,224,-4539,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,1102,88,78,225,102,78,101,224,101,-6240,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1107,226,677,224,102,2,223,223,1006,224,329,101,1,223,223,1108,226,677,224,1002,223,2,223,1005,224,344,101,1,223,223,8,226,677,224,102,2,223,223,1006,224,359,1001,223,1,223,1007,226,677,224,1002,223,2,223,1005,224,374,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,389,1001,223,1,223,1108,677,226,224,1002,223,2,223,1006,224,404,1001,223,1,223,1007,226,226,224,1002,223,2,223,1005,224,419,1001,223,1,223,1107,677,226,224,1002,223,2,223,1006,224,434,101,1,223,223,108,677,677,224,1002,223,2,223,1005,224,449,1001,223,1,223,1107,677,677,224,102,2,223,223,1005,224,464,1001,223,1,223,108,226,226,224,1002,223,2,223,1006,224,479,1001,223,1,223,1008,226,226,224,102,2,223,223,1005,224,494,101,1,223,223,108,677,226,224,102,2,223,223,1005,224,509,1001,223,1,223,8,677,226,224,1002,223,2,223,1006,224,524,101,1,223,223,7,226,677,224,1002,223,2,223,1006,224,539,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,554,1001,223,1,223,7,226,226,224,1002,223,2,223,1006,224,569,101,1,223,223,107,677,677,224,102,2,223,223,1006,224,584,101,1,223,223,1108,677,677,224,102,2,223,223,1006,224,599,1001,223,1,223,1008,677,226,224,1002,223,2,223,1005,224,614,1001,223,1,223,8,677,677,224,1002,223,2,223,1006,224,629,1001,223,1,223,107,226,677,224,1002,223,2,223,1006,224,644,101,1,223,223,1007,677,677,224,102,2,223,223,1006,224,659,101,1,223,223,107,226,226,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226
|
53
2019/d06/ex1/ex1.py
Executable file
53
2019/d06/ex1/ex1.py
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrbitGraph:
|
||||
name: str
|
||||
children: List["OrbitGraph"] = field(default_factory=list)
|
||||
|
||||
|
||||
def make_orbits(description: List[str]) -> OrbitGraph:
|
||||
orbits: Dict[str, OrbitGraph] = {}
|
||||
|
||||
def find_or_add(name: str) -> OrbitGraph:
|
||||
if name in orbits:
|
||||
return orbits[name]
|
||||
orbit = OrbitGraph(name)
|
||||
orbits[name] = orbit
|
||||
return orbit
|
||||
|
||||
for l in description:
|
||||
parent, child = map(find_or_add, map(lambda x: x.strip(), l.split(")")))
|
||||
parent.children.append(child)
|
||||
|
||||
return orbits["COM"] # Assume common root is named 'COM'
|
||||
|
||||
|
||||
def count_orbits(root: OrbitGraph) -> int:
|
||||
ans = 0
|
||||
stack = 0 # Count the number of direct and indirect orbits to the current root
|
||||
|
||||
def helper(root: OrbitGraph):
|
||||
nonlocal ans
|
||||
nonlocal stack
|
||||
ans += stack # Count the number of orbits to this node
|
||||
stack += 1 # Add the current root to stack of parents
|
||||
for child in root.children:
|
||||
helper(child) # Count those orbits for each child
|
||||
stack -= 1 # Remove the current root from the stack of parents
|
||||
|
||||
helper(root)
|
||||
return ans
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print(count_orbits(make_orbits(sys.stdin.readlines())))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1069
2019/d06/ex1/input
Normal file
1069
2019/d06/ex1/input
Normal file
File diff suppressed because it is too large
Load diff
86
2019/d06/ex2/ex2.py
Executable file
86
2019/d06/ex2/ex2.py
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrbitGraph:
|
||||
name: str
|
||||
children: List["OrbitGraph"] = field(default_factory=list)
|
||||
|
||||
|
||||
def make_orbits(description: List[str]) -> OrbitGraph:
|
||||
orbits: Dict[str, OrbitGraph] = {}
|
||||
|
||||
def find_or_add(name: str) -> OrbitGraph:
|
||||
if name in orbits:
|
||||
return orbits[name]
|
||||
orbit = OrbitGraph(name)
|
||||
orbits[name] = orbit
|
||||
return orbit
|
||||
|
||||
for l in description:
|
||||
parent, child = map(find_or_add, map(lambda x: x.strip(), l.split(")")))
|
||||
parent.children.append(child)
|
||||
|
||||
return orbits["COM"] # Assume common root is named 'COM'
|
||||
|
||||
|
||||
def count_orbits_hop(root: OrbitGraph) -> int:
|
||||
nodes: List[OrbitGraph] = []
|
||||
|
||||
def ind_node(node: OrbitGraph) -> int:
|
||||
return nodes.index(node)
|
||||
|
||||
def fill_nodes(root: OrbitGraph) -> None:
|
||||
nodes.append(root)
|
||||
for child in root.children:
|
||||
fill_nodes(child)
|
||||
|
||||
fill_nodes(root)
|
||||
n = len(nodes)
|
||||
dist: List[List[int]] = [[2 * n] * len(nodes) for __ in range(len(nodes))]
|
||||
next_nodes: List[List[Optional[OrbitGraph]]] = [[None] * n for __ in range(n)]
|
||||
|
||||
def fill_mat(root: OrbitGraph) -> None:
|
||||
# From root to itself
|
||||
dist[ind_node(root)][ind_node(root)] = 0
|
||||
next_nodes[ind_node(root)][ind_node(root)] = root
|
||||
for child in root.children:
|
||||
# From root to child
|
||||
dist[ind_node(root)][ind_node(child)] = 1
|
||||
next_nodes[ind_node(root)][ind_node(child)] = child
|
||||
# The other way
|
||||
dist[ind_node(child)][ind_node(root)] = 1
|
||||
next_nodes[ind_node(child)][ind_node(root)] = root
|
||||
# Do it again
|
||||
fill_mat(child)
|
||||
|
||||
fill_mat(root)
|
||||
|
||||
for k in range(n):
|
||||
print(f"{k} / {n} rounds")
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
new_dist = dist[i][k] + dist[k][j]
|
||||
if dist[i][j] > new_dist:
|
||||
dist[i][j] = new_dist
|
||||
next_nodes[i][j] = next_nodes[i][k]
|
||||
|
||||
useful_indices: Dict[str, int] = {}
|
||||
for index, node in enumerate(nodes):
|
||||
if node.name in ("YOU", "SAN"):
|
||||
useful_indices[node.name] = index
|
||||
return (
|
||||
dist[useful_indices["YOU"]][useful_indices["SAN"]] - 2
|
||||
) # Because we are in orbit
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print(count_orbits_hop(make_orbits(sys.stdin.readlines())))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1069
2019/d06/ex2/input
Normal file
1069
2019/d06/ex2/input
Normal file
File diff suppressed because it is too large
Load diff
263
2019/d07/ex1/ex1.py
Executable file
263
2019/d07/ex1/ex1.py
Executable file
|
@ -0,0 +1,263 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Mypy has issues with assigning Callable to fields of objects
|
||||
# See https://github.com/python/mypy/issues/708
|
||||
# type: ignore
|
||||
|
||||
import itertools
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
from enum import IntEnum
|
||||
from typing import Callable, List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
read_input: Callable[[], str] = input
|
||||
print_output: Callable[[int], None] = print
|
||||
|
||||
def run(self) -> None:
|
||||
is_halted = self.run_single()
|
||||
while not is_halted:
|
||||
is_halted = self.run_single()
|
||||
|
||||
def run_single(self) -> bool: # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
return True # Halted
|
||||
elif instr.op == 1: # Sum
|
||||
self.do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self.do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self.do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self.do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self.do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self.do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self.do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self.do_equal_to(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
return False # Not halted
|
||||
|
||||
def do_addition(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = lhs + rhs
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = lhs * rhs
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def do_input(self, instr: Instruction) -> None:
|
||||
value = int(self.read_input())
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
assert instr.p1_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[param] = value
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def do_output(self, instr: Instruction) -> None:
|
||||
value = self.memory[instr.address + 1]
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
value = self.memory[value]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
self.print_output(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond, value = self.memory[instr.address + 1 : instr.address + 3]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
cond = self.memory[cond]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
value = self.memory[value]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond, value = self.memory[instr.address + 1 : instr.address + 3]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
cond = self.memory[cond]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
value = self.memory[value]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def do_less_than(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = 1 if lhs < rhs else 0
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs, rhs, dest = self.memory[instr.address + 1 : instr.address + 4]
|
||||
|
||||
if instr.p1_mode == ParameterMode.POSITION:
|
||||
lhs = self.memory[lhs]
|
||||
else:
|
||||
assert instr.p1_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
if instr.p2_mode == ParameterMode.POSITION:
|
||||
rhs = self.memory[rhs]
|
||||
else:
|
||||
assert instr.p2_mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = 1 if lhs == rhs else 0
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
def get_input_fun(phase: int, last_output: List[int]) -> Callable[[], str]:
|
||||
has_been_called = False
|
||||
|
||||
def _input() -> str:
|
||||
nonlocal has_been_called
|
||||
if has_been_called:
|
||||
return str(last_output.pop(0))
|
||||
has_been_called = True
|
||||
return str(phase)
|
||||
|
||||
return _input
|
||||
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
max = 0
|
||||
ans = tuple(-1 for __ in range(5))
|
||||
for a, b, c, d, e in itertools.permutations(range(5)):
|
||||
amp1 = Computer(deepcopy(memory))
|
||||
amp1_output: List[int] = []
|
||||
amp1.read_input = get_input_fun(a, [0])
|
||||
amp1.print_output = lambda x: amp1_output.append(int(x))
|
||||
|
||||
amp2 = Computer(deepcopy(memory))
|
||||
amp2_output: List[int] = []
|
||||
amp2.read_input = get_input_fun(b, amp1_output)
|
||||
amp2.print_output = lambda x: amp2_output.append(int(x))
|
||||
|
||||
amp3 = Computer(deepcopy(memory))
|
||||
amp3_output: List[int] = []
|
||||
amp3.read_input = get_input_fun(c, amp2_output)
|
||||
amp3.print_output = lambda x: amp3_output.append(int(x))
|
||||
|
||||
amp4 = Computer(deepcopy(memory))
|
||||
amp4_output: List[int] = []
|
||||
amp4.read_input = get_input_fun(d, amp3_output)
|
||||
amp4.print_output = lambda x: amp4_output.append(int(x))
|
||||
|
||||
amp5 = Computer(deepcopy(memory))
|
||||
amp5_output: List[int] = []
|
||||
amp5.read_input = get_input_fun(e, amp4_output)
|
||||
amp5.print_output = lambda x: amp5_output.append(int(x))
|
||||
|
||||
amp1.run()
|
||||
amp2.run()
|
||||
amp3.run()
|
||||
amp4.run()
|
||||
amp5.run()
|
||||
|
||||
res = amp5_output.pop(0)
|
||||
if res > max:
|
||||
max = res
|
||||
ans = (a, b, c, d, e)
|
||||
print(f"Max: {max}, res: {ans}")
|
||||
|
||||
print(f"Final one: {max}, with {ans}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d07/ex1/input
Normal file
1
2019/d07/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,8,1001,8,10,8,105,1,0,0,21,46,55,76,89,106,187,268,349,430,99999,3,9,101,4,9,9,1002,9,2,9,101,5,9,9,1002,9,2,9,101,2,9,9,4,9,99,3,9,1002,9,5,9,4,9,99,3,9,1001,9,2,9,1002,9,4,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,1001,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,4,9,1001,9,4,9,102,5,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99
|
196
2019/d07/ex2/ex2.py
Executable file
196
2019/d07/ex2/ex2.py
Executable file
|
@ -0,0 +1,196 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import itertools
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = lhs + rhs
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = lhs * rhs
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
assert instr.p1_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[param] = value
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = 1 if lhs < rhs else 0
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
assert instr.p3_mode == ParameterMode.POSITION # Sanity check
|
||||
self.memory[dest] = 1 if lhs == rhs else 0
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
max = 0
|
||||
ans = tuple(-1 for __ in range(5))
|
||||
for perm in itertools.permutations(range(5, 10)):
|
||||
amps = [Computer(deepcopy(memory), input_list=[phase]) for phase in perm]
|
||||
|
||||
amp1 = amps[0] # Keep track of this guy for the output solution
|
||||
amp1.input_list.append(0) # Initial input
|
||||
|
||||
while not all(amp.is_halted for amp in amps):
|
||||
# Put a non halted comuter to the front
|
||||
while amps[0].is_halted:
|
||||
amps.append(amps.pop(0))
|
||||
# Run it until exhaustion or input/output interrupt
|
||||
try:
|
||||
amps[0].run()
|
||||
except InputInterrupt:
|
||||
amps.append(amps.pop(0))
|
||||
except OutputInterrupt:
|
||||
amps[1].input_list.append(amps[0].output_list.pop())
|
||||
|
||||
res = amp1.input_list.pop(0) # Amplifier 5 output to amplifier 1 at the end
|
||||
if res > max:
|
||||
max = res
|
||||
ans = perm
|
||||
print(f"Max: {max}, res: {ans}")
|
||||
|
||||
print(f"Final one: {max}, with {ans}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d07/ex2/input
Normal file
1
2019/d07/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,8,1001,8,10,8,105,1,0,0,21,46,55,76,89,106,187,268,349,430,99999,3,9,101,4,9,9,1002,9,2,9,101,5,9,9,1002,9,2,9,101,2,9,9,4,9,99,3,9,1002,9,5,9,4,9,99,3,9,1001,9,2,9,1002,9,4,9,101,2,9,9,1002,9,3,9,4,9,99,3,9,1001,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,4,9,1001,9,4,9,102,5,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99
|
25
2019/d08/ex1/ex1.py
Executable file
25
2019/d08/ex1/ex1.py
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main() -> None:
|
||||
COLUMNS = 25
|
||||
ROWS = 6
|
||||
digits = [int(d) for d in str(int(sys.stdin.read()))]
|
||||
|
||||
assert len(digits) % (COLUMNS * ROWS) == 0 # Sanity check
|
||||
LAYERS = int(len(digits) / (COLUMNS * ROWS))
|
||||
|
||||
layers = [
|
||||
[digits.pop(0) for __ in range(COLUMNS) for __ in range(ROWS)]
|
||||
for __ in range(LAYERS)
|
||||
]
|
||||
|
||||
least_zeros = min(layers, key=lambda l: sum(1 for d in l if d == 0))
|
||||
|
||||
print(sum(1 for d in least_zeros if d == 1) * sum(1 for d in least_zeros if d == 2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d08/ex1/input
Normal file
1
2019/d08/ex1/input
Normal file
File diff suppressed because one or more lines are too long
32
2019/d08/ex2/ex2.py
Executable file
32
2019/d08/ex2/ex2.py
Executable file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def main() -> None:
|
||||
COLUMNS = 25
|
||||
ROWS = 6
|
||||
digits = [int(d) for d in str(int(sys.stdin.read()))]
|
||||
|
||||
assert len(digits) % (COLUMNS * ROWS) == 0 # Sanity check
|
||||
LAYERS = int(len(digits) / (COLUMNS * ROWS))
|
||||
|
||||
layers = [
|
||||
[digits.pop(0) for __ in range(COLUMNS) for __ in range(ROWS)]
|
||||
for __ in range(LAYERS)
|
||||
]
|
||||
|
||||
ans = []
|
||||
for pixels in zip(*(layer for layer in layers)):
|
||||
ans.append(next(color for color in pixels if color != 2))
|
||||
|
||||
print(
|
||||
"\n".join(
|
||||
"".join("█" if ans.pop(0) == 0 else " " for __ in range(COLUMNS))
|
||||
for __ in range(ROWS)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d08/ex2/input
Normal file
1
2019/d08/ex2/input
Normal file
File diff suppressed because one or more lines are too long
210
2019/d09/ex1/ex1.py
Executable file
210
2019/d09/ex1/ex1.py
Executable file
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
computer = Computer(deepcopy(memory), input_list=[1])
|
||||
|
||||
computer.run_no_output_interrupt()
|
||||
print(computer.output_list.pop())
|
||||
assert len(computer.output_list) == 0 # Sanity check
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d09/ex1/input
Normal file
1
2019/d09/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,1,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,26,1,1005,1101,0,24,1019,1102,1,32,1007,1101,0,704,1027,1102,0,1,1020,1101,0,348,1029,1102,28,1,1002,1101,34,0,1016,1102,29,1,1008,1102,1,30,1013,1102,25,1,1012,1101,0,33,1009,1102,1,37,1001,1101,31,0,1017,1101,245,0,1022,1102,39,1,1000,1101,27,0,1011,1102,770,1,1025,1101,0,22,1015,1102,1,1,1021,1101,711,0,1026,1101,20,0,1004,1101,0,23,1018,1101,242,0,1023,1102,21,1,1003,1101,38,0,1010,1101,0,35,1014,1101,0,36,1006,1101,0,357,1028,1102,1,775,1024,109,-3,2102,1,9,63,1008,63,36,63,1005,63,203,4,187,1105,1,207,1001,64,1,64,1002,64,2,64,109,8,21101,40,0,5,1008,1010,41,63,1005,63,227,1106,0,233,4,213,1001,64,1,64,1002,64,2,64,109,16,2105,1,2,1105,1,251,4,239,1001,64,1,64,1002,64,2,64,109,1,21107,41,40,-4,1005,1018,271,1001,64,1,64,1105,1,273,4,257,1002,64,2,64,109,-18,1207,0,21,63,1005,63,295,4,279,1001,64,1,64,1105,1,295,1002,64,2,64,109,-3,1207,0,36,63,1005,63,311,1105,1,317,4,301,1001,64,1,64,1002,64,2,64,109,6,2108,20,-3,63,1005,63,339,4,323,1001,64,1,64,1106,0,339,1002,64,2,64,109,28,2106,0,-7,4,345,1001,64,1,64,1106,0,357,1002,64,2,64,109,-18,1206,4,373,1001,64,1,64,1105,1,375,4,363,1002,64,2,64,109,-6,2107,31,-4,63,1005,63,397,4,381,1001,64,1,64,1105,1,397,1002,64,2,64,109,1,21102,42,1,-1,1008,1011,39,63,1005,63,421,1001,64,1,64,1106,0,423,4,403,1002,64,2,64,109,-2,2108,26,-2,63,1005,63,439,1106,0,445,4,429,1001,64,1,64,1002,64,2,64,109,6,21102,43,1,-5,1008,1011,43,63,1005,63,467,4,451,1105,1,471,1001,64,1,64,1002,64,2,64,109,6,21101,44,0,-3,1008,1019,44,63,1005,63,493,4,477,1105,1,497,1001,64,1,64,1002,64,2,64,109,-9,1206,7,511,4,503,1105,1,515,1001,64,1,64,1002,64,2,64,109,14,1205,-7,531,1001,64,1,64,1106,0,533,4,521,1002,64,2,64,109,-27,1201,0,0,63,1008,63,39,63,1005,63,555,4,539,1105,1,559,1001,64,1,64,1002,64,2,64,109,10,2101,0,-5,63,1008,63,24,63,1005,63,583,1001,64,1,64,1105,1,585,4,565,1002,64,2,64,109,-11,2107,21,5,63,1005,63,601,1105,1,607,4,591,1001,64,1,64,1002,64,2,64,109,10,1208,0,36,63,1005,63,627,1001,64,1,64,1106,0,629,4,613,1002,64,2,64,109,15,21108,45,45,-9,1005,1015,647,4,635,1105,1,651,1001,64,1,64,1002,64,2,64,109,-19,2101,0,-4,63,1008,63,37,63,1005,63,677,4,657,1001,64,1,64,1106,0,677,1002,64,2,64,109,22,1205,-6,695,4,683,1001,64,1,64,1105,1,695,1002,64,2,64,109,-10,2106,0,10,1001,64,1,64,1105,1,713,4,701,1002,64,2,64,109,-9,1201,-8,0,63,1008,63,36,63,1005,63,733,1105,1,739,4,719,1001,64,1,64,1002,64,2,64,109,7,21107,46,47,0,1005,1015,757,4,745,1106,0,761,1001,64,1,64,1002,64,2,64,109,14,2105,1,-5,4,767,1105,1,779,1001,64,1,64,1002,64,2,64,109,-34,2102,1,6,63,1008,63,39,63,1005,63,799,1105,1,805,4,785,1001,64,1,64,1002,64,2,64,109,25,21108,47,49,-4,1005,1016,825,1001,64,1,64,1106,0,827,4,811,1002,64,2,64,109,-6,1208,-8,36,63,1005,63,845,4,833,1106,0,849,1001,64,1,64,1002,64,2,64,109,-10,1202,2,1,63,1008,63,36,63,1005,63,875,4,855,1001,64,1,64,1105,1,875,1002,64,2,64,109,-5,1202,10,1,63,1008,63,30,63,1005,63,895,1106,0,901,4,881,1001,64,1,64,4,64,99,21101,27,0,1,21101,0,915,0,1105,1,922,21201,1,65916,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1105,1,922,21201,1,0,-1,21201,-2,-3,1,21102,1,957,0,1105,1,922,22201,1,-1,-2,1106,0,968,22102,1,-2,-2,109,-3,2105,1,0
|
210
2019/d09/ex2/ex2.py
Executable file
210
2019/d09/ex2/ex2.py
Executable file
|
@ -0,0 +1,210 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
computer = Computer(deepcopy(memory), input_list=[2])
|
||||
|
||||
computer.run_no_output_interrupt()
|
||||
print(computer.output_list.pop())
|
||||
assert len(computer.output_list) == 0 # Sanity check
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d09/ex2/input
Normal file
1
2019/d09/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,1,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,26,1,1005,1101,0,24,1019,1102,1,32,1007,1101,0,704,1027,1102,0,1,1020,1101,0,348,1029,1102,28,1,1002,1101,34,0,1016,1102,29,1,1008,1102,1,30,1013,1102,25,1,1012,1101,0,33,1009,1102,1,37,1001,1101,31,0,1017,1101,245,0,1022,1102,39,1,1000,1101,27,0,1011,1102,770,1,1025,1101,0,22,1015,1102,1,1,1021,1101,711,0,1026,1101,20,0,1004,1101,0,23,1018,1101,242,0,1023,1102,21,1,1003,1101,38,0,1010,1101,0,35,1014,1101,0,36,1006,1101,0,357,1028,1102,1,775,1024,109,-3,2102,1,9,63,1008,63,36,63,1005,63,203,4,187,1105,1,207,1001,64,1,64,1002,64,2,64,109,8,21101,40,0,5,1008,1010,41,63,1005,63,227,1106,0,233,4,213,1001,64,1,64,1002,64,2,64,109,16,2105,1,2,1105,1,251,4,239,1001,64,1,64,1002,64,2,64,109,1,21107,41,40,-4,1005,1018,271,1001,64,1,64,1105,1,273,4,257,1002,64,2,64,109,-18,1207,0,21,63,1005,63,295,4,279,1001,64,1,64,1105,1,295,1002,64,2,64,109,-3,1207,0,36,63,1005,63,311,1105,1,317,4,301,1001,64,1,64,1002,64,2,64,109,6,2108,20,-3,63,1005,63,339,4,323,1001,64,1,64,1106,0,339,1002,64,2,64,109,28,2106,0,-7,4,345,1001,64,1,64,1106,0,357,1002,64,2,64,109,-18,1206,4,373,1001,64,1,64,1105,1,375,4,363,1002,64,2,64,109,-6,2107,31,-4,63,1005,63,397,4,381,1001,64,1,64,1105,1,397,1002,64,2,64,109,1,21102,42,1,-1,1008,1011,39,63,1005,63,421,1001,64,1,64,1106,0,423,4,403,1002,64,2,64,109,-2,2108,26,-2,63,1005,63,439,1106,0,445,4,429,1001,64,1,64,1002,64,2,64,109,6,21102,43,1,-5,1008,1011,43,63,1005,63,467,4,451,1105,1,471,1001,64,1,64,1002,64,2,64,109,6,21101,44,0,-3,1008,1019,44,63,1005,63,493,4,477,1105,1,497,1001,64,1,64,1002,64,2,64,109,-9,1206,7,511,4,503,1105,1,515,1001,64,1,64,1002,64,2,64,109,14,1205,-7,531,1001,64,1,64,1106,0,533,4,521,1002,64,2,64,109,-27,1201,0,0,63,1008,63,39,63,1005,63,555,4,539,1105,1,559,1001,64,1,64,1002,64,2,64,109,10,2101,0,-5,63,1008,63,24,63,1005,63,583,1001,64,1,64,1105,1,585,4,565,1002,64,2,64,109,-11,2107,21,5,63,1005,63,601,1105,1,607,4,591,1001,64,1,64,1002,64,2,64,109,10,1208,0,36,63,1005,63,627,1001,64,1,64,1106,0,629,4,613,1002,64,2,64,109,15,21108,45,45,-9,1005,1015,647,4,635,1105,1,651,1001,64,1,64,1002,64,2,64,109,-19,2101,0,-4,63,1008,63,37,63,1005,63,677,4,657,1001,64,1,64,1106,0,677,1002,64,2,64,109,22,1205,-6,695,4,683,1001,64,1,64,1105,1,695,1002,64,2,64,109,-10,2106,0,10,1001,64,1,64,1105,1,713,4,701,1002,64,2,64,109,-9,1201,-8,0,63,1008,63,36,63,1005,63,733,1105,1,739,4,719,1001,64,1,64,1002,64,2,64,109,7,21107,46,47,0,1005,1015,757,4,745,1106,0,761,1001,64,1,64,1002,64,2,64,109,14,2105,1,-5,4,767,1105,1,779,1001,64,1,64,1002,64,2,64,109,-34,2102,1,6,63,1008,63,39,63,1005,63,799,1105,1,805,4,785,1001,64,1,64,1002,64,2,64,109,25,21108,47,49,-4,1005,1016,825,1001,64,1,64,1106,0,827,4,811,1002,64,2,64,109,-6,1208,-8,36,63,1005,63,845,4,833,1106,0,849,1001,64,1,64,1002,64,2,64,109,-10,1202,2,1,63,1008,63,36,63,1005,63,875,4,855,1001,64,1,64,1105,1,875,1002,64,2,64,109,-5,1202,10,1,63,1008,63,30,63,1005,63,895,1106,0,901,4,881,1001,64,1,64,4,64,99,21101,27,0,1,21101,0,915,0,1105,1,922,21201,1,65916,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1105,1,922,21201,1,0,-1,21201,-2,-3,1,21102,1,957,0,1105,1,922,22201,1,-1,-2,1106,0,968,22102,1,-2,-2,109,-3,2105,1,0
|
51
2019/d10/ex1/ex1.py
Executable file
51
2019/d10/ex1/ex1.py
Executable file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from math import gcd
|
||||
from typing import NamedTuple, Set
|
||||
|
||||
|
||||
class Position(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
def main() -> None:
|
||||
asteroids = [
|
||||
Position(x, y)
|
||||
for y, line in enumerate(sys.stdin.readlines())
|
||||
for x, c in enumerate(line.rstrip())
|
||||
if c == "#"
|
||||
]
|
||||
|
||||
def count_spotted(x: int, y: int) -> int:
|
||||
seen: Set[Position] = set()
|
||||
ans = 0
|
||||
radius = 1
|
||||
|
||||
while True:
|
||||
|
||||
def is_r_away(pos: Position) -> bool:
|
||||
return max(abs(pos.x - x), abs(pos.y - y)) == radius
|
||||
|
||||
to_visit = list(filter(is_r_away, asteroids))
|
||||
radius += 1
|
||||
if len(to_visit) == 0:
|
||||
break
|
||||
for pos in to_visit:
|
||||
rel = (pos.x - x, pos.y - y)
|
||||
common = gcd(*rel)
|
||||
rel = Position(*(a // common for a in rel))
|
||||
if rel in seen:
|
||||
continue # Already have an asteroid on this path
|
||||
seen.add(rel)
|
||||
ans += 1
|
||||
|
||||
return ans
|
||||
|
||||
ans, x, y = max((count_spotted(*pos), *pos) for pos in asteroids)
|
||||
print(f"({x}, {y}): {ans}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
31
2019/d10/ex1/input
Normal file
31
2019/d10/ex1/input
Normal file
|
@ -0,0 +1,31 @@
|
|||
#...##.####.#.......#.##..##.#.
|
||||
#.##.#..#..#...##..##.##.#.....
|
||||
#..#####.#......#..#....#.###.#
|
||||
...#.#.#...#..#.....#..#..#.#..
|
||||
.#.....##..#...#..#.#...##.....
|
||||
##.....#..........##..#......##
|
||||
.##..##.#.#....##..##.......#..
|
||||
#.##.##....###..#...##...##....
|
||||
##.#.#............##..#...##..#
|
||||
###..##.###.....#.##...####....
|
||||
...##..#...##...##..#.#..#...#.
|
||||
..#.#.##.#.#.#####.#....####.#.
|
||||
#......###.##....#...#...#...##
|
||||
.....#...#.#.#.#....#...#......
|
||||
#..#.#.#..#....#..#...#..#..##.
|
||||
#.....#..##.....#...###..#..#.#
|
||||
.....####.#..#...##..#..#..#..#
|
||||
..#.....#.#........#.#.##..####
|
||||
.#.....##..#.##.....#...###....
|
||||
###.###....#..#..#.....#####...
|
||||
#..##.##..##.#.#....#.#......#.
|
||||
.#....#.##..#.#.#.......##.....
|
||||
##.##...#...#....###.#....#....
|
||||
.....#.######.#.#..#..#.#.....#
|
||||
.#..#.##.#....#.##..#.#...##..#
|
||||
.##.###..#..#..#.###...#####.#.
|
||||
#...#...........#.....#.......#
|
||||
#....##.#.#..##...#..####...#..
|
||||
#.####......#####.....#.##..#..
|
||||
.#...#....#...##..##.#.#......#
|
||||
#..###.....##.#.......#.##...##
|
86
2019/d10/ex2/ex2.py
Executable file
86
2019/d10/ex2/ex2.py
Executable file
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from cmath import phase
|
||||
from itertools import groupby
|
||||
from math import gcd, pi
|
||||
from typing import NamedTuple, Set, Tuple
|
||||
|
||||
|
||||
class Position(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
def pos_to_angle_dist(pos: Position) -> Tuple[float, float]:
|
||||
cartesian = complex(*pos)
|
||||
angle = phase(cartesian)
|
||||
if angle < -pi / 2:
|
||||
angle += 2.5 * pi
|
||||
else:
|
||||
angle += pi / 2
|
||||
return (angle, abs(cartesian))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
asteroids = [
|
||||
Position(x, y)
|
||||
for y, line in enumerate(sys.stdin.readlines())
|
||||
for x, c in enumerate(line.rstrip())
|
||||
if c == "#"
|
||||
]
|
||||
|
||||
def count_spotted(x: int, y: int) -> int:
|
||||
seen: Set[Position] = set()
|
||||
ans = 0
|
||||
radius = 1
|
||||
|
||||
while True:
|
||||
|
||||
def is_r_away(pos: Position) -> bool:
|
||||
return max(abs(pos.x - x), abs(pos.y - y)) == radius
|
||||
|
||||
to_visit = list(filter(is_r_away, asteroids))
|
||||
radius += 1
|
||||
if len(to_visit) == 0:
|
||||
break
|
||||
for pos in to_visit:
|
||||
rel = (pos.x - x, pos.y - y)
|
||||
common = gcd(*rel)
|
||||
rel = Position(*(a // common for a in rel))
|
||||
if rel in seen:
|
||||
continue # Already have an asteroid on this path
|
||||
seen.add(rel)
|
||||
ans += 1
|
||||
|
||||
return ans
|
||||
|
||||
# We need to find the observatory's position as a prerequisite
|
||||
ans, orig = max((count_spotted(*pos), pos) for pos in asteroids)
|
||||
print(f"({orig.x}, {orig.y}): {ans}")
|
||||
|
||||
def to_rel(p: Position) -> Position:
|
||||
return Position(*(a - o for (a, o) in zip(p, orig)))
|
||||
|
||||
angle_dists = sorted(
|
||||
(pos_to_angle_dist(to_rel(p)), p) for p in asteroids if p != orig
|
||||
)
|
||||
grouped_angle_dists = [
|
||||
[val[1] for val in group]
|
||||
for __, group in groupby(angle_dists, key=lambda x: x[0][0])
|
||||
]
|
||||
|
||||
def find_n_th(n: int) -> Position:
|
||||
assert 0 < n < len(asteroids) # Sanity check
|
||||
while n >= len(grouped_angle_dists):
|
||||
for group in grouped_angle_dists:
|
||||
group.pop(0)
|
||||
n -= 1
|
||||
return grouped_angle_dists[n - 1][0]
|
||||
|
||||
x, y = find_n_th(200)
|
||||
print(x * 100 + y)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
31
2019/d10/ex2/input
Normal file
31
2019/d10/ex2/input
Normal file
|
@ -0,0 +1,31 @@
|
|||
#...##.####.#.......#.##..##.#.
|
||||
#.##.#..#..#...##..##.##.#.....
|
||||
#..#####.#......#..#....#.###.#
|
||||
...#.#.#...#..#.....#..#..#.#..
|
||||
.#.....##..#...#..#.#...##.....
|
||||
##.....#..........##..#......##
|
||||
.##..##.#.#....##..##.......#..
|
||||
#.##.##....###..#...##...##....
|
||||
##.#.#............##..#...##..#
|
||||
###..##.###.....#.##...####....
|
||||
...##..#...##...##..#.#..#...#.
|
||||
..#.#.##.#.#.#####.#....####.#.
|
||||
#......###.##....#...#...#...##
|
||||
.....#...#.#.#.#....#...#......
|
||||
#..#.#.#..#....#..#...#..#..##.
|
||||
#.....#..##.....#...###..#..#.#
|
||||
.....####.#..#...##..#..#..#..#
|
||||
..#.....#.#........#.#.##..####
|
||||
.#.....##..#.##.....#...###....
|
||||
###.###....#..#..#.....#####...
|
||||
#..##.##..##.#.#....#.#......#.
|
||||
.#....#.##..#.#.#.......##.....
|
||||
##.##...#...#....###.#....#....
|
||||
.....#.######.#.#..#..#.#.....#
|
||||
.#..#.##.#....#.##..#.#...##..#
|
||||
.##.###..#..#..#.###...#####.#.
|
||||
#...#...........#.....#.......#
|
||||
#....##.#.#..##...#..####...#..
|
||||
#.####......#####.....#.##..#..
|
||||
.#...#....#...##..##.#.#......#
|
||||
#..###.....##.#.......#.##...##
|
243
2019/d11/ex1/ex1.py
Executable file
243
2019/d11/ex1/ex1.py
Executable file
|
@ -0,0 +1,243 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import Dict, List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
class Position(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
# Up, Right, Down, Left offsets
|
||||
offsets = [Position(1, 0), Position(0, 1), Position(-1, 0), Position(0, -1)]
|
||||
|
||||
|
||||
class Color(IntEnum):
|
||||
BLACK = 0
|
||||
WHITE = 1
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
painter = Computer(memory)
|
||||
pos = Position(0, 0)
|
||||
orientation = 0
|
||||
painted: Dict[Position, Color] = {}
|
||||
|
||||
has_painted = False
|
||||
while not painter.is_halted:
|
||||
try:
|
||||
painter.run()
|
||||
except InputInterrupt:
|
||||
painter.input_list.append(int(painted.get(pos, Color.BLACK)))
|
||||
except OutputInterrupt:
|
||||
if has_painted:
|
||||
orientation += 1 if painter.output_list.pop(0) == 1 else -1
|
||||
if orientation < 0:
|
||||
orientation += len(offsets)
|
||||
else:
|
||||
orientation = orientation % len(offsets)
|
||||
offset = offsets[orientation]
|
||||
pos = Position(pos.x + offset.x, pos.y + offset.y)
|
||||
else:
|
||||
painted[pos] = Color(painter.output_list.pop(0))
|
||||
has_painted = not has_painted
|
||||
|
||||
print(len(painted))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d11/ex1/input
Normal file
1
2019/d11/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,8,1005,8,330,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,29,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,101,0,8,51,1,1103,2,10,1006,0,94,1006,0,11,1,1106,13,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,87,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,109,2,1105,5,10,2,103,16,10,1,1103,12,10,2,105,2,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1001,8,0,146,1006,0,49,2,1,12,10,2,1006,6,10,1,1101,4,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,1001,8,0,183,1,6,9,10,1006,0,32,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,213,2,1101,9,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,239,1006,0,47,1006,0,4,2,6,0,10,1006,0,58,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,102,1,8,274,2,1005,14,10,1006,0,17,1,104,20,10,1006,0,28,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,309,101,1,9,9,1007,9,928,10,1005,10,15,99,109,652,104,0,104,1,21101,0,937263411860,1,21102,347,1,0,1105,1,451,21101,932440724376,0,1,21102,1,358,0,1105,1,451,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,0,29015167015,1,21101,0,405,0,1106,0,451,21102,1,3422723163,1,21101,0,416,0,1106,0,451,3,10,104,0,104,0,3,10,104,0,104,0,21101,0,868389376360,1,21101,0,439,0,1105,1,451,21102,825544712960,1,1,21102,1,450,0,1106,0,451,99,109,2,21201,-1,0,1,21101,0,40,2,21102,482,1,3,21102,1,472,0,1106,0,515,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,477,478,493,4,0,1001,477,1,477,108,4,477,10,1006,10,509,1101,0,0,477,109,-2,2106,0,0,0,109,4,2101,0,-1,514,1207,-3,0,10,1006,10,532,21102,1,0,-3,22101,0,-3,1,22102,1,-2,2,21102,1,1,3,21101,551,0,0,1106,0,556,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,579,2207,-4,-2,10,1006,10,579,22102,1,-4,-4,1106,0,647,21201,-4,0,1,21201,-3,-1,2,21202,-2,2,3,21102,1,598,0,1106,0,556,22101,0,1,-4,21101,1,0,-1,2207,-4,-2,10,1006,10,617,21102,0,1,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,639,21201,-1,0,1,21102,639,1,0,105,1,514,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0
|
253
2019/d11/ex2/ex2.py
Executable file
253
2019/d11/ex2/ex2.py
Executable file
|
@ -0,0 +1,253 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import Dict, List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
class Position(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
# Up, Right, Down, Left offsets
|
||||
offsets = [Position(1, 0), Position(0, 1), Position(-1, 0), Position(0, -1)]
|
||||
|
||||
|
||||
class Color(IntEnum):
|
||||
BLACK = 0
|
||||
WHITE = 1
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
painter = Computer(memory)
|
||||
pos = Position(0, 0)
|
||||
orientation = 0
|
||||
painted: Dict[Position, Color] = {pos: Color.WHITE}
|
||||
|
||||
has_painted = False
|
||||
while not painter.is_halted:
|
||||
try:
|
||||
painter.run()
|
||||
except InputInterrupt:
|
||||
painter.input_list.append(int(painted.get(pos, Color.BLACK)))
|
||||
except OutputInterrupt:
|
||||
if has_painted:
|
||||
orientation += 1 if painter.output_list.pop(0) == 1 else -1
|
||||
if orientation < 0:
|
||||
orientation += len(offsets)
|
||||
else:
|
||||
orientation = orientation % len(offsets)
|
||||
offset = offsets[orientation]
|
||||
pos = Position(pos.x + offset.x, pos.y + offset.y)
|
||||
else:
|
||||
painted[pos] = Color(painter.output_list.pop(0))
|
||||
has_painted = not has_painted
|
||||
|
||||
maxx, maxy = max(p.x for p in painted), max(p.y for p in painted)
|
||||
minx, miny = min(p.x for p in painted), min(p.y for p in painted)
|
||||
|
||||
ans: List[List[str]] = []
|
||||
for x in range(minx, maxx + 1):
|
||||
ans.append([])
|
||||
for y in range(miny, maxy + 1):
|
||||
color = painted.get(Position(x, y), Color.BLACK)
|
||||
ans[-1].append("█" if color == Color.WHITE else " ")
|
||||
lines = ["".join(l) for l in ans]
|
||||
print("\n".join(reversed(lines))) # Seems like my coordinates are reversed
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d11/ex2/input
Normal file
1
2019/d11/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,8,1005,8,330,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,102,1,8,29,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,101,0,8,51,1,1103,2,10,1006,0,94,1006,0,11,1,1106,13,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,87,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,109,2,1105,5,10,2,103,16,10,1,1103,12,10,2,105,2,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1001,8,0,146,1006,0,49,2,1,12,10,2,1006,6,10,1,1101,4,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,1001,8,0,183,1,6,9,10,1006,0,32,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,213,2,1101,9,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,239,1006,0,47,1006,0,4,2,6,0,10,1006,0,58,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,102,1,8,274,2,1005,14,10,1006,0,17,1,104,20,10,1006,0,28,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,309,101,1,9,9,1007,9,928,10,1005,10,15,99,109,652,104,0,104,1,21101,0,937263411860,1,21102,347,1,0,1105,1,451,21101,932440724376,0,1,21102,1,358,0,1105,1,451,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,0,29015167015,1,21101,0,405,0,1106,0,451,21102,1,3422723163,1,21101,0,416,0,1106,0,451,3,10,104,0,104,0,3,10,104,0,104,0,21101,0,868389376360,1,21101,0,439,0,1105,1,451,21102,825544712960,1,1,21102,1,450,0,1106,0,451,99,109,2,21201,-1,0,1,21101,0,40,2,21102,482,1,3,21102,1,472,0,1106,0,515,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,477,478,493,4,0,1001,477,1,477,108,4,477,10,1006,10,509,1101,0,0,477,109,-2,2106,0,0,0,109,4,2101,0,-1,514,1207,-3,0,10,1006,10,532,21102,1,0,-3,22101,0,-3,1,22102,1,-2,2,21102,1,1,3,21101,551,0,0,1106,0,556,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,579,2207,-4,-2,10,1006,10,579,22102,1,-4,-4,1106,0,647,21201,-4,0,1,21201,-3,-1,2,21202,-2,2,3,21102,1,598,0,1106,0,556,22101,0,1,-4,21101,1,0,-1,2207,-4,-2,10,1006,10,617,21102,0,1,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,639,21201,-1,0,1,21102,639,1,0,105,1,514,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0
|
50
2019/d12/ex1/ex1.py
Executable file
50
2019/d12/ex1/ex1.py
Executable file
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Position:
|
||||
x: int
|
||||
y: int
|
||||
z: int
|
||||
|
||||
|
||||
def line_to_pos(l: str) -> Position:
|
||||
"<x=4, y=1, z=1>"
|
||||
regex = r"<x=(?P<x>[^,]*), y=(?P<y>[^,]*), z=(?P<z>[^,]*)>"
|
||||
match = re.search(regex, l)
|
||||
assert match is not None # Sanity check
|
||||
return Position(*(int(match.group(g)) for g in ("x", "y", "z")))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
asteroids = [line_to_pos(line) for line in sys.stdin.readlines()]
|
||||
velocities = [Position(0, 0, 0) for __ in asteroids]
|
||||
|
||||
for __ in range(1000):
|
||||
for orig, v in zip(asteroids, velocities):
|
||||
for other in asteroids:
|
||||
if orig.x != other.x:
|
||||
v.x += 1 if orig.x < other.x else -1
|
||||
if orig.y != other.y:
|
||||
v.y += 1 if orig.y < other.y else -1
|
||||
if orig.z != other.z:
|
||||
v.z += 1 if orig.z < other.z else -1
|
||||
|
||||
for asteroid, v in zip(asteroids, velocities):
|
||||
asteroid.x += v.x
|
||||
asteroid.y += v.y
|
||||
asteroid.z += v.z
|
||||
|
||||
pot = (abs(p.x) + abs(p.y) + abs(p.z) for p in asteroids)
|
||||
kin = (abs(v.x) + abs(v.y) + abs(v.z) for v in velocities)
|
||||
|
||||
print(sum(p * k for p, k in zip(pot, kin)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
4
2019/d12/ex1/input
Normal file
4
2019/d12/ex1/input
Normal file
|
@ -0,0 +1,4 @@
|
|||
<x=4, y=1, z=1>
|
||||
<x=11, y=-18, z=-1>
|
||||
<x=-2, y=-10, z=-4>
|
||||
<x=-7, y=-2, z=14>
|
77
2019/d12/ex2/ex2.py
Executable file
77
2019/d12/ex2/ex2.py
Executable file
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
from math import gcd
|
||||
from typing import List
|
||||
|
||||
|
||||
@dataclass
|
||||
class Position:
|
||||
x: int
|
||||
y: int
|
||||
z: int
|
||||
|
||||
|
||||
def line_to_pos(l: str) -> Position:
|
||||
"<x=4, y=1, z=1>"
|
||||
regex = r"<x=(?P<x>[^,]*), y=(?P<y>[^,]*), z=(?P<z>[^,]*)>"
|
||||
match = re.search(regex, l)
|
||||
assert match is not None # Sanity check
|
||||
return Position(*(int(match.group(g)) for g in ("x", "y", "z")))
|
||||
|
||||
|
||||
def lcm(a: int, b: int, c: int) -> int:
|
||||
def lcm_2(a: int, b: int) -> int:
|
||||
return abs(a * b) // gcd(a, b)
|
||||
|
||||
return lcm_2(lcm_2(a, b), c)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
asteroids = [line_to_pos(line) for line in sys.stdin.readlines()]
|
||||
velocities = [Position(0, 0, 0) for __ in asteroids]
|
||||
|
||||
cycles: List[int] = []
|
||||
for attr in ("x", "y", "z"):
|
||||
all_prev_pos = [deepcopy(asteroids)]
|
||||
all_prev_vel = [deepcopy(velocities)]
|
||||
i = 0
|
||||
|
||||
found = False
|
||||
while not found:
|
||||
i += 1
|
||||
for orig, v in zip(asteroids, velocities):
|
||||
for other in asteroids:
|
||||
if orig.x != other.x:
|
||||
v.x += 1 if orig.x < other.x else -1
|
||||
if orig.y != other.y:
|
||||
v.y += 1 if orig.y < other.y else -1
|
||||
if orig.z != other.z:
|
||||
v.z += 1 if orig.z < other.z else -1
|
||||
|
||||
for asteroid, v in zip(asteroids, velocities):
|
||||
asteroid.x += v.x
|
||||
asteroid.y += v.y
|
||||
asteroid.z += v.z
|
||||
|
||||
for old_pos, old_vel in zip(all_prev_pos, all_prev_vel):
|
||||
if all(
|
||||
n.__getattribute__(attr) == o.__getattribute__(attr)
|
||||
for n, o in zip(asteroids, old_pos)
|
||||
) and all(
|
||||
n.__getattribute__(attr) == o.__getattribute__(attr)
|
||||
for n, o in zip(velocities, old_vel)
|
||||
):
|
||||
found = True
|
||||
|
||||
cycles.append(i)
|
||||
|
||||
print(lcm(*cycles))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
4
2019/d12/ex2/input
Normal file
4
2019/d12/ex2/input
Normal file
|
@ -0,0 +1,4 @@
|
|||
<x=4, y=1, z=1>
|
||||
<x=11, y=-18, z=-1>
|
||||
<x=-2, y=-10, z=-4>
|
||||
<x=-7, y=-2, z=14>
|
213
2019/d13/ex1/ex1.py
Executable file
213
2019/d13/ex1/ex1.py
Executable file
|
@ -0,0 +1,213 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import Iterable, List, NamedTuple, Tuple, TypeVar
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
game = Computer(memory)
|
||||
game.run_no_output_interrupt()
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
def grouped(l: Iterable[T], n: int) -> Iterable[Tuple[T, ...]]:
|
||||
return zip(*[iter(l)] * n)
|
||||
|
||||
print(sum(1 for __, __, tile in grouped(game.output_list, 3) if tile == 2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d13/ex1/input
Normal file
1
2019/d13/ex1/input
Normal file
File diff suppressed because one or more lines are too long
249
2019/d13/ex2/ex2.py
Executable file
249
2019/d13/ex2/ex2.py
Executable file
|
@ -0,0 +1,249 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import Iterable, List, NamedTuple, Tuple, TypeVar
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
class Tile(IntEnum):
|
||||
EMPTY = 0
|
||||
WALL = 1
|
||||
BLOCK = 2
|
||||
PADDLE = 3
|
||||
BALL = 4
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
memory[0] = 2 # Play for free
|
||||
game = Computer(memory)
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
def grouped(l: Iterable[T], n: int) -> Iterable[Tuple[T, ...]]:
|
||||
return zip(*[iter(l)] * n)
|
||||
|
||||
paddle_pos = None
|
||||
ball_pos = None
|
||||
score = None
|
||||
output_num = 0
|
||||
while not game.is_halted:
|
||||
try:
|
||||
game.run()
|
||||
except OutputInterrupt:
|
||||
output_num += 1
|
||||
if output_num < 3: # Not processable yet
|
||||
continue
|
||||
x, y = game.output_list[0:2]
|
||||
if x == -1 and y == 0: # Score display
|
||||
score = game.output_list[2]
|
||||
else:
|
||||
tile_type = Tile(game.output_list[2])
|
||||
if tile_type == Tile.PADDLE:
|
||||
paddle_pos = x
|
||||
elif tile_type == Tile.BALL:
|
||||
ball_pos = x
|
||||
game.output_list.clear() # Remove processed tiles
|
||||
output_num = 0 # Reset count for next output
|
||||
except InputInterrupt:
|
||||
assert paddle_pos is not None and ball_pos is not None # Sanity check
|
||||
offset = ball_pos - paddle_pos
|
||||
game.input_list.append(0 if offset == 0 else offset // abs(offset))
|
||||
|
||||
assert score is not None # Sanity check
|
||||
print(score)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d13/ex2/input
Normal file
1
2019/d13/ex2/input
Normal file
File diff suppressed because one or more lines are too long
89
2019/d14/ex1/ex1.py
Executable file
89
2019/d14/ex1/ex1.py
Executable file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from math import ceil
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
@dataclass
|
||||
class Ingredient:
|
||||
name: str
|
||||
quantity: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReactionEquation:
|
||||
quantity: int
|
||||
inputs: List[Ingredient]
|
||||
|
||||
|
||||
Reactions = Dict[str, ReactionEquation]
|
||||
|
||||
|
||||
def solve_for(n: int, reactions: Reactions) -> int:
|
||||
ore_needed = 0
|
||||
wanted = [("FUEL", n)]
|
||||
excess: Dict[str, int] = {}
|
||||
|
||||
def provide_ingredient(name: str, wanted_quantity: int) -> None:
|
||||
nonlocal ore_needed
|
||||
nonlocal excess
|
||||
nonlocal wanted
|
||||
|
||||
if name == "ORE":
|
||||
ore_needed += wanted_quantity # There's no recipy for this one
|
||||
return
|
||||
|
||||
if name in excess:
|
||||
# Take from excess
|
||||
if excess[name] > wanted_quantity:
|
||||
excess[name] -= wanted_quantity
|
||||
return # Nothing left to do
|
||||
wanted_quantity -= excess[name]
|
||||
del excess[name] # Took everything
|
||||
|
||||
if wanted_quantity == 0: # In case we provided just enough by excess
|
||||
return
|
||||
|
||||
equation = reactions[name]
|
||||
reaction_num = ceil(wanted_quantity / equation.quantity)
|
||||
|
||||
for ingredient in equation.inputs:
|
||||
needed_quantity = ingredient.quantity * reaction_num
|
||||
provide_ingredient(ingredient.name, needed_quantity)
|
||||
|
||||
produced_quantity = equation.quantity * reaction_num
|
||||
excess_quantity = produced_quantity - wanted_quantity
|
||||
if excess_quantity > 0:
|
||||
if name in excess:
|
||||
excess[name] += excess_quantity
|
||||
else:
|
||||
excess[name] = excess_quantity
|
||||
|
||||
while len(wanted) != 0:
|
||||
provide_ingredient(*(wanted.pop()))
|
||||
|
||||
return ore_needed
|
||||
|
||||
|
||||
def main() -> None:
|
||||
reactions: Reactions = {}
|
||||
|
||||
def parse_react(l: str) -> None:
|
||||
def parse_ingredient(i: str) -> Ingredient:
|
||||
quantity, name = i.strip().split(" ")
|
||||
return Ingredient(name, int(quantity))
|
||||
|
||||
input_list, output_str = l.split("=>")
|
||||
inputs = [i for i in map(parse_ingredient, input_list.split(", "))]
|
||||
output = parse_ingredient(output_str)
|
||||
reactions[output.name] = ReactionEquation(output.quantity, inputs)
|
||||
|
||||
for line in sys.stdin.readlines():
|
||||
parse_react(line)
|
||||
print(solve_for(1, reactions))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
59
2019/d14/ex1/input
Normal file
59
2019/d14/ex1/input
Normal file
|
@ -0,0 +1,59 @@
|
|||
10 LSZLT, 29 XQJK => 4 BMRQJ
|
||||
22 HCKS => 1 GQKCZ
|
||||
1 HCKS, 8 WZWRV, 18 HVZR => 7 BGFR
|
||||
1 LSZLT, 1 WRKJ, 3 LJFP, 3 RNLPB, 1 NZGK, 3 LDSV, 5 RJDN, 8 HGFGC => 3 QZTXD
|
||||
1 BRSGQ, 1 XGLF, 1 ZHSK, 20 LSZLT, 16 WFCPT, 3 KTWV, 1 QRJC => 4 XPKX
|
||||
1 DCLR, 6 RNLPB => 5 HCKS
|
||||
1 HFHFV => 3 SHLMF
|
||||
2 LTMZQ, 21 FGCXN => 6 QKFKV
|
||||
3 BGFR => 7 WRKJ
|
||||
3 KHSB => 2 XQJL
|
||||
3 SHLMF => 2 LPLG
|
||||
12 SVHWT, 20 BXPSZ => 9 NBMF
|
||||
2 FGCXN, 32 DCSVN => 8 TBDWZ
|
||||
1 KHSB, 3 HGFGC => 6 WZWRV
|
||||
27 WFCPT, 4 KTWV, 14 BRSGQ, 1 MFNK, 1 WRKJ, 2 NZGK, 24 FBFLK => 5 TRLCK
|
||||
2 SVHWT => 3 QRJC
|
||||
1 MNVR, 1 FKBMW => 2 FGCXN
|
||||
4 GJXW => 9 JXFS
|
||||
3 XQJK => 5 WNJM
|
||||
1 WZVWZ, 1 XQJL => 9 SHKJV
|
||||
2 DCSVN => 4 HDVC
|
||||
2 GJXW => 2 RNLPB
|
||||
1 QKFKV, 1 PBRWB => 5 WTZQ
|
||||
14 QKFKV => 6 RDFTD
|
||||
166 ORE => 1 QDSXV
|
||||
2 DCSVN => 5 BXPSZ
|
||||
113 ORE => 6 LTMZQ
|
||||
13 MNVR => 7 RJDN
|
||||
2 NZGK, 9 XQJK, 18 WRKJ => 9 KTWV
|
||||
1 NZGK => 8 XQJK
|
||||
6 RZCGN, 6 HDVC, 1 DLKR => 9 DSLXW
|
||||
18 HVZR => 8 LJFP
|
||||
7 XQJL => 1 NPDS
|
||||
15 DLKR, 1 DSLXW, 26 MJFVP => 3 FBFLK
|
||||
125 ORE => 9 MNVR
|
||||
3 RJDN => 4 HFHFV
|
||||
1 TBDWZ, 1 DCLR => 2 HVZR
|
||||
2 SHKJV => 5 GJXW
|
||||
7 LTMZQ, 1 QDSXV, 1 FKBMW => 3 DCSVN
|
||||
9 LPLG, 11 JXFS => 3 BRSGQ
|
||||
5 JXFS, 1 ZHSK, 25 XGLF => 4 MFNK
|
||||
5 PBRWB => 2 SVHWT
|
||||
15 SHKJV => 5 XGLF
|
||||
1 XQJL, 2 NPDS => 4 DLKR
|
||||
39 JXFS => 5 KSHF
|
||||
6 GJXW, 1 FBFLK => 7 HGFGC
|
||||
3 JXFS => 1 LSZLT
|
||||
3 NBMF, 1 BMRQJ => 2 LDSV
|
||||
1 JXFS, 25 GJXW, 10 HGFGC => 4 NZGK
|
||||
8 QZTXD, 26 KSHF, 60 WNJM, 6 GJXW, 9 TRLCK, 20 XPKX, 21 FGCXN, 57 GQKCZ, 6 WRKJ => 1 FUEL
|
||||
4 SVHWT, 1 RZCGN => 3 ZHSK
|
||||
1 BXPSZ => 7 DCLR
|
||||
8 RDFTD, 1 SHKJV, 1 HFHFV => 6 MJFVP
|
||||
1 LTMZQ => 9 KHSB
|
||||
5 WTZQ, 4 HGFGC, 4 HCKS => 9 WFCPT
|
||||
184 ORE => 4 FKBMW
|
||||
4 XQJL => 3 WZVWZ
|
||||
12 QDSXV => 9 RZCGN
|
||||
1 FBFLK, 7 HVZR => 9 PBRWB
|
106
2019/d14/ex2/ex2.py
Executable file
106
2019/d14/ex2/ex2.py
Executable file
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from math import ceil
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
@dataclass
|
||||
class Ingredient:
|
||||
name: str
|
||||
quantity: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReactionEquation:
|
||||
quantity: int
|
||||
inputs: List[Ingredient]
|
||||
|
||||
|
||||
Reactions = Dict[str, ReactionEquation]
|
||||
|
||||
|
||||
def solve_for(n: int, reactions: Reactions) -> int:
|
||||
ore_needed = 0
|
||||
wanted = [("FUEL", n)]
|
||||
excess: Dict[str, int] = {}
|
||||
|
||||
def provide_ingredient(name: str, wanted_quantity: int) -> None:
|
||||
nonlocal ore_needed
|
||||
nonlocal excess
|
||||
nonlocal wanted
|
||||
|
||||
if name == "ORE":
|
||||
ore_needed += wanted_quantity # There's no recipy for this one
|
||||
return
|
||||
|
||||
if name in excess:
|
||||
# Take from excess
|
||||
if excess[name] > wanted_quantity:
|
||||
excess[name] -= wanted_quantity
|
||||
return # Nothing left to do
|
||||
wanted_quantity -= excess[name]
|
||||
del excess[name] # Took everything
|
||||
|
||||
if wanted_quantity == 0: # In case we provided just enough by excess
|
||||
return
|
||||
|
||||
equation = reactions[name]
|
||||
reaction_num = ceil(wanted_quantity / equation.quantity)
|
||||
|
||||
for ingredient in equation.inputs:
|
||||
needed_quantity = ingredient.quantity * reaction_num
|
||||
provide_ingredient(ingredient.name, needed_quantity)
|
||||
|
||||
produced_quantity = equation.quantity * reaction_num
|
||||
excess_quantity = produced_quantity - wanted_quantity
|
||||
if excess_quantity > 0:
|
||||
if name in excess:
|
||||
excess[name] += excess_quantity
|
||||
else:
|
||||
excess[name] = excess_quantity
|
||||
|
||||
while len(wanted) != 0:
|
||||
provide_ingredient(*(wanted.pop()))
|
||||
|
||||
return ore_needed
|
||||
|
||||
|
||||
def main() -> None:
|
||||
reactions: Reactions = {}
|
||||
|
||||
def parse_react(l: str) -> None:
|
||||
def parse_ingredient(i: str) -> Ingredient:
|
||||
quantity, name = i.strip().split(" ")
|
||||
return Ingredient(name, int(quantity))
|
||||
|
||||
input_list, output_str = l.split("=>")
|
||||
inputs = [i for i in map(parse_ingredient, input_list.split(", "))]
|
||||
output = parse_ingredient(output_str)
|
||||
reactions[output.name] = ReactionEquation(output.quantity, inputs)
|
||||
|
||||
for line in sys.stdin.readlines():
|
||||
parse_react(line)
|
||||
|
||||
for_one = solve_for(1, reactions)
|
||||
target = 1000000000000
|
||||
# Educated guesses about minimum and maximum fuel needed to use 'target' ORE
|
||||
min_fuel_needed = target // for_one
|
||||
max_fuel_needed = 2 * min_fuel_needed
|
||||
while min_fuel_needed < max_fuel_needed:
|
||||
# We already know that minimum value is valid, offset it by one for the search
|
||||
mid = ceil((min_fuel_needed + max_fuel_needed) / 2)
|
||||
mid_res = solve_for(mid, reactions)
|
||||
if mid_res > target:
|
||||
# Exclude the maximum that was already searched
|
||||
max_fuel_needed = mid - 1
|
||||
else:
|
||||
# Keep the valid minimum value
|
||||
min_fuel_needed = mid
|
||||
|
||||
print(max_fuel_needed)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
59
2019/d14/ex2/input
Normal file
59
2019/d14/ex2/input
Normal file
|
@ -0,0 +1,59 @@
|
|||
10 LSZLT, 29 XQJK => 4 BMRQJ
|
||||
22 HCKS => 1 GQKCZ
|
||||
1 HCKS, 8 WZWRV, 18 HVZR => 7 BGFR
|
||||
1 LSZLT, 1 WRKJ, 3 LJFP, 3 RNLPB, 1 NZGK, 3 LDSV, 5 RJDN, 8 HGFGC => 3 QZTXD
|
||||
1 BRSGQ, 1 XGLF, 1 ZHSK, 20 LSZLT, 16 WFCPT, 3 KTWV, 1 QRJC => 4 XPKX
|
||||
1 DCLR, 6 RNLPB => 5 HCKS
|
||||
1 HFHFV => 3 SHLMF
|
||||
2 LTMZQ, 21 FGCXN => 6 QKFKV
|
||||
3 BGFR => 7 WRKJ
|
||||
3 KHSB => 2 XQJL
|
||||
3 SHLMF => 2 LPLG
|
||||
12 SVHWT, 20 BXPSZ => 9 NBMF
|
||||
2 FGCXN, 32 DCSVN => 8 TBDWZ
|
||||
1 KHSB, 3 HGFGC => 6 WZWRV
|
||||
27 WFCPT, 4 KTWV, 14 BRSGQ, 1 MFNK, 1 WRKJ, 2 NZGK, 24 FBFLK => 5 TRLCK
|
||||
2 SVHWT => 3 QRJC
|
||||
1 MNVR, 1 FKBMW => 2 FGCXN
|
||||
4 GJXW => 9 JXFS
|
||||
3 XQJK => 5 WNJM
|
||||
1 WZVWZ, 1 XQJL => 9 SHKJV
|
||||
2 DCSVN => 4 HDVC
|
||||
2 GJXW => 2 RNLPB
|
||||
1 QKFKV, 1 PBRWB => 5 WTZQ
|
||||
14 QKFKV => 6 RDFTD
|
||||
166 ORE => 1 QDSXV
|
||||
2 DCSVN => 5 BXPSZ
|
||||
113 ORE => 6 LTMZQ
|
||||
13 MNVR => 7 RJDN
|
||||
2 NZGK, 9 XQJK, 18 WRKJ => 9 KTWV
|
||||
1 NZGK => 8 XQJK
|
||||
6 RZCGN, 6 HDVC, 1 DLKR => 9 DSLXW
|
||||
18 HVZR => 8 LJFP
|
||||
7 XQJL => 1 NPDS
|
||||
15 DLKR, 1 DSLXW, 26 MJFVP => 3 FBFLK
|
||||
125 ORE => 9 MNVR
|
||||
3 RJDN => 4 HFHFV
|
||||
1 TBDWZ, 1 DCLR => 2 HVZR
|
||||
2 SHKJV => 5 GJXW
|
||||
7 LTMZQ, 1 QDSXV, 1 FKBMW => 3 DCSVN
|
||||
9 LPLG, 11 JXFS => 3 BRSGQ
|
||||
5 JXFS, 1 ZHSK, 25 XGLF => 4 MFNK
|
||||
5 PBRWB => 2 SVHWT
|
||||
15 SHKJV => 5 XGLF
|
||||
1 XQJL, 2 NPDS => 4 DLKR
|
||||
39 JXFS => 5 KSHF
|
||||
6 GJXW, 1 FBFLK => 7 HGFGC
|
||||
3 JXFS => 1 LSZLT
|
||||
3 NBMF, 1 BMRQJ => 2 LDSV
|
||||
1 JXFS, 25 GJXW, 10 HGFGC => 4 NZGK
|
||||
8 QZTXD, 26 KSHF, 60 WNJM, 6 GJXW, 9 TRLCK, 20 XPKX, 21 FGCXN, 57 GQKCZ, 6 WRKJ => 1 FUEL
|
||||
4 SVHWT, 1 RZCGN => 3 ZHSK
|
||||
1 BXPSZ => 7 DCLR
|
||||
8 RDFTD, 1 SHKJV, 1 HFHFV => 6 MJFVP
|
||||
1 LTMZQ => 9 KHSB
|
||||
5 WTZQ, 4 HGFGC, 4 HCKS => 9 WFCPT
|
||||
184 ORE => 4 FKBMW
|
||||
4 XQJL => 3 WZVWZ
|
||||
12 QDSXV => 9 RZCGN
|
||||
1 FBFLK, 7 HVZR => 9 PBRWB
|
315
2019/d15/ex1/ex1.py
Executable file
315
2019/d15/ex1/ex1.py
Executable file
|
@ -0,0 +1,315 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import heapq
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntEnum, auto
|
||||
from typing import List, NamedTuple, Optional, Set
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
class Movement(IntEnum):
|
||||
NORTH = 1
|
||||
SOUTH = 2
|
||||
WEST = 3
|
||||
EAST = 4
|
||||
|
||||
|
||||
class StatusCode(IntEnum):
|
||||
BLOCKED = 0
|
||||
SUCCESS = 1
|
||||
ON_TANK = 2
|
||||
|
||||
|
||||
class BlockType(Enum):
|
||||
WALL = auto()
|
||||
HALLWAY = auto()
|
||||
OXYGEN_TANK = auto()
|
||||
|
||||
|
||||
class Coordinate(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class GraphNode:
|
||||
memory_state: Optional[List[int]] # Only walls have no need for the memory state
|
||||
block_type: BlockType
|
||||
parent: Optional[Coordinate] # Only the root of the exploration has no parent
|
||||
|
||||
|
||||
def coord_plus_dir(c: Coordinate, d: Movement) -> Coordinate:
|
||||
offset = {
|
||||
Movement.NORTH: Coordinate(0, 1),
|
||||
Movement.SOUTH: Coordinate(0, -1),
|
||||
Movement.WEST: Coordinate(-1, 0),
|
||||
Movement.EAST: Coordinate(1, 0),
|
||||
}
|
||||
return Coordinate(*(a + b for (a, b) in zip(c, offset[d])))
|
||||
|
||||
|
||||
def move_to_opposite(d: Movement) -> Movement:
|
||||
if d == Movement.NORTH:
|
||||
return Movement.SOUTH
|
||||
elif d == Movement.SOUTH:
|
||||
return Movement.NORTH
|
||||
elif d == Movement.WEST:
|
||||
return Movement.EAST
|
||||
else:
|
||||
return Movement.WEST
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
droid = Computer(memory)
|
||||
block_map = {Coordinate(0, 0): BlockType.HALLWAY}
|
||||
|
||||
def dfs(p: Coordinate, direction: Movement) -> None:
|
||||
end_coord = coord_plus_dir(p, direction)
|
||||
if end_coord in block_map:
|
||||
return # Nothing to do
|
||||
|
||||
droid.input_list.append(int(direction))
|
||||
try:
|
||||
droid.run()
|
||||
except OutputInterrupt:
|
||||
status = StatusCode(droid.output_list.pop(0))
|
||||
if status == StatusCode.BLOCKED:
|
||||
block_map[end_coord] = BlockType.WALL
|
||||
return # Don't need to backtrack
|
||||
block_map[end_coord] = (
|
||||
BlockType.OXYGEN_TANK
|
||||
if status == StatusCode.ON_TANK
|
||||
else BlockType.HALLWAY
|
||||
)
|
||||
for d in Movement:
|
||||
dfs(end_coord, d)
|
||||
droid.input_list.append(int(move_to_opposite(direction)))
|
||||
try:
|
||||
droid.run()
|
||||
except OutputInterrupt:
|
||||
droid.output_list.pop(0)
|
||||
|
||||
for direction in Movement:
|
||||
dfs(Coordinate(0, 0), direction)
|
||||
assert len(droid.input_list) == 0 and len(droid.output_list) == 0 # Sanity check
|
||||
|
||||
block_map = {p: t for p, t in block_map.items() if t != BlockType.WALL}
|
||||
oxygen_gen = (
|
||||
pos for pos, block in block_map.items() if block == BlockType.OXYGEN_TANK
|
||||
)
|
||||
oxygen_pos = next(oxygen_gen)
|
||||
assert next(oxygen_gen, None) is None # Sanity check
|
||||
|
||||
seen: Set[Coordinate] = set()
|
||||
to_visit = [(0, oxygen_pos)]
|
||||
|
||||
def find_shortest() -> int:
|
||||
while True:
|
||||
dist, pos = heapq.heappop(to_visit)
|
||||
if pos == Coordinate(0, 0):
|
||||
return dist
|
||||
if pos in seen:
|
||||
continue
|
||||
if pos not in block_map:
|
||||
continue
|
||||
seen.add(pos)
|
||||
for d in Movement:
|
||||
new_pos = coord_plus_dir(pos, d)
|
||||
heapq.heappush(to_visit, (dist + 1, new_pos))
|
||||
|
||||
print(find_shortest())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d15/ex1/input
Normal file
1
2019/d15/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,101,0,1034,1039,1001,1036,0,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,1002,1034,1,1039,1001,1036,0,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1106,0,124,1001,1034,-1,1039,1008,1036,0,1041,101,0,1035,1040,1001,1038,0,1043,1002,1037,1,1042,1105,1,124,1001,1034,1,1039,1008,1036,0,1041,1002,1035,1,1040,101,0,1038,1043,1001,1037,0,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,33,1032,1006,1032,165,1008,1040,33,1032,1006,1032,165,1101,2,0,1044,1106,0,224,2,1041,1043,1032,1006,1032,179,1101,0,1,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,68,1044,1106,0,224,1101,0,0,1044,1105,1,224,1006,1044,247,1002,1039,1,1034,102,1,1040,1035,1001,1041,0,1036,1002,1043,1,1038,1001,1042,0,1037,4,1044,1105,1,0,67,55,37,80,63,12,30,78,95,7,20,63,83,54,86,58,97,11,84,24,11,77,42,78,22,54,89,52,44,28,93,30,81,60,58,78,87,60,54,59,78,96,17,82,74,85,66,41,89,96,54,40,82,17,22,89,65,96,71,55,81,34,90,11,85,44,58,83,79,93,30,76,62,80,16,73,20,43,40,73,69,39,39,15,93,39,99,8,74,33,97,84,24,50,91,5,71,34,81,76,22,98,50,93,80,36,76,16,76,43,19,71,63,41,21,99,40,75,55,27,82,80,83,54,66,75,61,86,14,10,74,38,92,31,49,97,20,98,15,71,59,96,53,86,35,60,6,73,71,59,79,10,84,69,23,82,14,7,76,99,45,19,96,92,14,63,55,71,46,71,34,74,73,22,95,89,10,24,59,69,17,42,96,12,92,94,66,1,69,91,36,90,94,13,17,33,46,20,89,90,24,12,94,92,83,42,73,43,70,83,55,17,92,66,23,74,99,1,92,82,54,71,96,1,22,78,74,94,66,78,40,87,13,87,73,74,89,26,26,70,42,79,3,9,84,72,55,98,56,27,73,74,57,85,66,76,88,55,58,30,97,40,71,76,6,10,55,71,43,36,99,46,59,34,37,84,61,85,90,62,98,18,39,46,84,23,70,93,9,71,5,71,94,5,59,40,71,26,90,12,45,57,74,5,92,86,32,99,20,92,82,22,44,88,29,41,89,7,86,81,72,76,9,94,94,3,8,94,71,12,93,6,82,91,91,20,86,86,38,85,95,42,86,85,19,57,90,17,85,6,84,17,81,42,77,63,26,59,9,24,85,22,31,35,93,64,90,4,16,91,67,83,23,43,63,75,3,88,93,52,14,84,85,36,95,12,51,79,54,1,16,72,1,76,79,88,63,95,77,6,91,86,23,92,54,91,51,82,45,14,98,89,74,47,52,82,80,65,74,44,58,90,14,98,42,91,6,50,88,29,81,96,25,1,97,62,62,73,61,48,82,76,93,98,49,14,74,6,97,30,47,73,77,8,89,10,17,65,21,74,95,43,83,89,72,96,27,59,20,58,80,10,70,86,42,92,26,50,98,85,3,62,20,93,86,78,19,78,91,23,90,37,71,66,97,97,95,86,40,46,79,70,37,14,98,51,91,81,4,9,77,93,19,53,70,87,40,11,95,25,93,90,17,98,39,76,92,55,57,93,39,76,13,99,58,92,26,88,80,65,34,71,62,72,17,64,38,97,85,32,4,88,69,82,51,63,61,71,77,33,90,59,74,49,76,8,76,93,55,36,71,84,7,67,47,3,85,98,9,99,32,8,79,18,28,55,77,10,30,79,77,4,1,99,82,66,90,41,64,22,82,33,20,87,24,29,80,53,72,27,17,85,84,70,16,94,11,81,92,48,85,61,47,83,21,45,92,92,38,61,75,98,52,73,80,29,82,94,29,85,61,69,59,35,84,86,60,98,63,83,69,39,10,15,64,18,85,88,63,97,95,56,13,43,75,93,13,34,85,57,37,96,39,65,60,73,73,82,11,81,80,38,88,76,23,88,19,70,2,93,46,28,79,92,91,18,6,92,96,50,77,56,45,77,36,64,83,91,64,75,48,72,71,17,69,40,82,7,6,92,70,25,23,72,9,23,84,16,17,75,76,70,60,61,99,86,21,27,85,63,80,81,55,87,93,97,53,78,53,97,14,97,49,85,65,91,72,72,5,93,34,81,10,85,86,81,19,87,61,84,11,99,96,94,8,78,13,84,9,70,0,0,21,21,1,10,1,0,0,0,0,0,0
|
318
2019/d15/ex2/ex2.py
Executable file
318
2019/d15/ex2/ex2.py
Executable file
|
@ -0,0 +1,318 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import heapq
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntEnum, auto
|
||||
from typing import List, NamedTuple, Optional, Set
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
class Movement(IntEnum):
|
||||
NORTH = 1
|
||||
SOUTH = 2
|
||||
WEST = 3
|
||||
EAST = 4
|
||||
|
||||
|
||||
class StatusCode(IntEnum):
|
||||
BLOCKED = 0
|
||||
SUCCESS = 1
|
||||
ON_TANK = 2
|
||||
|
||||
|
||||
class BlockType(Enum):
|
||||
WALL = auto()
|
||||
HALLWAY = auto()
|
||||
OXYGEN_TANK = auto()
|
||||
|
||||
|
||||
class Coordinate(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class GraphNode:
|
||||
memory_state: Optional[List[int]] # Only walls have no need for the memory state
|
||||
block_type: BlockType
|
||||
parent: Optional[Coordinate] # Only the root of the exploration has no parent
|
||||
|
||||
|
||||
def coord_plus_dir(c: Coordinate, d: Movement) -> Coordinate:
|
||||
offset = {
|
||||
Movement.NORTH: Coordinate(0, 1),
|
||||
Movement.SOUTH: Coordinate(0, -1),
|
||||
Movement.WEST: Coordinate(-1, 0),
|
||||
Movement.EAST: Coordinate(1, 0),
|
||||
}
|
||||
return Coordinate(*(a + b for (a, b) in zip(c, offset[d])))
|
||||
|
||||
|
||||
def move_to_opposite(d: Movement) -> Movement:
|
||||
if d == Movement.NORTH:
|
||||
return Movement.SOUTH
|
||||
elif d == Movement.SOUTH:
|
||||
return Movement.NORTH
|
||||
elif d == Movement.WEST:
|
||||
return Movement.EAST
|
||||
else:
|
||||
return Movement.WEST
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
droid = Computer(memory)
|
||||
block_map = {Coordinate(0, 0): BlockType.HALLWAY}
|
||||
|
||||
def dfs(p: Coordinate, direction: Movement) -> None:
|
||||
end_coord = coord_plus_dir(p, direction)
|
||||
if end_coord in block_map:
|
||||
return # Nothing to do
|
||||
|
||||
droid.input_list.append(int(direction))
|
||||
try:
|
||||
droid.run()
|
||||
except OutputInterrupt:
|
||||
status = StatusCode(droid.output_list.pop(0))
|
||||
if status == StatusCode.BLOCKED:
|
||||
block_map[end_coord] = BlockType.WALL
|
||||
return # Don't need to backtrack
|
||||
block_map[end_coord] = (
|
||||
BlockType.OXYGEN_TANK
|
||||
if status == StatusCode.ON_TANK
|
||||
else BlockType.HALLWAY
|
||||
)
|
||||
for d in Movement:
|
||||
dfs(end_coord, d)
|
||||
droid.input_list.append(int(move_to_opposite(direction)))
|
||||
try:
|
||||
droid.run()
|
||||
except OutputInterrupt:
|
||||
droid.output_list.pop(0)
|
||||
|
||||
for direction in Movement:
|
||||
dfs(Coordinate(0, 0), direction)
|
||||
assert len(droid.input_list) == 0 and len(droid.output_list) == 0 # Sanity check
|
||||
|
||||
block_map = {p: t for p, t in block_map.items() if t != BlockType.WALL}
|
||||
oxygen_gen = (
|
||||
pos for pos, block in block_map.items() if block == BlockType.OXYGEN_TANK
|
||||
)
|
||||
oxygen_pos = next(oxygen_gen)
|
||||
assert next(oxygen_gen, None) is None # Sanity check
|
||||
|
||||
seen: Set[Coordinate] = set()
|
||||
to_visit = [(0, oxygen_pos)]
|
||||
|
||||
max_dist = 0
|
||||
|
||||
def fill_oxygen() -> None:
|
||||
nonlocal max_dist
|
||||
while len(to_visit) != 0:
|
||||
dist, pos = heapq.heappop(to_visit)
|
||||
if pos in seen:
|
||||
continue
|
||||
if pos not in block_map:
|
||||
continue
|
||||
seen.add(pos)
|
||||
max_dist = max(max_dist, dist)
|
||||
for d in Movement:
|
||||
new_pos = coord_plus_dir(pos, d)
|
||||
heapq.heappush(to_visit, (dist + 1, new_pos))
|
||||
|
||||
fill_oxygen()
|
||||
print(max_dist)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d15/ex2/input
Normal file
1
2019/d15/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,101,0,1034,1039,1001,1036,0,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,1002,1034,1,1039,1001,1036,0,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1106,0,124,1001,1034,-1,1039,1008,1036,0,1041,101,0,1035,1040,1001,1038,0,1043,1002,1037,1,1042,1105,1,124,1001,1034,1,1039,1008,1036,0,1041,1002,1035,1,1040,101,0,1038,1043,1001,1037,0,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,33,1032,1006,1032,165,1008,1040,33,1032,1006,1032,165,1101,2,0,1044,1106,0,224,2,1041,1043,1032,1006,1032,179,1101,0,1,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,68,1044,1106,0,224,1101,0,0,1044,1105,1,224,1006,1044,247,1002,1039,1,1034,102,1,1040,1035,1001,1041,0,1036,1002,1043,1,1038,1001,1042,0,1037,4,1044,1105,1,0,67,55,37,80,63,12,30,78,95,7,20,63,83,54,86,58,97,11,84,24,11,77,42,78,22,54,89,52,44,28,93,30,81,60,58,78,87,60,54,59,78,96,17,82,74,85,66,41,89,96,54,40,82,17,22,89,65,96,71,55,81,34,90,11,85,44,58,83,79,93,30,76,62,80,16,73,20,43,40,73,69,39,39,15,93,39,99,8,74,33,97,84,24,50,91,5,71,34,81,76,22,98,50,93,80,36,76,16,76,43,19,71,63,41,21,99,40,75,55,27,82,80,83,54,66,75,61,86,14,10,74,38,92,31,49,97,20,98,15,71,59,96,53,86,35,60,6,73,71,59,79,10,84,69,23,82,14,7,76,99,45,19,96,92,14,63,55,71,46,71,34,74,73,22,95,89,10,24,59,69,17,42,96,12,92,94,66,1,69,91,36,90,94,13,17,33,46,20,89,90,24,12,94,92,83,42,73,43,70,83,55,17,92,66,23,74,99,1,92,82,54,71,96,1,22,78,74,94,66,78,40,87,13,87,73,74,89,26,26,70,42,79,3,9,84,72,55,98,56,27,73,74,57,85,66,76,88,55,58,30,97,40,71,76,6,10,55,71,43,36,99,46,59,34,37,84,61,85,90,62,98,18,39,46,84,23,70,93,9,71,5,71,94,5,59,40,71,26,90,12,45,57,74,5,92,86,32,99,20,92,82,22,44,88,29,41,89,7,86,81,72,76,9,94,94,3,8,94,71,12,93,6,82,91,91,20,86,86,38,85,95,42,86,85,19,57,90,17,85,6,84,17,81,42,77,63,26,59,9,24,85,22,31,35,93,64,90,4,16,91,67,83,23,43,63,75,3,88,93,52,14,84,85,36,95,12,51,79,54,1,16,72,1,76,79,88,63,95,77,6,91,86,23,92,54,91,51,82,45,14,98,89,74,47,52,82,80,65,74,44,58,90,14,98,42,91,6,50,88,29,81,96,25,1,97,62,62,73,61,48,82,76,93,98,49,14,74,6,97,30,47,73,77,8,89,10,17,65,21,74,95,43,83,89,72,96,27,59,20,58,80,10,70,86,42,92,26,50,98,85,3,62,20,93,86,78,19,78,91,23,90,37,71,66,97,97,95,86,40,46,79,70,37,14,98,51,91,81,4,9,77,93,19,53,70,87,40,11,95,25,93,90,17,98,39,76,92,55,57,93,39,76,13,99,58,92,26,88,80,65,34,71,62,72,17,64,38,97,85,32,4,88,69,82,51,63,61,71,77,33,90,59,74,49,76,8,76,93,55,36,71,84,7,67,47,3,85,98,9,99,32,8,79,18,28,55,77,10,30,79,77,4,1,99,82,66,90,41,64,22,82,33,20,87,24,29,80,53,72,27,17,85,84,70,16,94,11,81,92,48,85,61,47,83,21,45,92,92,38,61,75,98,52,73,80,29,82,94,29,85,61,69,59,35,84,86,60,98,63,83,69,39,10,15,64,18,85,88,63,97,95,56,13,43,75,93,13,34,85,57,37,96,39,65,60,73,73,82,11,81,80,38,88,76,23,88,19,70,2,93,46,28,79,92,91,18,6,92,96,50,77,56,45,77,36,64,83,91,64,75,48,72,71,17,69,40,82,7,6,92,70,25,23,72,9,23,84,16,17,75,76,70,60,61,99,86,21,27,85,63,80,81,55,87,93,97,53,78,53,97,14,97,49,85,65,91,72,72,5,93,34,81,10,85,86,81,19,87,61,84,11,99,96,94,8,78,13,84,9,70,0,0,21,21,1,10,1,0,0,0,0,0,0
|
29
2019/d16/ex1/ex1.py
Executable file
29
2019/d16/ex1/ex1.py
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from functools import reduce
|
||||
from itertools import chain, cycle
|
||||
from typing import Iterable, List
|
||||
|
||||
|
||||
def sequencer(pattern: List[int], n: int) -> Iterable[int]:
|
||||
gen = cycle(list(chain(*([a] * n for a in pattern))))
|
||||
next(gen) # Skip the first one
|
||||
yield from gen
|
||||
|
||||
|
||||
def main() -> None:
|
||||
signal = [int(d) for d in sys.stdin.read().strip()]
|
||||
base_pattern = [0, 1, 0, -1]
|
||||
|
||||
for __ in range(100):
|
||||
signal = [
|
||||
abs(sum(a * b for a, b in zip(signal, sequencer(base_pattern, i + 1)))) % 10
|
||||
for i in range(len(signal))
|
||||
]
|
||||
|
||||
print(reduce(lambda a, b: a * 10 + b, signal[0:8]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d16/ex1/input
Normal file
1
2019/d16/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
59793513516782374825915243993822865203688298721919339628274587775705006728427921751430533510981343323758576985437451867752936052153192753660463974146842169169504066730474876587016668826124639010922391218906707376662919204980583671961374243713362170277231101686574078221791965458164785925384486127508173239563372833776841606271237694768938831709136453354321708319835083666223956618272981294631469954624760620412170069396383335680428214399523030064601263676270903213996956414287336234682903859823675958155009987384202594409175930384736760416642456784909043049471828143167853096088824339425988907292558707480725410676823614387254696304038713756368483311
|
27
2019/d16/ex2/ex2.py
Executable file
27
2019/d16/ex2/ex2.py
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from functools import reduce
|
||||
|
||||
|
||||
def main() -> None:
|
||||
rep = 10000
|
||||
signal = [int(d) for d in sys.stdin.read().strip()] * rep
|
||||
offset = reduce(lambda a, b: a * 10 + b, signal[0:7])
|
||||
|
||||
assert offset >= len(signal) / 2 # Sanity check
|
||||
# The trick is that the second half is only affected by itself (triangular matrix):
|
||||
# For i > len(signal) / 2, new_signal[i] = sum(signal, i, len(signal))
|
||||
# Therefore, we're only interested in numbers that start at the offset
|
||||
signal = signal[offset:] # Only take the end we need
|
||||
|
||||
for __ in range(100):
|
||||
for i in range(len(signal) - 1, 0, -1): # Do the sum from the end
|
||||
signal[i - 1] += signal[i]
|
||||
signal[i - 1] = signal[i - 1] % 10
|
||||
|
||||
print(reduce(lambda a, b: a * 10 + b, signal[:8]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d16/ex2/input
Normal file
1
2019/d16/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
59793513516782374825915243993822865203688298721919339628274587775705006728427921751430533510981343323758576985437451867752936052153192753660463974146842169169504066730474876587016668826124639010922391218906707376662919204980583671961374243713362170277231101686574078221791965458164785925384486127508173239563372833776841606271237694768938831709136453354321708319835083666223956618272981294631469954624760620412170069396383335680428214399523030064601263676270903213996956414287336234682903859823675958155009987384202594409175930384736760416642456784909043049471828143167853096088824339425988907292558707480725410676823614387254696304038713756368483311
|
223
2019/d17/ex1/ex1.py
Executable file
223
2019/d17/ex1/ex1.py
Executable file
|
@ -0,0 +1,223 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import sys
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
camera = Computer(memory)
|
||||
|
||||
camera.run_no_output_interrupt()
|
||||
|
||||
view = "".join(chr(c) for c in camera.output_list)
|
||||
mapped_view = [[c for c in line] for line in view.split("\n") if line != ""]
|
||||
|
||||
def is_intersection(x: int, y: int) -> bool:
|
||||
neighbors_and_point = ((x, y), (x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1))
|
||||
return all(mapped_view[a][b] not in (".", "X") for a, b in neighbors_and_point)
|
||||
|
||||
tot = 0
|
||||
for x in range(1, len(mapped_view) - 1):
|
||||
for y in range(1, len(mapped_view[0]) - 1): # No need to look at the borders
|
||||
if is_intersection(x, y):
|
||||
tot += x * y
|
||||
|
||||
print(tot)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d17/ex1/input
Normal file
1
2019/d17/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
1,330,331,332,109,2952,1101,1182,0,16,1101,1467,0,24,102,1,0,570,1006,570,36,1002,571,1,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,16,1,16,1008,16,1467,570,1006,570,14,21101,0,58,0,1105,1,786,1006,332,62,99,21102,1,333,1,21101,73,0,0,1106,0,579,1101,0,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,101,0,574,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21101,340,0,1,1105,1,177,21101,477,0,1,1106,0,177,21101,514,0,1,21101,0,176,0,1105,1,579,99,21102,1,184,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,101,0,572,1182,21101,375,0,1,21101,211,0,0,1106,0,579,21101,1182,11,1,21101,222,0,0,1105,1,979,21101,0,388,1,21102,233,1,0,1106,0,579,21101,1182,22,1,21101,0,244,0,1106,0,979,21101,401,0,1,21102,1,255,0,1106,0,579,21101,1182,33,1,21101,266,0,0,1105,1,979,21101,414,0,1,21102,1,277,0,1106,0,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21101,1182,0,1,21101,313,0,0,1105,1,622,1005,575,327,1101,0,1,575,21102,327,1,0,1106,0,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,20,14,0,109,4,2102,1,-3,586,21001,0,0,-1,22101,1,-3,-3,21102,1,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1105,1,597,109,-4,2105,1,0,109,5,2101,0,-4,629,21001,0,0,-2,22101,1,-4,-4,21101,0,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21002,0,1,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,702,0,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21101,0,731,0,1105,1,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21102,1,756,0,1105,1,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1105,1,622,21201,-3,1,-3,1106,0,640,109,-5,2106,0,0,109,7,1005,575,802,20102,1,576,-6,20101,0,577,-5,1106,0,814,21101,0,0,-1,21102,1,0,-5,21101,0,0,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,45,-3,22201,-6,-3,-3,22101,1467,-3,-3,1202,-3,1,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1106,0,924,1205,-2,873,21101,0,35,-4,1105,1,924,1201,-3,0,878,1008,0,1,570,1006,570,916,1001,374,1,374,1201,-3,0,895,1102,1,2,0,1201,-3,0,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,921,21001,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,45,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,33,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21101,973,0,0,1106,0,786,99,109,-7,2105,1,0,109,6,21101,0,0,-4,21102,1,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1106,0,1041,21102,-4,1,-2,1106,0,1041,21102,1,-5,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1202,-2,1,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,1201,-2,0,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21101,0,439,1,1105,1,1150,21102,477,1,1,1106,0,1150,21102,1,514,1,21102,1149,1,0,1106,0,579,99,21102,1157,1,0,1105,1,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,1202,-5,1,1176,2102,1,-4,0,109,-6,2105,1,0,10,11,34,1,9,1,34,1,9,1,7,9,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,9,1,13,3,1,26,1,9,1,3,1,3,1,20,11,5,1,1,9,18,1,5,1,3,1,5,1,1,1,1,1,3,1,1,1,18,1,5,1,3,1,5,1,1,1,1,1,3,1,1,1,18,1,5,1,3,1,5,1,1,1,1,1,3,1,1,1,18,1,5,1,1,9,1,1,1,1,3,9,12,1,5,1,3,1,7,1,1,1,5,1,5,1,10,9,3,1,1,9,5,1,5,1,10,1,1,1,9,1,1,1,5,1,7,1,5,14,9,9,7,1,5,2,9,1,13,1,13,1,5,2,7,9,7,1,13,1,5,2,7,1,1,1,5,1,7,1,19,2,7,1,1,1,5,1,7,1,19,2,7,1,1,1,5,1,7,1,19,2,7,1,1,13,1,1,7,14,7,1,7,1,5,1,1,1,7,1,12,1,7,1,7,1,5,1,1,1,7,1,12,1,7,1,7,1,5,1,1,1,7,1,12,9,7,9,7,1,34,1,9,1,34,1,9,1,34,1,9,1,34,11,12
|
350
2019/d17/ex2/ex2.py
Executable file
350
2019/d17/ex2/ex2.py
Executable file
|
@ -0,0 +1,350 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum, IntEnum, auto
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self): # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
class Position(NamedTuple):
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
class Direction(Enum):
|
||||
NORTH = auto()
|
||||
WEST = auto()
|
||||
SOUTH = auto()
|
||||
EAST = auto()
|
||||
|
||||
|
||||
DIRECTIONS = [d for d in Direction]
|
||||
ARROW_DIRECTION = {
|
||||
"^": Direction.NORTH,
|
||||
"v": Direction.SOUTH,
|
||||
"<": Direction.WEST,
|
||||
">": Direction.EAST,
|
||||
}
|
||||
DIRECTION_OFFSET = {
|
||||
Direction.NORTH: (-1, 0),
|
||||
Direction.SOUTH: (1, 0),
|
||||
Direction.WEST: (0, -1),
|
||||
Direction.EAST: (0, 1),
|
||||
}
|
||||
|
||||
|
||||
def turn(d: Direction, turn: str) -> Direction:
|
||||
def turn_left() -> Direction:
|
||||
return DIRECTIONS[(DIRECTIONS.index(d) + 1) % len(DIRECTIONS)]
|
||||
|
||||
def turn_right() -> Direction:
|
||||
return DIRECTIONS[DIRECTIONS.index(d) - 1]
|
||||
|
||||
if turn == "L":
|
||||
return turn_left()
|
||||
elif turn == "R":
|
||||
return turn_right()
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def find_arrow(mapped_view: List[List[str]]) -> Position:
|
||||
for x in range(len(mapped_view)):
|
||||
for y in range(len(mapped_view[0])):
|
||||
if mapped_view[x][y] in ARROW_DIRECTION:
|
||||
return Position(x, y)
|
||||
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def get_path(mapped_view: List[List[str]]) -> List[str]:
|
||||
pos = find_arrow(mapped_view)
|
||||
|
||||
def pos_is_valid(p: Position) -> bool:
|
||||
return 0 <= p.x < len(mapped_view) and 0 <= p.y < len(mapped_view[0])
|
||||
|
||||
def pos_is_scaffold(p: Position) -> bool:
|
||||
return pos_is_valid(p) and mapped_view[p.x][p.y] != "."
|
||||
|
||||
direction = ARROW_DIRECTION[mapped_view[pos.x][pos.y]]
|
||||
ans: List[str] = []
|
||||
|
||||
def advance_until_stopped(turn_string: str) -> bool:
|
||||
nonlocal pos
|
||||
nonlocal direction
|
||||
d = turn(direction, turn_string)
|
||||
offset = DIRECTION_OFFSET[d]
|
||||
neighbor = Position(*(a + b for a, b in zip(pos, offset)))
|
||||
tot = 0
|
||||
while pos_is_scaffold(neighbor):
|
||||
tot += 1
|
||||
mapped_view[pos.x][pos.y] = "@"
|
||||
pos = neighbor
|
||||
neighbor = Position(*(a + b for a, b in zip(pos, offset)))
|
||||
|
||||
if tot == 0:
|
||||
return False
|
||||
direction = d
|
||||
ans.append(turn_string)
|
||||
ans.append(str(tot))
|
||||
return True
|
||||
|
||||
has_no_neighbors = False
|
||||
while not has_no_neighbors:
|
||||
for turn_string in ("L", "R"):
|
||||
if advance_until_stopped(turn_string):
|
||||
break
|
||||
else:
|
||||
has_no_neighbors = True
|
||||
return ans
|
||||
|
||||
|
||||
def sequitur_algorithm(path: str) -> None:
|
||||
# FIXME: seems like a good candidate for compression
|
||||
pass
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
camera = Computer(deepcopy(memory))
|
||||
|
||||
camera.run_no_output_interrupt()
|
||||
|
||||
view = "".join(chr(c) for c in camera.output_list)
|
||||
mapped_view = [[c for c in line] for line in view.split("\n") if line != ""]
|
||||
|
||||
path = get_path(mapped_view)
|
||||
print(path)
|
||||
|
||||
# I didn't want to write the compression algorithm when I could just use Vim
|
||||
# The answere is A,B,B,A,C,A,A,C,B,C
|
||||
# A: R,8,L,12,R,8
|
||||
# B: R,12,L,8,R,10
|
||||
# C: R,8,L,8,L,8,R,8,R,10
|
||||
|
||||
ans = "A,B,B,A,C,A,A,C,B,C"
|
||||
A = "R,8,L,12,R,8"
|
||||
B = "R,12,L,8,R,10"
|
||||
C = "R,8,L,8,L,8,R,8,R,10"
|
||||
|
||||
assert len(ans) <= 20 # Sanity check
|
||||
assert len(A) <= 20 # Sanity check
|
||||
assert len(B) <= 20 # Sanity check
|
||||
assert len(C) <= 20 # Sanity check
|
||||
|
||||
memory[0] = 2 # Wake up the robot
|
||||
robot = Computer(memory)
|
||||
|
||||
for c in ans:
|
||||
robot.input_list.append(ord(c))
|
||||
robot.input_list.append(ord("\n"))
|
||||
for c in A:
|
||||
robot.input_list.append(ord(c))
|
||||
robot.input_list.append(ord("\n"))
|
||||
for c in B:
|
||||
robot.input_list.append(ord(c))
|
||||
robot.input_list.append(ord("\n"))
|
||||
for c in C:
|
||||
robot.input_list.append(ord(c))
|
||||
robot.input_list.append(ord("\n"))
|
||||
|
||||
for c in "n\n": # Do not output the video feed
|
||||
robot.input_list.append(ord(c))
|
||||
|
||||
robot.run_no_output_interrupt()
|
||||
print(robot.output_list.pop())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d17/ex2/input
Normal file
1
2019/d17/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
1,330,331,332,109,2952,1101,1182,0,16,1101,1467,0,24,102,1,0,570,1006,570,36,1002,571,1,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,16,1,16,1008,16,1467,570,1006,570,14,21101,0,58,0,1105,1,786,1006,332,62,99,21102,1,333,1,21101,73,0,0,1106,0,579,1101,0,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,101,0,574,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21101,340,0,1,1105,1,177,21101,477,0,1,1106,0,177,21101,514,0,1,21101,0,176,0,1105,1,579,99,21102,1,184,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,101,0,572,1182,21101,375,0,1,21101,211,0,0,1106,0,579,21101,1182,11,1,21101,222,0,0,1105,1,979,21101,0,388,1,21102,233,1,0,1106,0,579,21101,1182,22,1,21101,0,244,0,1106,0,979,21101,401,0,1,21102,1,255,0,1106,0,579,21101,1182,33,1,21101,266,0,0,1105,1,979,21101,414,0,1,21102,1,277,0,1106,0,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21101,1182,0,1,21101,313,0,0,1105,1,622,1005,575,327,1101,0,1,575,21102,327,1,0,1106,0,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,20,14,0,109,4,2102,1,-3,586,21001,0,0,-1,22101,1,-3,-3,21102,1,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1105,1,597,109,-4,2105,1,0,109,5,2101,0,-4,629,21001,0,0,-2,22101,1,-4,-4,21101,0,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21002,0,1,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,702,0,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21101,0,731,0,1105,1,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21102,1,756,0,1105,1,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1105,1,622,21201,-3,1,-3,1106,0,640,109,-5,2106,0,0,109,7,1005,575,802,20102,1,576,-6,20101,0,577,-5,1106,0,814,21101,0,0,-1,21102,1,0,-5,21101,0,0,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,45,-3,22201,-6,-3,-3,22101,1467,-3,-3,1202,-3,1,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1106,0,924,1205,-2,873,21101,0,35,-4,1105,1,924,1201,-3,0,878,1008,0,1,570,1006,570,916,1001,374,1,374,1201,-3,0,895,1102,1,2,0,1201,-3,0,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,921,21001,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,45,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,33,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21101,973,0,0,1106,0,786,99,109,-7,2105,1,0,109,6,21101,0,0,-4,21102,1,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1106,0,1041,21102,-4,1,-2,1106,0,1041,21102,1,-5,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1202,-2,1,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,1201,-2,0,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21101,0,439,1,1105,1,1150,21102,477,1,1,1106,0,1150,21102,1,514,1,21102,1149,1,0,1106,0,579,99,21102,1157,1,0,1105,1,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,1202,-5,1,1176,2102,1,-4,0,109,-6,2105,1,0,10,11,34,1,9,1,34,1,9,1,7,9,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,1,9,1,7,1,7,1,18,9,1,13,3,1,26,1,9,1,3,1,3,1,20,11,5,1,1,9,18,1,5,1,3,1,5,1,1,1,1,1,3,1,1,1,18,1,5,1,3,1,5,1,1,1,1,1,3,1,1,1,18,1,5,1,3,1,5,1,1,1,1,1,3,1,1,1,18,1,5,1,1,9,1,1,1,1,3,9,12,1,5,1,3,1,7,1,1,1,5,1,5,1,10,9,3,1,1,9,5,1,5,1,10,1,1,1,9,1,1,1,5,1,7,1,5,14,9,9,7,1,5,2,9,1,13,1,13,1,5,2,7,9,7,1,13,1,5,2,7,1,1,1,5,1,7,1,19,2,7,1,1,1,5,1,7,1,19,2,7,1,1,1,5,1,7,1,19,2,7,1,1,13,1,1,7,14,7,1,7,1,5,1,1,1,7,1,12,1,7,1,7,1,5,1,1,1,7,1,12,1,7,1,7,1,5,1,1,1,7,1,12,9,7,9,7,1,34,1,9,1,34,1,9,1,34,1,9,1,34,11,12
|
128
2019/d18/ex1/ex1.py
Executable file
128
2019/d18/ex1/ex1.py
Executable file
|
@ -0,0 +1,128 @@
|
|||
#!/usr/bin/env python
|
||||
import heapq
|
||||
import sys
|
||||
from collections import defaultdict, deque
|
||||
from dataclasses import dataclass
|
||||
from functools import lru_cache
|
||||
from math import inf
|
||||
from typing import DefaultDict, Deque, Dict, FrozenSet, Iterator, List, Tuple, Union
|
||||
|
||||
RawGrid = List[str]
|
||||
GraphInfo = List[Tuple[str, int]]
|
||||
Graph = Dict[str, GraphInfo]
|
||||
|
||||
|
||||
@dataclass(eq=True, frozen=True) # Hash-able
|
||||
class Position:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
def neighbours(grid: RawGrid, pos: Position) -> Iterator[Position]:
|
||||
for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
|
||||
new_pos = Position(pos.x + dx, pos.y + dy)
|
||||
if not (0 <= new_pos.x < len(grid) and 0 <= new_pos.y < len(grid[0])):
|
||||
continue
|
||||
if grid[new_pos.x][new_pos.y] == "#":
|
||||
continue
|
||||
yield new_pos
|
||||
|
||||
|
||||
def find_adjacent(grid: RawGrid, pos: Position) -> GraphInfo:
|
||||
queue: Deque[Tuple[Position, int]] = deque()
|
||||
visited = {pos}
|
||||
adjacent: GraphInfo = []
|
||||
|
||||
for n in neighbours(grid, pos):
|
||||
queue.append((n, 1)) # Distance is 1
|
||||
|
||||
while queue:
|
||||
n, d = queue.popleft()
|
||||
if n in visited:
|
||||
continue
|
||||
visited |= {n}
|
||||
cell = grid[n.x][n.y]
|
||||
|
||||
if cell not in "#.@": # We don't care about those
|
||||
adjacent.append((cell, d))
|
||||
continue # Do not go through doors and keys
|
||||
|
||||
for neighbour in neighbours(grid, n):
|
||||
queue.append((neighbour, d + 1))
|
||||
|
||||
return adjacent
|
||||
|
||||
|
||||
def build_graph(grid: RawGrid) -> Graph:
|
||||
graph = {}
|
||||
|
||||
for x, row in enumerate(grid):
|
||||
for y, cell in enumerate(row):
|
||||
if cell not in "#.":
|
||||
graph[cell] = find_adjacent(grid, Position(x, y))
|
||||
|
||||
return graph
|
||||
|
||||
|
||||
def solve(G: Graph, start: str) -> int:
|
||||
@lru_cache(2**20)
|
||||
def reachable_keys(src: str, found: FrozenSet[str]) -> List[Tuple[str, int]]:
|
||||
queue = []
|
||||
distance: DefaultDict[str, Union[float, int]] = defaultdict(lambda: inf)
|
||||
reachable: List[Tuple[str, int]] = []
|
||||
|
||||
for neighbor, weight in G[src]:
|
||||
queue.append((weight, neighbor)) # Weight first for heap comparisons
|
||||
|
||||
heapq.heapify(queue)
|
||||
|
||||
while queue:
|
||||
dist, node = heapq.heappop(queue)
|
||||
|
||||
# Do key, add it to reachable if not found previously
|
||||
if node.islower() and node not in found:
|
||||
reachable.append((node, dist))
|
||||
continue
|
||||
|
||||
# Do door, if not opened by a key that was found in the search
|
||||
if node.lower() not in found:
|
||||
continue
|
||||
|
||||
# If not a key and not a closed door
|
||||
for neighbor, weight in G[node]:
|
||||
new_dist = dist + weight
|
||||
if new_dist < distance[neighbor]:
|
||||
distance[neighbor] = new_dist
|
||||
heapq.heappush(queue, (new_dist, neighbor))
|
||||
|
||||
return reachable
|
||||
|
||||
@lru_cache(2**20)
|
||||
def min_steps(
|
||||
src: str, keys_to_find: int, found: FrozenSet[str] = frozenset()
|
||||
) -> int:
|
||||
if keys_to_find == 0:
|
||||
return 0
|
||||
|
||||
best = inf
|
||||
|
||||
for key, dist in reachable_keys(src, found):
|
||||
new_keys = found | {key}
|
||||
dist += min_steps(key, keys_to_find - 1, new_keys)
|
||||
|
||||
if dist < best:
|
||||
best = dist
|
||||
|
||||
return int(best) # That way we throw if we kept the infinite float
|
||||
|
||||
total_keys = sum(node.islower() for node in G)
|
||||
return min_steps(start, total_keys)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
G = build_graph(list(line.strip() for line in sys.stdin.readlines()))
|
||||
print(solve(G, "@"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
81
2019/d18/ex1/input
Normal file
81
2019/d18/ex1/input
Normal file
|
@ -0,0 +1,81 @@
|
|||
#################################################################################
|
||||
#.......#...#...#...........#.....#...#.#.....#m......#.......#.....#........u..#
|
||||
#####.#.#.#.#.#.###.#######.###.#.#.#.#.#.###.###.#####.#.###.###.#.###########.#
|
||||
#.....#...#...#.....#.#.....#...#...#...#.#....e#.......#...#.....#.....#.......#
|
||||
#.###################.#.#####.#########.#.#####.###########.###########.#.#######
|
||||
#.#...#...#...........#.#.....#.......#.#.....#.....#.....#...#.......#.#.#.....#
|
||||
#.#S#.###.#.#####.#####.#.###.#.###.###.#####.#####.#.###.###.#.#.#####.#.#.###.#
|
||||
#.#.#...#.#...#.#.......#.#.#.#.#...#...#.D.#.#...#...#.#.#...#.#.#.....#j..#...#
|
||||
#.#.###.#.###.#.#########.#.#.###.###.###.#.#.#.#.#####.#.#.###.###.#########.###
|
||||
#.#...#.#...#...#.#.........#...#.#...#.#.#...#.#.....#...#...#...#.#.#.....#...#
|
||||
#.###.#.###.###.#.#.#########.#.#.#.###.#.#####.#####.#.#####.###.#.#.#.#.#.###.#
|
||||
#...#.#c..#.....#.......#...#.#.#.#.#...#...#.....#.#.#.#.....#...#.#...#.#...#.#
|
||||
#.###.###.#.#############.#.###.#.#.#.#.###.#####.#.#.#.#.#####.###.#.###.###.#.#
|
||||
#.#...#.#.#.........#.....#...#.#.....#.#.#...#.#...#.#...#...#.....#.#...#...K.#
|
||||
#.#.###.#.#########.#.#######.#.#########.###.#.###.#.#####.#.#.#######.#########
|
||||
#.......#.#.......#h..#.....#.#.........#...#.#.....#.......#...#.....#.#...#...#
|
||||
#.#######.#O#####.#######.#.#.#.#######.###.#.#.#######.#######.#.###F#.#.#.#.#.#
|
||||
#.#....y..#...#...#.....#.#.#.#.#.#.....#...#.#.#.....#.#.....#...#.#.#...#.#.#.#
|
||||
###.#####.###.#.###.###.#.###.#.#.#.###.#.#.#.###.###.#.#.###.#####.#.#.###.#.#.#
|
||||
#...#.....#.#.#...#.#.Z.#...#.#.#.#.#...#.#.#.....#.#.#.#.#.#...#.....#...#...#.#
|
||||
#.###.#####.#.###A#.#.###.#.#.#.#.#.#####.#########.#.#.#.#.###.#.#########.###.#
|
||||
#.#.#.#.....#.#.#...#.#...#...#...#.....#.#.........#.#.#.#.#...#.#.......#.#...#
|
||||
#.#.#.#####.#.#.#######.#########.#####.#.#.#####.#.#.#.#.#.#####.#.###.#.###.#.#
|
||||
#.#.#...#...#.#...#.....#.....#.......#.#.#.#.#...#.#.#.#.#.....#.#.#...#.....#.#
|
||||
#.#.###.#.#.#.###.#.#######.#.#####.###.#.#.#.#.#####.#.#.#.#.###.###.#########X#
|
||||
#.#...#...#.#...#.#...#.....#.....#.#...#.....#.#...#.#.#.#.#...#...#.....#.....#
|
||||
#.#W#.#####.###N#.###.#.#.#######.###.#.#######.#.#.#.###.#.###.###.#####.###.###
|
||||
#i#.#.....#.#.#.#...#.#.#.#.....#.....#.#..r..#...#.#...#.#.#.....#.#...#...#.#.#
|
||||
#.#######.#.#.#.#.###.###.#.###########.#.###.#.###.###.#.###.#####.#.#.###.#.#.#
|
||||
#.......#...#.#.#...#...#.#.............#.#.#.#.#.#...#...#...#.....#.#.....#.#.#
|
||||
#.#####.#.###.#.#.#.###.#.#.#############.#.#.#.#.###.#####.###.#####.#######.#.#
|
||||
#.#.#...#.....#.#.#...#..t#...#.#.......#.#.#.#...#.....#.....#...#...#.....#.#.#
|
||||
#.#.#.#######.#.#.###.#######.#.#.#.#####.#.#.#.###.###.#####.###.###.#.###.#.#.#
|
||||
#...#.#...#...#.#...#.....#.#.#...#.....#.#.#.#.#...#.........#.#...#...T.#.#...#
|
||||
###.#.#.#.#.###.###.#.###.#.#.#########.#.#.#.###.###########.#.###.#####.#.###.#
|
||||
#...#...#.#.#...#...#...#...#.......#...#.#.#...#.#.....#...#...#...#...#.#...#.#
|
||||
#.#######.###.###.#####.###########.#.###.#.###.#.#.###.#.#.###.#.###.#.#####.###
|
||||
#.#...#v#...#.#.#.....#.........#...#...#.#.......#...#..l#...#.#.....#.....#.P.#
|
||||
#.#.#.#.###.#.#.#####.#########.#.#####.#.###########.#######.#############.###.#
|
||||
#...#.....#...#...............#.............................#....b..............#
|
||||
#######################################.@.#######################################
|
||||
#...#.#.........#.....#...........#...........#...#.....#.......#...#.....Q.#...#
|
||||
#.#.#.#.#####.###.#.#.#.#####.###.#.###.#.###.#.#.#.###.#.#####.#.#.#.#.###.###.#
|
||||
#.#.#.#.#...#.....#.#.#.#.#...#...#...#.#.#.....#.#...#...#.....#.#.#.#...#.#...#
|
||||
#.#.#.#.#.#.#######.###.#.#.#####.###.#.#.#######.###.#####.#####.#.#.###.#.#.#.#
|
||||
#.#...#.#.#.....#.#.#.B...#.....#.#...#.#.....#.....#.#...#.......#.#.#...#...#.#
|
||||
#.#####.#.#####.#.#.#.#######.#.###.###.#.###.###.###.#.#####.#####.#.#.#######.#
|
||||
#.#...#q#..f#.....#...#.....#.#...#.#...#.#.#...#.#.....#...#.#...#...#.#.....#.#
|
||||
#.#.#.#.#.#.#######.###.###.###.#.#.#.###.#.###.###.#####.#.#.###.#####.#.###.#.#
|
||||
#...#.#.#.#...#...#p..#.#.#...#.#...#...#.....#...#.#.....#.#.....#...#...#...#.#
|
||||
#####.#.#####.#.#.###.#.#.###.#########.#####.###.#.#.#####.#####.###.#####.###.#
|
||||
#.....#.......#.#.#...#.#...#.#.......#.#...#.#.#...#.#...#.....#.....#.#...#.#.#
|
||||
#.###########.#.#.#####.###.#L#.#####R#.#.#.#.#.#####.#.#.#####.#####.#.#.###.#.#
|
||||
#...........#.#.#.......#...#...#...#...#.#.#.....#...#.#.....#...#...#.#...#...#
|
||||
#######.###.#.#.#########.#.#####.#.#######.#####.#.#######.#.###.#.###.###.###.#
|
||||
#.......#...#.#.#.........#.......#.....#...#.....#.#.....#.#...#.#...#...#...#.#
|
||||
#.#######.###.#.#.###.#################.#.###.#####.#.#.#.###.###.###.###.###.#.#
|
||||
#.#.........#.#.#...#.............#.....#.........#.#.#.#.....#...#.#.......#.#.#
|
||||
#.###.#######.#.###########.#####.#.###############.###.#####.#.###.#.#####.#.###
|
||||
#...#.#.......#.#.........#.#...#.#.#...#.......#...#...#.#...#.#.....#...#.#...#
|
||||
#.#G###.#######.#.#######.#.###.#.###.#.#.#####.#.###.###.#.###.#######.#.#####.#
|
||||
#.#...#....x#.#.#.#z#.....#.....#.....#.#.....#...#...#...#.#...#.......#.#...#.#
|
||||
#.###.#####.#.#.#.#.#########.#########.#####.#######.#.###.#####.#######.#.#.#.#
|
||||
#k#.#.....#...#...#.#.....#...#.......#.#...#.#.......#.#...#.....#.#...#...#.#.#
|
||||
#.#.#####.###.#####.#.###.#.###.#####.#.#.#.#.#.#.#####.#.###.#####.#.#.#####.#H#
|
||||
#.#.....#...#.....#.#...#.#.#...#...#...#.#...#.#.#.....#.#...#...#...#...#.#.#.#
|
||||
#.#.###.###.#####.#.###.#.#.#.###.#.###.#.#######.#.###.#.#.###.#.#.###.#Y#.#.#.#
|
||||
#...#...#.#...#...#.....#..o#.#.#.#.....#.#.......#.#...#...#...#...#...#...#..g#
|
||||
#####.###.#.###.#######.#####.#.#.#######.#####.###.###.#############.#####.###.#
|
||||
#...#.#...#.....#.....#.....#.#.#...#...#.......#.....#...#...........#.#...#...#
|
||||
#.#.#.###.#######.###.#######.#.###.#.###########.###.###.#.###########.#.###.###
|
||||
#.#.#.#.....#.#.....#.#.......#...#.#...#...#...#...#.#...#.......#...#.I.#.#...#
|
||||
#.#.#.#.###.#.#.###.#.#.#######.#.#.###.#.###.#.#.###.#.#########.###.#.###.###.#
|
||||
#.#.#.#.#...#s....#.#.#.......#a#.#.....#.#...#.#.#...#.....#.....#...#.....#.#.#
|
||||
#.###M#U###.#####.#.#.###.###.###.#####.#.#.###.#.#.#.#####.#.#####.#V#####.#.#.#
|
||||
#.....#...#...#...#.#...#...#.#...#....n#.#...#d..#.#.#.J.#...#.....#...#..w#.#.#
|
||||
#.#######.###.#####.###.#####.#.###.#####.###.#####.#.#.#.###.#####.#####.###.#.#
|
||||
#.......#.#.#...#...#.#.....#.#...#.#...#...#.#.#...#.#.#.#...#...#...........#.#
|
||||
#######.#.#.###E#.###.#####.#.#.#.#.###.#.###.#.#.#####.#.#####.#.#############.#
|
||||
#.........#.......#.........C.#.#.......#.......#.......#.......#...............#
|
||||
#################################################################################
|
130
2019/d18/ex2/ex2.py
Executable file
130
2019/d18/ex2/ex2.py
Executable file
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/env python
|
||||
import heapq
|
||||
import sys
|
||||
from collections import defaultdict, deque
|
||||
from dataclasses import dataclass
|
||||
from functools import lru_cache
|
||||
from math import inf
|
||||
from typing import DefaultDict, Deque, Dict, FrozenSet, Iterator, List, Tuple, Union
|
||||
|
||||
RawGrid = List[str]
|
||||
GraphInfo = List[Tuple[str, int]]
|
||||
Graph = Dict[str, GraphInfo]
|
||||
|
||||
|
||||
@dataclass(eq=True, frozen=True) # Hash-able
|
||||
class Position:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
def neighbours(grid: RawGrid, pos: Position) -> Iterator[Position]:
|
||||
for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
|
||||
new_pos = Position(pos.x + dx, pos.y + dy)
|
||||
if not (0 <= new_pos.x < len(grid) and 0 <= new_pos.y < len(grid[0])):
|
||||
continue
|
||||
if grid[new_pos.x][new_pos.y] == "#":
|
||||
continue
|
||||
yield new_pos
|
||||
|
||||
|
||||
def find_adjacent(grid: RawGrid, pos: Position) -> GraphInfo:
|
||||
queue: Deque[Tuple[Position, int]] = deque()
|
||||
visited = {pos}
|
||||
adjacent: GraphInfo = []
|
||||
|
||||
for n in neighbours(grid, pos):
|
||||
queue.append((n, 1)) # Distance is 1
|
||||
|
||||
while queue:
|
||||
n, d = queue.popleft()
|
||||
if n in visited:
|
||||
continue
|
||||
visited |= {n}
|
||||
cell = grid[n.x][n.y]
|
||||
|
||||
if cell not in "#.1234": # We don't care about those
|
||||
adjacent.append((cell, d))
|
||||
continue # Do not go through doors and keys
|
||||
|
||||
for neighbour in neighbours(grid, n):
|
||||
queue.append((neighbour, d + 1))
|
||||
|
||||
return adjacent
|
||||
|
||||
|
||||
def build_graph(grid: RawGrid) -> Graph:
|
||||
graph = {}
|
||||
|
||||
for x, row in enumerate(grid):
|
||||
for y, cell in enumerate(row):
|
||||
if cell not in "#.":
|
||||
graph[cell] = find_adjacent(grid, Position(x, y))
|
||||
|
||||
return graph
|
||||
|
||||
|
||||
def solve(G: Graph, start: str) -> int:
|
||||
@lru_cache(2**20)
|
||||
def reachable_keys(src: str, found: FrozenSet[str]) -> GraphInfo:
|
||||
queue = []
|
||||
distance: DefaultDict[str, Union[float, int]] = defaultdict(lambda: inf)
|
||||
reachable: GraphInfo = []
|
||||
|
||||
for neighbor, weight in G[src]:
|
||||
queue.append((weight, neighbor)) # Weight first for heap comparisons
|
||||
|
||||
heapq.heapify(queue)
|
||||
|
||||
while queue:
|
||||
dist, node = heapq.heappop(queue)
|
||||
|
||||
# Do key, add it to reachable if not found previously
|
||||
if node.islower() and node not in found:
|
||||
reachable.append((node, dist))
|
||||
continue
|
||||
|
||||
# Do door, if not opened by a key that was found in the search
|
||||
if node.lower() not in found:
|
||||
continue
|
||||
|
||||
# If not a key and not a closed door
|
||||
for neighbor, weight in G[node]:
|
||||
new_dist = dist + weight
|
||||
if new_dist < distance[neighbor]:
|
||||
distance[neighbor] = new_dist
|
||||
heapq.heappush(queue, (new_dist, neighbor))
|
||||
|
||||
return reachable
|
||||
|
||||
@lru_cache(2**20)
|
||||
def min_steps(
|
||||
sources: str, keys_to_find: int, found: FrozenSet[str] = frozenset()
|
||||
) -> Union[float, int]:
|
||||
if keys_to_find == 0:
|
||||
return 0
|
||||
|
||||
best = inf
|
||||
|
||||
for src in sources:
|
||||
for key, dist in reachable_keys(src, found):
|
||||
new_keys = found | {key}
|
||||
new_sources = sources.replace(src, key)
|
||||
new_dist = dist + min_steps(new_sources, keys_to_find - 1, new_keys)
|
||||
|
||||
if new_dist < best:
|
||||
best = new_dist
|
||||
|
||||
return best
|
||||
|
||||
total_keys = sum(node.islower() for node in G)
|
||||
return int(min_steps(start, total_keys)) # Throw if we kept the infinite float
|
||||
|
||||
|
||||
def main() -> None:
|
||||
G = build_graph(list(line.strip() for line in sys.stdin.readlines()))
|
||||
print(solve(G, "1234"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
81
2019/d18/ex2/input
Normal file
81
2019/d18/ex2/input
Normal file
|
@ -0,0 +1,81 @@
|
|||
#################################################################################
|
||||
#.......#...#...#...........#.....#...#.#.....#m......#.......#.....#........u..#
|
||||
#####.#.#.#.#.#.###.#######.###.#.#.#.#.#.###.###.#####.#.###.###.#.###########.#
|
||||
#.....#...#...#.....#.#.....#...#...#...#.#....e#.......#...#.....#.....#.......#
|
||||
#.###################.#.#####.#########.#.#####.###########.###########.#.#######
|
||||
#.#...#...#...........#.#.....#.......#.#.....#.....#.....#...#.......#.#.#.....#
|
||||
#.#S#.###.#.#####.#####.#.###.#.###.###.#####.#####.#.###.###.#.#.#####.#.#.###.#
|
||||
#.#.#...#.#...#.#.......#.#.#.#.#...#...#.D.#.#...#...#.#.#...#.#.#.....#j..#...#
|
||||
#.#.###.#.###.#.#########.#.#.###.###.###.#.#.#.#.#####.#.#.###.###.#########.###
|
||||
#.#...#.#...#...#.#.........#...#.#...#.#.#...#.#.....#...#...#...#.#.#.....#...#
|
||||
#.###.#.###.###.#.#.#########.#.#.#.###.#.#####.#####.#.#####.###.#.#.#.#.#.###.#
|
||||
#...#.#c..#.....#.......#...#.#.#.#.#...#...#.....#.#.#.#.....#...#.#...#.#...#.#
|
||||
#.###.###.#.#############.#.###.#.#.#.#.###.#####.#.#.#.#.#####.###.#.###.###.#.#
|
||||
#.#...#.#.#.........#.....#...#.#.....#.#.#...#.#...#.#...#...#.....#.#...#...K.#
|
||||
#.#.###.#.#########.#.#######.#.#########.###.#.###.#.#####.#.#.#######.#########
|
||||
#.......#.#.......#h..#.....#.#.........#...#.#.....#.......#...#.....#.#...#...#
|
||||
#.#######.#O#####.#######.#.#.#.#######.###.#.#.#######.#######.#.###F#.#.#.#.#.#
|
||||
#.#....y..#...#...#.....#.#.#.#.#.#.....#...#.#.#.....#.#.....#...#.#.#...#.#.#.#
|
||||
###.#####.###.#.###.###.#.###.#.#.#.###.#.#.#.###.###.#.#.###.#####.#.#.###.#.#.#
|
||||
#...#.....#.#.#...#.#.Z.#...#.#.#.#.#...#.#.#.....#.#.#.#.#.#...#.....#...#...#.#
|
||||
#.###.#####.#.###A#.#.###.#.#.#.#.#.#####.#########.#.#.#.#.###.#.#########.###.#
|
||||
#.#.#.#.....#.#.#...#.#...#...#...#.....#.#.........#.#.#.#.#...#.#.......#.#...#
|
||||
#.#.#.#####.#.#.#######.#########.#####.#.#.#####.#.#.#.#.#.#####.#.###.#.###.#.#
|
||||
#.#.#...#...#.#...#.....#.....#.......#.#.#.#.#...#.#.#.#.#.....#.#.#...#.....#.#
|
||||
#.#.###.#.#.#.###.#.#######.#.#####.###.#.#.#.#.#####.#.#.#.#.###.###.#########X#
|
||||
#.#...#...#.#...#.#...#.....#.....#.#...#.....#.#...#.#.#.#.#...#...#.....#.....#
|
||||
#.#W#.#####.###N#.###.#.#.#######.###.#.#######.#.#.#.###.#.###.###.#####.###.###
|
||||
#i#.#.....#.#.#.#...#.#.#.#.....#.....#.#..r..#...#.#...#.#.#.....#.#...#...#.#.#
|
||||
#.#######.#.#.#.#.###.###.#.###########.#.###.#.###.###.#.###.#####.#.#.###.#.#.#
|
||||
#.......#...#.#.#...#...#.#.............#.#.#.#.#.#...#...#...#.....#.#.....#.#.#
|
||||
#.#####.#.###.#.#.#.###.#.#.#############.#.#.#.#.###.#####.###.#####.#######.#.#
|
||||
#.#.#...#.....#.#.#...#..t#...#.#.......#.#.#.#...#.....#.....#...#...#.....#.#.#
|
||||
#.#.#.#######.#.#.###.#######.#.#.#.#####.#.#.#.###.###.#####.###.###.#.###.#.#.#
|
||||
#...#.#...#...#.#...#.....#.#.#...#.....#.#.#.#.#...#.........#.#...#...T.#.#...#
|
||||
###.#.#.#.#.###.###.#.###.#.#.#########.#.#.#.###.###########.#.###.#####.#.###.#
|
||||
#...#...#.#.#...#...#...#...#.......#...#.#.#...#.#.....#...#...#...#...#.#...#.#
|
||||
#.#######.###.###.#####.###########.#.###.#.###.#.#.###.#.#.###.#.###.#.#####.###
|
||||
#.#...#v#...#.#.#.....#.........#...#...#.#.......#...#..l#...#.#.....#.....#.P.#
|
||||
#.#.#.#.###.#.#.#####.#########.#.#####.#.###########.#######.#############.###.#
|
||||
#...#.....#...#...............#........1#2..................#....b..............#
|
||||
########################################@.#######################################
|
||||
#...#.#.........#.....#...........#....3#4....#...#.....#.......#...#.....Q.#...#
|
||||
#.#.#.#.#####.###.#.#.#.#####.###.#.###.#.###.#.#.#.###.#.#####.#.#.#.#.###.###.#
|
||||
#.#.#.#.#...#.....#.#.#.#.#...#...#...#.#.#.....#.#...#...#.....#.#.#.#...#.#...#
|
||||
#.#.#.#.#.#.#######.###.#.#.#####.###.#.#.#######.###.#####.#####.#.#.###.#.#.#.#
|
||||
#.#...#.#.#.....#.#.#.B...#.....#.#...#.#.....#.....#.#...#.......#.#.#...#...#.#
|
||||
#.#####.#.#####.#.#.#.#######.#.###.###.#.###.###.###.#.#####.#####.#.#.#######.#
|
||||
#.#...#q#..f#.....#...#.....#.#...#.#...#.#.#...#.#.....#...#.#...#...#.#.....#.#
|
||||
#.#.#.#.#.#.#######.###.###.###.#.#.#.###.#.###.###.#####.#.#.###.#####.#.###.#.#
|
||||
#...#.#.#.#...#...#p..#.#.#...#.#...#...#.....#...#.#.....#.#.....#...#...#...#.#
|
||||
#####.#.#####.#.#.###.#.#.###.#########.#####.###.#.#.#####.#####.###.#####.###.#
|
||||
#.....#.......#.#.#...#.#...#.#.......#.#...#.#.#...#.#...#.....#.....#.#...#.#.#
|
||||
#.###########.#.#.#####.###.#L#.#####R#.#.#.#.#.#####.#.#.#####.#####.#.#.###.#.#
|
||||
#...........#.#.#.......#...#...#...#...#.#.#.....#...#.#.....#...#...#.#...#...#
|
||||
#######.###.#.#.#########.#.#####.#.#######.#####.#.#######.#.###.#.###.###.###.#
|
||||
#.......#...#.#.#.........#.......#.....#...#.....#.#.....#.#...#.#...#...#...#.#
|
||||
#.#######.###.#.#.###.#################.#.###.#####.#.#.#.###.###.###.###.###.#.#
|
||||
#.#.........#.#.#...#.............#.....#.........#.#.#.#.....#...#.#.......#.#.#
|
||||
#.###.#######.#.###########.#####.#.###############.###.#####.#.###.#.#####.#.###
|
||||
#...#.#.......#.#.........#.#...#.#.#...#.......#...#...#.#...#.#.....#...#.#...#
|
||||
#.#G###.#######.#.#######.#.###.#.###.#.#.#####.#.###.###.#.###.#######.#.#####.#
|
||||
#.#...#....x#.#.#.#z#.....#.....#.....#.#.....#...#...#...#.#...#.......#.#...#.#
|
||||
#.###.#####.#.#.#.#.#########.#########.#####.#######.#.###.#####.#######.#.#.#.#
|
||||
#k#.#.....#...#...#.#.....#...#.......#.#...#.#.......#.#...#.....#.#...#...#.#.#
|
||||
#.#.#####.###.#####.#.###.#.###.#####.#.#.#.#.#.#.#####.#.###.#####.#.#.#####.#H#
|
||||
#.#.....#...#.....#.#...#.#.#...#...#...#.#...#.#.#.....#.#...#...#...#...#.#.#.#
|
||||
#.#.###.###.#####.#.###.#.#.#.###.#.###.#.#######.#.###.#.#.###.#.#.###.#Y#.#.#.#
|
||||
#...#...#.#...#...#.....#..o#.#.#.#.....#.#.......#.#...#...#...#...#...#...#..g#
|
||||
#####.###.#.###.#######.#####.#.#.#######.#####.###.###.#############.#####.###.#
|
||||
#...#.#...#.....#.....#.....#.#.#...#...#.......#.....#...#...........#.#...#...#
|
||||
#.#.#.###.#######.###.#######.#.###.#.###########.###.###.#.###########.#.###.###
|
||||
#.#.#.#.....#.#.....#.#.......#...#.#...#...#...#...#.#...#.......#...#.I.#.#...#
|
||||
#.#.#.#.###.#.#.###.#.#.#######.#.#.###.#.###.#.#.###.#.#########.###.#.###.###.#
|
||||
#.#.#.#.#...#s....#.#.#.......#a#.#.....#.#...#.#.#...#.....#.....#...#.....#.#.#
|
||||
#.###M#U###.#####.#.#.###.###.###.#####.#.#.###.#.#.#.#####.#.#####.#V#####.#.#.#
|
||||
#.....#...#...#...#.#...#...#.#...#....n#.#...#d..#.#.#.J.#...#.....#...#..w#.#.#
|
||||
#.#######.###.#####.###.#####.#.###.#####.###.#####.#.#.#.###.#####.#####.###.#.#
|
||||
#.......#.#.#...#...#.#.....#.#...#.#...#...#.#.#...#.#.#.#...#...#...........#.#
|
||||
#######.#.#.###E#.###.#####.#.#.#.#.###.#.###.#.#.#####.#.#####.#.#############.#
|
||||
#.........#.......#.........C.#.#.......#.......#.......#.......#...............#
|
||||
#################################################################################
|
214
2019/d19/ex1/ex1.py
Executable file
214
2019/d19/ex1/ex1.py
Executable file
|
@ -0,0 +1,214 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from itertools import product
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self) -> None: # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
|
||||
lines: List[List[int]] = [[0 for i in range(50)] for __ in range(50)]
|
||||
for x, y in product(range(50), range(50)):
|
||||
drone = Computer(deepcopy(memory), input_list=[x, y])
|
||||
drone.run_no_output_interrupt()
|
||||
assert len(drone.output_list) == 1
|
||||
lines[x][y] = drone.output_list.pop()
|
||||
print(sum(map(sum, lines)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d19/ex1/input
Normal file
1
2019/d19/ex1/input
Normal file
|
@ -0,0 +1 @@
|
|||
109,424,203,1,21102,11,1,0,1106,0,282,21102,18,1,0,1106,0,259,1201,1,0,221,203,1,21102,31,1,0,1106,0,282,21101,38,0,0,1106,0,259,21002,23,1,2,22102,1,1,3,21101,1,0,1,21102,57,1,0,1105,1,303,2102,1,1,222,20101,0,221,3,20101,0,221,2,21102,259,1,1,21101,80,0,0,1106,0,225,21101,0,44,2,21102,91,1,0,1105,1,303,1201,1,0,223,20101,0,222,4,21101,0,259,3,21102,225,1,2,21101,225,0,1,21102,118,1,0,1105,1,225,21002,222,1,3,21101,100,0,2,21101,133,0,0,1105,1,303,21202,1,-1,1,22001,223,1,1,21101,148,0,0,1106,0,259,2102,1,1,223,20102,1,221,4,21002,222,1,3,21102,1,12,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21102,1,195,0,106,0,108,20207,1,223,2,21002,23,1,1,21102,-1,1,3,21101,0,214,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2102,1,-4,249,21201,-3,0,1,22101,0,-2,2,22101,0,-1,3,21101,0,250,0,1105,1,225,22102,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,21202,-2,1,-2,109,-3,2105,1,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22102,1,-2,3,21101,0,343,0,1105,1,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21201,-4,0,1,21101,0,384,0,1106,0,303,1106,0,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,22102,1,1,-4,109,-5,2106,0,0
|
221
2019/d19/ex2/ex2.py
Executable file
221
2019/d19/ex2/ex2.py
Executable file
|
@ -0,0 +1,221 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum
|
||||
from typing import List, NamedTuple
|
||||
|
||||
|
||||
class ParameterMode(IntEnum):
|
||||
POSITION = 0 # Acts on address
|
||||
IMMEDIATE = 1 # Acts on the immediate value
|
||||
RELATIVE = 2 # Acts on offset to relative base
|
||||
|
||||
|
||||
class Instruction(NamedTuple):
|
||||
address: int # The address of the instruction, for convenience
|
||||
op: int # The opcode
|
||||
p1_mode: ParameterMode # Which mode is the first parameter in
|
||||
p2_mode: ParameterMode # Which mode is the second parameter in
|
||||
p3_mode: ParameterMode # Which mode is the third parameter in
|
||||
|
||||
|
||||
def lookup_ops(index: int, memory: List[int]) -> Instruction:
|
||||
digits = list(map(int, str(memory[index])))
|
||||
a, b, c, d, e = [0] * (5 - len(digits)) + digits # Pad with default values
|
||||
return Instruction(
|
||||
address=index,
|
||||
op=d * 10 + e,
|
||||
p1_mode=ParameterMode(c),
|
||||
p2_mode=ParameterMode(b),
|
||||
p3_mode=ParameterMode(a),
|
||||
)
|
||||
|
||||
|
||||
class InputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OutputInterrupt(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
memory: List[int] # Memory space
|
||||
rip: int = 0 # Instruction pointer
|
||||
input_list: List[int] = field(default_factory=list)
|
||||
output_list: List[int] = field(default_factory=list)
|
||||
is_halted: bool = field(default=False, init=False)
|
||||
relative_base: int = field(default=0, init=False)
|
||||
|
||||
def run(self) -> None:
|
||||
while not self.is_halted:
|
||||
self.run_single()
|
||||
|
||||
def run_no_output_interrupt(self) -> None:
|
||||
while not self.is_halted:
|
||||
try:
|
||||
self.run_single()
|
||||
except OutputInterrupt:
|
||||
continue
|
||||
|
||||
def run_single(self) -> None: # Returns True when halted
|
||||
instr = lookup_ops(self.rip, self.memory)
|
||||
if instr.op == 99: # Halt
|
||||
self.is_halted = True
|
||||
elif instr.op == 1: # Sum
|
||||
self._do_addition(instr)
|
||||
elif instr.op == 2: # Multiplication
|
||||
self._do_multiplication(instr)
|
||||
elif instr.op == 3: # Load from input
|
||||
self._do_input(instr)
|
||||
elif instr.op == 4: # Store to output
|
||||
self._do_output(instr)
|
||||
elif instr.op == 5: # Jump if true
|
||||
self._do_jump_if_true(instr)
|
||||
elif instr.op == 6: # Jump if false
|
||||
self._do_jump_if_false(instr)
|
||||
elif instr.op == 7: # Less than
|
||||
self._do_less_than(instr)
|
||||
elif instr.op == 8: # Equal to
|
||||
self._do_equal_to(instr)
|
||||
elif instr.op == 9: # Change relative base
|
||||
self._do_change_relative_base(instr)
|
||||
else:
|
||||
assert False # Sanity check
|
||||
|
||||
def _fill_to_addres(self, address: int) -> None:
|
||||
values = address - len(self.memory) + 1
|
||||
if values <= 0:
|
||||
return
|
||||
for __ in range(values):
|
||||
self.memory.append(0)
|
||||
|
||||
def _get_value(self, mode: ParameterMode, val: int) -> int:
|
||||
if mode == ParameterMode.POSITION:
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
elif mode == ParameterMode.RELATIVE:
|
||||
val += self.relative_base
|
||||
assert 0 <= val # Sanity check
|
||||
self._fill_to_addres(val)
|
||||
return self.memory[val]
|
||||
assert mode == ParameterMode.IMMEDIATE # Sanity check
|
||||
return val
|
||||
|
||||
def _set_value(self, mode: ParameterMode, address: int, value: int) -> None:
|
||||
if mode == ParameterMode.RELATIVE:
|
||||
address += self.relative_base
|
||||
else:
|
||||
assert mode == ParameterMode.POSITION # Sanity check
|
||||
|
||||
assert address >= 0 # Sanity check
|
||||
self._fill_to_addres(address)
|
||||
|
||||
self.memory[address] = value
|
||||
|
||||
def _do_addition(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs + rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_multiplication(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, lhs * rhs)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_input(self, instr: Instruction) -> None:
|
||||
if len(self.input_list) == 0:
|
||||
raise InputInterrupt # No input, halt until an input is provided
|
||||
|
||||
value = int(self.input_list.pop(0))
|
||||
param = self.memory[instr.address + 1]
|
||||
|
||||
self._set_value(instr.p1_mode, param, value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
def _do_output(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.output_list.append(value)
|
||||
|
||||
self.rip += 2 # Length of the instruction
|
||||
raise OutputInterrupt # Alert that we got an output to give
|
||||
|
||||
def _do_jump_if_true(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond != 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_jump_if_false(self, instr: Instruction) -> None:
|
||||
cond = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
value = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
|
||||
if cond == 0:
|
||||
self.rip = value
|
||||
else:
|
||||
self.rip += 3 # Length of the instruction
|
||||
|
||||
def _do_less_than(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs < rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_equal_to(self, instr: Instruction) -> None:
|
||||
lhs = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
rhs = self._get_value(instr.p2_mode, self.memory[instr.address + 2])
|
||||
dest = self.memory[instr.address + 3]
|
||||
|
||||
self._set_value(instr.p3_mode, dest, 1 if lhs == rhs else 0)
|
||||
|
||||
self.rip += 4 # Length of the instruction
|
||||
|
||||
def _do_change_relative_base(self, instr: Instruction) -> None:
|
||||
value = self._get_value(instr.p1_mode, self.memory[instr.address + 1])
|
||||
|
||||
self.relative_base += value
|
||||
self.rip += 2 # Length of the instruction
|
||||
|
||||
|
||||
def true_at(memory: List[int], x: int, y: int) -> bool:
|
||||
drone = Computer(deepcopy(memory), input_list=[x, y])
|
||||
drone.run_no_output_interrupt()
|
||||
assert len(drone.output_list) == 1
|
||||
return drone.output_list.pop() == 1
|
||||
|
||||
|
||||
def main() -> None:
|
||||
memory = [int(n) for n in sys.stdin.read().split(",")]
|
||||
|
||||
x = 0
|
||||
y = 0
|
||||
size = 100
|
||||
while not true_at(memory, x + size - 1, y):
|
||||
y += 1
|
||||
while not true_at(memory, x, y + size - 1):
|
||||
x += 1
|
||||
print((x * 10000 + y))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1
2019/d19/ex2/input
Normal file
1
2019/d19/ex2/input
Normal file
|
@ -0,0 +1 @@
|
|||
109,424,203,1,21102,11,1,0,1106,0,282,21102,18,1,0,1106,0,259,1201,1,0,221,203,1,21102,31,1,0,1106,0,282,21101,38,0,0,1106,0,259,21002,23,1,2,22102,1,1,3,21101,1,0,1,21102,57,1,0,1105,1,303,2102,1,1,222,20101,0,221,3,20101,0,221,2,21102,259,1,1,21101,80,0,0,1106,0,225,21101,0,44,2,21102,91,1,0,1105,1,303,1201,1,0,223,20101,0,222,4,21101,0,259,3,21102,225,1,2,21101,225,0,1,21102,118,1,0,1105,1,225,21002,222,1,3,21101,100,0,2,21101,133,0,0,1105,1,303,21202,1,-1,1,22001,223,1,1,21101,148,0,0,1106,0,259,2102,1,1,223,20102,1,221,4,21002,222,1,3,21102,1,12,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21102,1,195,0,106,0,108,20207,1,223,2,21002,23,1,1,21102,-1,1,3,21101,0,214,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,2102,1,-4,249,21201,-3,0,1,22101,0,-2,2,22101,0,-1,3,21101,0,250,0,1105,1,225,22102,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,21202,-2,1,-2,109,-3,2105,1,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22102,1,-2,3,21101,0,343,0,1105,1,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21201,-4,0,1,21101,0,384,0,1106,0,303,1106,0,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,22102,1,1,-4,109,-5,2106,0,0
|
17
2020/d01/ex1/ex1.py
Executable file
17
2020/d01/ex1/ex1.py
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
import functools
|
||||
import itertools
|
||||
import operator
|
||||
import sys
|
||||
|
||||
|
||||
def main() -> None:
|
||||
values = [int(n) for n in sys.stdin.readlines()]
|
||||
for tup in itertools.combinations(values, 2):
|
||||
if sum(tup) == 2020:
|
||||
print(functools.reduce(operator.mul, tup))
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
200
2020/d01/ex1/input
Normal file
200
2020/d01/ex1/input
Normal file
|
@ -0,0 +1,200 @@
|
|||
1742
|
||||
1763
|
||||
1238
|
||||
1424
|
||||
1736
|
||||
1903
|
||||
1580
|
||||
1847
|
||||
1860
|
||||
1933
|
||||
1779
|
||||
1901
|
||||
1984
|
||||
1861
|
||||
1769
|
||||
1896
|
||||
1428
|
||||
2010
|
||||
1673
|
||||
1491
|
||||
1996
|
||||
1746
|
||||
1973
|
||||
1696
|
||||
1616
|
||||
2006
|
||||
1890
|
||||
1600
|
||||
1991
|
||||
1724
|
||||
1804
|
||||
1794
|
||||
462
|
||||
1706
|
||||
2002
|
||||
1939
|
||||
1834
|
||||
1312
|
||||
1943
|
||||
1465
|
||||
1405
|
||||
1459
|
||||
1659
|
||||
1288
|
||||
1241
|
||||
1935
|
||||
1294
|
||||
1388
|
||||
1772
|
||||
1945
|
||||
1649
|
||||
813
|
||||
1956
|
||||
1274
|
||||
1686
|
||||
1404
|
||||
1770
|
||||
1631
|
||||
1366
|
||||
1321
|
||||
1353
|
||||
1685
|
||||
1365
|
||||
1738
|
||||
1911
|
||||
1235
|
||||
1495
|
||||
1837
|
||||
1456
|
||||
1283
|
||||
1929
|
||||
1326
|
||||
1735
|
||||
1604
|
||||
1223
|
||||
1261
|
||||
1844
|
||||
1850
|
||||
1429
|
||||
277
|
||||
1848
|
||||
1818
|
||||
1395
|
||||
1522
|
||||
1863
|
||||
1475
|
||||
1562
|
||||
1351
|
||||
1538
|
||||
1313
|
||||
1416
|
||||
1690
|
||||
1539
|
||||
1338
|
||||
1982
|
||||
1297
|
||||
1821
|
||||
780
|
||||
1859
|
||||
1420
|
||||
1934
|
||||
1303
|
||||
1731
|
||||
1714
|
||||
1702
|
||||
1417
|
||||
1872
|
||||
1998
|
||||
1908
|
||||
1957
|
||||
1270
|
||||
1359
|
||||
1760
|
||||
1997
|
||||
1773
|
||||
2000
|
||||
1203
|
||||
1880
|
||||
1955
|
||||
1273
|
||||
1775
|
||||
1893
|
||||
1237
|
||||
1707
|
||||
1885
|
||||
1900
|
||||
1801
|
||||
1367
|
||||
1561
|
||||
1524
|
||||
1678
|
||||
1511
|
||||
1623
|
||||
1464
|
||||
1477
|
||||
1733
|
||||
1423
|
||||
1575
|
||||
1851
|
||||
2007
|
||||
1651
|
||||
804
|
||||
1836
|
||||
1849
|
||||
1713
|
||||
1401
|
||||
1502
|
||||
1806
|
||||
1506
|
||||
1646
|
||||
1968
|
||||
1253
|
||||
1889
|
||||
1759
|
||||
1734
|
||||
1611
|
||||
1558
|
||||
1256
|
||||
1657
|
||||
1778
|
||||
1953
|
||||
1578
|
||||
1717
|
||||
1498
|
||||
1381
|
||||
1919
|
||||
1512
|
||||
1391
|
||||
384
|
||||
1802
|
||||
1573
|
||||
1940
|
||||
1323
|
||||
2003
|
||||
1689
|
||||
1936
|
||||
1368
|
||||
1962
|
||||
1964
|
||||
1586
|
||||
1619
|
||||
1482
|
||||
1445
|
||||
372
|
||||
1792
|
||||
96
|
||||
1468
|
||||
1999
|
||||
1301
|
||||
1757
|
||||
1613
|
||||
1807
|
||||
1941
|
||||
1642
|
||||
1557
|
||||
1884
|
||||
1626
|
||||
489
|
||||
1989
|
||||
1327
|
17
2020/d01/ex2/ex2.py
Executable file
17
2020/d01/ex2/ex2.py
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
import functools
|
||||
import itertools
|
||||
import operator
|
||||
import sys
|
||||
|
||||
|
||||
def main() -> None:
|
||||
values = [int(n) for n in sys.stdin.readlines()]
|
||||
for tup in itertools.combinations(values, 3):
|
||||
if sum(tup) == 2020:
|
||||
print(functools.reduce(operator.mul, tup))
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
200
2020/d01/ex2/input
Normal file
200
2020/d01/ex2/input
Normal file
|
@ -0,0 +1,200 @@
|
|||
1742
|
||||
1763
|
||||
1238
|
||||
1424
|
||||
1736
|
||||
1903
|
||||
1580
|
||||
1847
|
||||
1860
|
||||
1933
|
||||
1779
|
||||
1901
|
||||
1984
|
||||
1861
|
||||
1769
|
||||
1896
|
||||
1428
|
||||
2010
|
||||
1673
|
||||
1491
|
||||
1996
|
||||
1746
|
||||
1973
|
||||
1696
|
||||
1616
|
||||
2006
|
||||
1890
|
||||
1600
|
||||
1991
|
||||
1724
|
||||
1804
|
||||
1794
|
||||
462
|
||||
1706
|
||||
2002
|
||||
1939
|
||||
1834
|
||||
1312
|
||||
1943
|
||||
1465
|
||||
1405
|
||||
1459
|
||||
1659
|
||||
1288
|
||||
1241
|
||||
1935
|
||||
1294
|
||||
1388
|
||||
1772
|
||||
1945
|
||||
1649
|
||||
813
|
||||
1956
|
||||
1274
|
||||
1686
|
||||
1404
|
||||
1770
|
||||
1631
|
||||
1366
|
||||
1321
|
||||
1353
|
||||
1685
|
||||
1365
|
||||
1738
|
||||
1911
|
||||
1235
|
||||
1495
|
||||
1837
|
||||
1456
|
||||
1283
|
||||
1929
|
||||
1326
|
||||
1735
|
||||
1604
|
||||
1223
|
||||
1261
|
||||
1844
|
||||
1850
|
||||
1429
|
||||
277
|
||||
1848
|
||||
1818
|
||||
1395
|
||||
1522
|
||||
1863
|
||||
1475
|
||||
1562
|
||||
1351
|
||||
1538
|
||||
1313
|
||||
1416
|
||||
1690
|
||||
1539
|
||||
1338
|
||||
1982
|
||||
1297
|
||||
1821
|
||||
780
|
||||
1859
|
||||
1420
|
||||
1934
|
||||
1303
|
||||
1731
|
||||
1714
|
||||
1702
|
||||
1417
|
||||
1872
|
||||
1998
|
||||
1908
|
||||
1957
|
||||
1270
|
||||
1359
|
||||
1760
|
||||
1997
|
||||
1773
|
||||
2000
|
||||
1203
|
||||
1880
|
||||
1955
|
||||
1273
|
||||
1775
|
||||
1893
|
||||
1237
|
||||
1707
|
||||
1885
|
||||
1900
|
||||
1801
|
||||
1367
|
||||
1561
|
||||
1524
|
||||
1678
|
||||
1511
|
||||
1623
|
||||
1464
|
||||
1477
|
||||
1733
|
||||
1423
|
||||
1575
|
||||
1851
|
||||
2007
|
||||
1651
|
||||
804
|
||||
1836
|
||||
1849
|
||||
1713
|
||||
1401
|
||||
1502
|
||||
1806
|
||||
1506
|
||||
1646
|
||||
1968
|
||||
1253
|
||||
1889
|
||||
1759
|
||||
1734
|
||||
1611
|
||||
1558
|
||||
1256
|
||||
1657
|
||||
1778
|
||||
1953
|
||||
1578
|
||||
1717
|
||||
1498
|
||||
1381
|
||||
1919
|
||||
1512
|
||||
1391
|
||||
384
|
||||
1802
|
||||
1573
|
||||
1940
|
||||
1323
|
||||
2003
|
||||
1689
|
||||
1936
|
||||
1368
|
||||
1962
|
||||
1964
|
||||
1586
|
||||
1619
|
||||
1482
|
||||
1445
|
||||
372
|
||||
1792
|
||||
96
|
||||
1468
|
||||
1999
|
||||
1301
|
||||
1757
|
||||
1613
|
||||
1807
|
||||
1941
|
||||
1642
|
||||
1557
|
||||
1884
|
||||
1626
|
||||
489
|
||||
1989
|
||||
1327
|
42
2020/d02/ex1/ex1.py
Executable file
42
2020/d02/ex1/ex1.py
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
|
||||
@dataclass
|
||||
class Policy:
|
||||
min: int
|
||||
max: int
|
||||
letter: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Password:
|
||||
policy: Policy
|
||||
password: str
|
||||
|
||||
|
||||
def is_valid(pwd: Password) -> bool:
|
||||
occurences = pwd.password.count(pwd.policy.letter)
|
||||
return pwd.policy.min <= occurences <= pwd.policy.max
|
||||
|
||||
|
||||
def solve(passwords: List[Password]) -> int:
|
||||
return sum(map(is_valid, passwords))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
pattern = re.compile("([0-9]+)-([0-9]+) (.): (.+)")
|
||||
input = [
|
||||
Password(Policy(int(m.group(1)), int(m.group(2)), m.group(3)), m.group(4))
|
||||
for m in (pattern.match(line) for line in sys.stdin.readlines())
|
||||
if m
|
||||
]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1000
2020/d02/ex1/input
Normal file
1000
2020/d02/ex1/input
Normal file
File diff suppressed because it is too large
Load diff
43
2020/d02/ex2/ex2.py
Executable file
43
2020/d02/ex2/ex2.py
Executable file
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
|
||||
@dataclass
|
||||
class Policy:
|
||||
min: int
|
||||
max: int
|
||||
letter: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Password:
|
||||
policy: Policy
|
||||
password: str
|
||||
|
||||
|
||||
def is_valid(pwd: Password) -> bool:
|
||||
min = pwd.password[pwd.policy.min - 1] == pwd.policy.letter
|
||||
max = pwd.password[pwd.policy.max - 1] == pwd.policy.letter
|
||||
return min ^ max
|
||||
|
||||
|
||||
def solve(passwords: List[Password]) -> int:
|
||||
return sum(map(is_valid, passwords))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
pattern = re.compile("([0-9]+)-([0-9]+) (.): (.+)")
|
||||
input = [
|
||||
Password(Policy(int(m.group(1)), int(m.group(2)), m.group(3)), m.group(4))
|
||||
for m in (pattern.match(line) for line in sys.stdin.readlines())
|
||||
if m
|
||||
]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1000
2020/d02/ex2/input
Normal file
1000
2020/d02/ex2/input
Normal file
File diff suppressed because it is too large
Load diff
25
2020/d03/ex1/ex1.py
Executable file
25
2020/d03/ex1/ex1.py
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
def solve(trees: List[str], delta: Tuple[int, int]) -> int:
|
||||
x, y = 0, 0
|
||||
sum = 0
|
||||
while True:
|
||||
x += delta[0]
|
||||
y += delta[1]
|
||||
if y >= len(trees):
|
||||
break
|
||||
sum += trees[y][x % len(trees[0])] == "#"
|
||||
return sum
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input, (3, 1)))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
323
2020/d03/ex1/input
Normal file
323
2020/d03/ex1/input
Normal file
|
@ -0,0 +1,323 @@
|
|||
...............#.#.............
|
||||
##..#....................#...##
|
||||
......#..#.#.....#..#.#.##.....
|
||||
.........#...#..............#.#
|
||||
............#.......##.........
|
||||
...#.....#.....#...#.....#..#..
|
||||
..............#..##.#..#......#
|
||||
.##.....#.....#......##.#......
|
||||
.#..........###....#...##....#.
|
||||
.....#....#.#.......#......##..
|
||||
.#....#......#.......#........#
|
||||
..#.#.......#..##.....##.......
|
||||
...#.#....#.......#.......#...#
|
||||
##.##...##..#......#.#.....#..#
|
||||
.#.#.......#..#.#......#...#.#.
|
||||
#.......##.......#...#.........
|
||||
.....#......#.#.#.....#....##..
|
||||
.#.#........#....#..#..#.......
|
||||
...#....#..###.........#.....#.
|
||||
........#........#........#....
|
||||
..##..............#.....#.#..#.
|
||||
.#...##.............#.#........
|
||||
....#..#...........#.......#...
|
||||
..#....#.....................#.
|
||||
#.#..................##......##
|
||||
.#.##....#......#........#.....
|
||||
.........##.....#....#...##..#.
|
||||
#..........#..#.#.............#
|
||||
.........#...#.#.#.#..##..##...
|
||||
#...#.....#..#..#....#...#.....
|
||||
..##.....#..................#..
|
||||
#..###.....#....#.......#..#...
|
||||
...##.##..#............#......#
|
||||
........###.........###......#.
|
||||
#..##....#.........#.........#.
|
||||
....#.....................#....
|
||||
#..#..##..#..####.##..#.....##.
|
||||
..#...#.#....#....##.....#.....
|
||||
...#.#.........#.....#.#.......
|
||||
....#................#..#...##.
|
||||
....#..#..........#...#.#.##...
|
||||
........#..##............#....#
|
||||
...#......##..........#.##...#.
|
||||
.......##......................
|
||||
.......##..........#....#.#...#
|
||||
......###.##..##..#....#...#..#
|
||||
#.#...........##.....#........#
|
||||
..#...........#..###....#.#.#..
|
||||
........#...........#......##..
|
||||
.........#...##.###...###..#...
|
||||
.....#.....#..##.........##....
|
||||
...##..............#.....#...##
|
||||
.##....#.......###.....#.......
|
||||
.#...........##.............##.
|
||||
......#..#..##.##......#......#
|
||||
........###........#......#.#..
|
||||
#.#....#.....#........#......#.
|
||||
.##..#.........##...##....#....
|
||||
.....#.........#...##.....#....
|
||||
.............#........###....#.
|
||||
......#.......#.#........#.#...
|
||||
..#....#.#...#....#...#.#...##.
|
||||
#...#......##..##......#.##.###
|
||||
...##.#....#...#....#.........#
|
||||
...#..####.....##.#..#.#...##..
|
||||
##.#..#....##......#......##...
|
||||
###.........#.#..#.#.....#.....
|
||||
...#........#..##...#.#.#..#.#.
|
||||
...###..#.###.#...#............
|
||||
....................###........
|
||||
...........#...........#.......
|
||||
#..............#.#.........###.
|
||||
....................##.....#..#
|
||||
#.#.....#.......#...#..........
|
||||
.#...#......#....##...#...#....
|
||||
.....#.##..................###.
|
||||
.........#.#..#.#......#.......
|
||||
.......#.....##..#.##.#........
|
||||
..#..........#.###.....#....#..
|
||||
......#.............#.#........
|
||||
........##....#........#.......
|
||||
...#.............#....#.#......
|
||||
#........#..####.....#.....#.#.
|
||||
.##......##...#........#..#.#..
|
||||
....##....#...#...#..##...#.#..
|
||||
#.##...###..#....##.#..........
|
||||
....#.#...#.#...#..##.###...#..
|
||||
#.....##..#..#....#.#.....##...
|
||||
.#..#..........##.#.....##.....
|
||||
.#..#........#.#.#.#...........
|
||||
.#..#.....#...........#...#....
|
||||
...#......##..........##..#....
|
||||
...#..#....#.##...#..#.....###.
|
||||
#.#....#.....##................
|
||||
#..#......#.#.#.......#........
|
||||
......#....#.#....#..##....#..#
|
||||
.#.....#.#....###.##.........#.
|
||||
.###..#.....#........#.#.......
|
||||
.#...#......#..#.#......#.....#
|
||||
#...............####...#.....#.
|
||||
.......#..........##.#........#
|
||||
#........##....##.....###..##..
|
||||
#..#.....#..##.....#....#..#...
|
||||
#.....#.......##......#.#.....#
|
||||
#.##..#......##..#.............
|
||||
##...#.....#........##.........
|
||||
....#..##....#...#.......#.#...
|
||||
....#...#...##..#....#..#...#..
|
||||
..............#.#...#....###...
|
||||
...#....#..##...##..#....##....
|
||||
#.##.#..#..#......#.#.#.#...#..
|
||||
.......#..#..##........#......#
|
||||
##.#....#....##.#......##.#....
|
||||
.#...#..............#........#.
|
||||
.#.#....#.........#............
|
||||
.#..#..###.............#....#..
|
||||
#......#...#.#..##..#...#....#.
|
||||
.......................#...#.#.
|
||||
.............#..#...##.........
|
||||
..#.#..#....#....#........#....
|
||||
#......#.##..#...#.#...........
|
||||
.....#....#...........##.#..#..
|
||||
..#.#.....#..............#.#...
|
||||
#.......#.....#................
|
||||
#..............#...#....#...#..
|
||||
...#...##..#..#............#...
|
||||
......###.....................#
|
||||
.........#.......##..#....#....
|
||||
........#...#.##..#.##......#..
|
||||
....###..#.#...#...#..#.#...###
|
||||
##...#...##.#...#.#...#.#....#.
|
||||
.........#...#.....###.........
|
||||
...#........##..#.......##.....
|
||||
.#.......##.........#.....##..#
|
||||
.#..................#...#......
|
||||
.##..#..#.#.....#.###..........
|
||||
...#.....##..#.........#...#...
|
||||
.#......#.#.......#.#..........
|
||||
.........#.#...#..........#.#..
|
||||
#..........#.##..#.##....#.....
|
||||
.#.#....#.....#..##.....#...#..
|
||||
..#........##...##..#..#....#..
|
||||
#...........##....#..###....#..
|
||||
...........##.........####...#.
|
||||
..#........###...#.#.........#.
|
||||
.#...............#.##.#.#...#..
|
||||
.#.##..#.....#.#.....##..#.....
|
||||
...#...#..#.##.##...#.......##.
|
||||
..#...#...#......##.##.##...#..
|
||||
##....#...#...#...............#
|
||||
...##...........#......#..#.#..
|
||||
#.........#......#.#.##.....#..
|
||||
........#..#.........##........
|
||||
..#.#....###.....##..#...#.....
|
||||
.........#...#.......#.....##..
|
||||
##.....................#...##..
|
||||
.#.#..#......#.................
|
||||
.....###..#......#..###..#.....
|
||||
...#.....##.........#......#..#
|
||||
......##.....#...#........#.#..
|
||||
..#.#...#......#...#.##.##.....
|
||||
...#..........#...#.......#..##
|
||||
.###........#........##........
|
||||
..#.#.#..........#.#...##......
|
||||
.........#........#......###..#
|
||||
....##..#.........#...........#
|
||||
..####..#............##.......#
|
||||
.....##.#..##.........#...#.#..
|
||||
...#.........#.....#.....#.....
|
||||
.......#...#..#...##.........#.
|
||||
...#...#..#...#....#..#........
|
||||
#............##.##...#.........
|
||||
.#.#.....#.......####.....#....
|
||||
..............#......#.#.......
|
||||
..............#...........#...#
|
||||
#...#........###....#.#....#.#.
|
||||
##.#..#..#......#......#.#.#...
|
||||
.#..#.....#..#.#..#.#.......##.
|
||||
......##.#...#...#......#...#..
|
||||
#...........##....#.#..........
|
||||
....#.......###.#...#..........
|
||||
.......................#.....#.
|
||||
........#...#..#...#.#.#.#.#...
|
||||
.#.#...........#......##...#...
|
||||
.........................#.....
|
||||
.................#.##.#...##...
|
||||
...#...##.....#.....##....#.#..
|
||||
...#...#...................#...
|
||||
...#..#..#...#...#....#........
|
||||
#....#...#.....#...............
|
||||
.......#...........#...#.......
|
||||
....#....#.....##.......#......
|
||||
.......#..........##...........
|
||||
.#.#........#..##....#......#..
|
||||
.....#.......#.#.........#...#.
|
||||
.#..####.#.#...............#..#
|
||||
.....###..#..#..........#.#..##
|
||||
..#.......#...#.....##..#..#.#.
|
||||
#....#......#..................
|
||||
........#.##.#....#...........#
|
||||
....#.#....##..#.#.....##......
|
||||
...#..#.......#....#.....#.#.#.
|
||||
#...#......#.....#.#..........#
|
||||
....#....#...............#.....
|
||||
..###......................###.
|
||||
.##....#..#.......###.....#..#.
|
||||
..###............#........#.##.
|
||||
.#........#......#.....#..#....
|
||||
....#..##...#...#.###.......#.#
|
||||
.......#.##...........#.#..#...
|
||||
.....#...##....................
|
||||
....#....#...##......#.........
|
||||
..#............##....###.#...#.
|
||||
.#........#...............#....
|
||||
#..#.#.##.........#..##....##..
|
||||
#.#....#..#.##....##...#.#.....
|
||||
.....#.....##....#.#........#..
|
||||
#..#...#...#....#....#.........
|
||||
...#........#..#.#.....##......
|
||||
..#...#...#................##..
|
||||
#........#.#.##.......#.#...#..
|
||||
#......#..####.##.....#.#..#.#.
|
||||
............#..#.#....#......##
|
||||
..#.....##....#...#.#..........
|
||||
...#...#.........#...#.#.......
|
||||
.###..#.......##.##.....#.#.#..
|
||||
...#....#...............##.#...
|
||||
....##..#..#..#.#......##.....#
|
||||
#.#..............##...##...####
|
||||
.....#.##...#.#...............#
|
||||
.##.....#.........#.......#.#.#
|
||||
#.#..#.....#.......#.......#..#
|
||||
...#.#.....#.....#......#......
|
||||
.......#....#..#.#..........#..
|
||||
......#......#.##...#..........
|
||||
.....#.......###...#...#.#.....
|
||||
#..#.#.........#.....#.##....#.
|
||||
..#.#.........#..#..#..#.....#.
|
||||
.#..##..#..#....#......#.##..#.
|
||||
...##......###.....#.##.##.....
|
||||
.#.....#...#..#...#............
|
||||
##..##..#.##....#..#...........
|
||||
...#..##..#..#.............#.##
|
||||
...............##............#.
|
||||
..#.....##........##.#...#....#
|
||||
.#.#...#.#.#..#.#.....#....#...
|
||||
.#....#...............#..#.....
|
||||
....#.##..#....#......#...###..
|
||||
#................###...#.#.....
|
||||
...#...#......##..#.#....#.....
|
||||
.#....#....#.#...##............
|
||||
....#...##..#..#........#.##...
|
||||
..##.....#..#..##..............
|
||||
..#..##..#.#..##....#....#....#
|
||||
...##.............#............
|
||||
#....#....#.#........#.....##.#
|
||||
.....#..#.#.....####...###.....
|
||||
................#......#.......
|
||||
.....#.#.#.#.#....#..#........#
|
||||
.##.#...#.#.......##....#....#.
|
||||
.....#........#................
|
||||
..#.....#..#...#..#...........#
|
||||
.#.....#...##.....##..#.#....##
|
||||
......#.......#..#......##.#...
|
||||
#.#..........#.##.#........#...
|
||||
...#..#.............#..........
|
||||
#..#..#..........#..##.#.......
|
||||
.#..#...............####..#....
|
||||
.......#.....#......#.....#.#..
|
||||
.#...............#...#.........
|
||||
.#..#..........#..#.#..##..#..#
|
||||
......##..#.....#..#......###..
|
||||
..........#...#..#.......#.....
|
||||
.#.#.#..#.....#.##.#...#..#....
|
||||
........#.......#.....#.#......
|
||||
......#.....##.....#....##.#...
|
||||
...............#......#.......#
|
||||
..#.#...#.....#.#...##......#..
|
||||
#.#.........#.#...#........####
|
||||
#..........##..#..#........##..
|
||||
.............#..#.......##.#..#
|
||||
..#........#.#....#........#.#.
|
||||
.#......####..#..#.............
|
||||
............###.......#.#..#...
|
||||
#.##......##...#...#.........#.
|
||||
....##.#.#.#......#....#..#...#
|
||||
.#..#.#....#...#.........#.....
|
||||
#...#.....##............#...#..
|
||||
#.#...#..#.................#...
|
||||
............#.#..#.....#.#.#..#
|
||||
...................#....#.##...
|
||||
.....#...#.#....#....#.#......#
|
||||
.......##.#.#......##..........
|
||||
.#..#...##.#...#..#......#.....
|
||||
......#.#..#..###..##..##......
|
||||
.#.#.#.#.....#...###.....#..#..
|
||||
.#....#.....#.......#.......#..
|
||||
..........##.........####......
|
||||
.#.#.............#..#.#...#....
|
||||
........#........##...#.#....#.
|
||||
........#......................
|
||||
..#.#....#...............#...##
|
||||
.......#.#...#..#.....##......#
|
||||
.#...#....#..........##........
|
||||
.#.........#.#............##...
|
||||
.....#......##...#.......#..#..
|
||||
#.#..#.............#...#...#...
|
||||
......#.......#............#...
|
||||
...........##....#......##.....
|
||||
.#.#..#.....................#..
|
||||
##..##.....###..##.#...........
|
||||
...##......##....#...##.....#..
|
||||
#...#.##.............#.........
|
||||
......#..#.........###.#......#
|
||||
#.#.....#.....................#
|
||||
....#####.....##........#.#..#.
|
||||
...........##..##.###..........
|
||||
..........##.....#........#...#
|
||||
.......#..#......#.....##..##.#
|
||||
.....##.#........#.........#...
|
||||
......##......................#
|
||||
.#.......#.#.#............#..#.
|
||||
.....##.#.......#.#........#...
|
33
2020/d03/ex2/ex2.py
Executable file
33
2020/d03/ex2/ex2.py
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from math import prod
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
def solve(trees: List[str], delta: Tuple[int, int]) -> int:
|
||||
x, y = 0, 0
|
||||
sum = 0
|
||||
while True:
|
||||
x += delta[0]
|
||||
y += delta[1]
|
||||
if y >= len(trees):
|
||||
break
|
||||
sum += trees[y][x % len(trees[0])] == "#"
|
||||
return sum
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
deltas = [
|
||||
(1, 1),
|
||||
(3, 1),
|
||||
(5, 1),
|
||||
(7, 1),
|
||||
(1, 2),
|
||||
]
|
||||
print(prod(solve(input, delt) for delt in deltas))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
323
2020/d03/ex2/input
Normal file
323
2020/d03/ex2/input
Normal file
|
@ -0,0 +1,323 @@
|
|||
...............#.#.............
|
||||
##..#....................#...##
|
||||
......#..#.#.....#..#.#.##.....
|
||||
.........#...#..............#.#
|
||||
............#.......##.........
|
||||
...#.....#.....#...#.....#..#..
|
||||
..............#..##.#..#......#
|
||||
.##.....#.....#......##.#......
|
||||
.#..........###....#...##....#.
|
||||
.....#....#.#.......#......##..
|
||||
.#....#......#.......#........#
|
||||
..#.#.......#..##.....##.......
|
||||
...#.#....#.......#.......#...#
|
||||
##.##...##..#......#.#.....#..#
|
||||
.#.#.......#..#.#......#...#.#.
|
||||
#.......##.......#...#.........
|
||||
.....#......#.#.#.....#....##..
|
||||
.#.#........#....#..#..#.......
|
||||
...#....#..###.........#.....#.
|
||||
........#........#........#....
|
||||
..##..............#.....#.#..#.
|
||||
.#...##.............#.#........
|
||||
....#..#...........#.......#...
|
||||
..#....#.....................#.
|
||||
#.#..................##......##
|
||||
.#.##....#......#........#.....
|
||||
.........##.....#....#...##..#.
|
||||
#..........#..#.#.............#
|
||||
.........#...#.#.#.#..##..##...
|
||||
#...#.....#..#..#....#...#.....
|
||||
..##.....#..................#..
|
||||
#..###.....#....#.......#..#...
|
||||
...##.##..#............#......#
|
||||
........###.........###......#.
|
||||
#..##....#.........#.........#.
|
||||
....#.....................#....
|
||||
#..#..##..#..####.##..#.....##.
|
||||
..#...#.#....#....##.....#.....
|
||||
...#.#.........#.....#.#.......
|
||||
....#................#..#...##.
|
||||
....#..#..........#...#.#.##...
|
||||
........#..##............#....#
|
||||
...#......##..........#.##...#.
|
||||
.......##......................
|
||||
.......##..........#....#.#...#
|
||||
......###.##..##..#....#...#..#
|
||||
#.#...........##.....#........#
|
||||
..#...........#..###....#.#.#..
|
||||
........#...........#......##..
|
||||
.........#...##.###...###..#...
|
||||
.....#.....#..##.........##....
|
||||
...##..............#.....#...##
|
||||
.##....#.......###.....#.......
|
||||
.#...........##.............##.
|
||||
......#..#..##.##......#......#
|
||||
........###........#......#.#..
|
||||
#.#....#.....#........#......#.
|
||||
.##..#.........##...##....#....
|
||||
.....#.........#...##.....#....
|
||||
.............#........###....#.
|
||||
......#.......#.#........#.#...
|
||||
..#....#.#...#....#...#.#...##.
|
||||
#...#......##..##......#.##.###
|
||||
...##.#....#...#....#.........#
|
||||
...#..####.....##.#..#.#...##..
|
||||
##.#..#....##......#......##...
|
||||
###.........#.#..#.#.....#.....
|
||||
...#........#..##...#.#.#..#.#.
|
||||
...###..#.###.#...#............
|
||||
....................###........
|
||||
...........#...........#.......
|
||||
#..............#.#.........###.
|
||||
....................##.....#..#
|
||||
#.#.....#.......#...#..........
|
||||
.#...#......#....##...#...#....
|
||||
.....#.##..................###.
|
||||
.........#.#..#.#......#.......
|
||||
.......#.....##..#.##.#........
|
||||
..#..........#.###.....#....#..
|
||||
......#.............#.#........
|
||||
........##....#........#.......
|
||||
...#.............#....#.#......
|
||||
#........#..####.....#.....#.#.
|
||||
.##......##...#........#..#.#..
|
||||
....##....#...#...#..##...#.#..
|
||||
#.##...###..#....##.#..........
|
||||
....#.#...#.#...#..##.###...#..
|
||||
#.....##..#..#....#.#.....##...
|
||||
.#..#..........##.#.....##.....
|
||||
.#..#........#.#.#.#...........
|
||||
.#..#.....#...........#...#....
|
||||
...#......##..........##..#....
|
||||
...#..#....#.##...#..#.....###.
|
||||
#.#....#.....##................
|
||||
#..#......#.#.#.......#........
|
||||
......#....#.#....#..##....#..#
|
||||
.#.....#.#....###.##.........#.
|
||||
.###..#.....#........#.#.......
|
||||
.#...#......#..#.#......#.....#
|
||||
#...............####...#.....#.
|
||||
.......#..........##.#........#
|
||||
#........##....##.....###..##..
|
||||
#..#.....#..##.....#....#..#...
|
||||
#.....#.......##......#.#.....#
|
||||
#.##..#......##..#.............
|
||||
##...#.....#........##.........
|
||||
....#..##....#...#.......#.#...
|
||||
....#...#...##..#....#..#...#..
|
||||
..............#.#...#....###...
|
||||
...#....#..##...##..#....##....
|
||||
#.##.#..#..#......#.#.#.#...#..
|
||||
.......#..#..##........#......#
|
||||
##.#....#....##.#......##.#....
|
||||
.#...#..............#........#.
|
||||
.#.#....#.........#............
|
||||
.#..#..###.............#....#..
|
||||
#......#...#.#..##..#...#....#.
|
||||
.......................#...#.#.
|
||||
.............#..#...##.........
|
||||
..#.#..#....#....#........#....
|
||||
#......#.##..#...#.#...........
|
||||
.....#....#...........##.#..#..
|
||||
..#.#.....#..............#.#...
|
||||
#.......#.....#................
|
||||
#..............#...#....#...#..
|
||||
...#...##..#..#............#...
|
||||
......###.....................#
|
||||
.........#.......##..#....#....
|
||||
........#...#.##..#.##......#..
|
||||
....###..#.#...#...#..#.#...###
|
||||
##...#...##.#...#.#...#.#....#.
|
||||
.........#...#.....###.........
|
||||
...#........##..#.......##.....
|
||||
.#.......##.........#.....##..#
|
||||
.#..................#...#......
|
||||
.##..#..#.#.....#.###..........
|
||||
...#.....##..#.........#...#...
|
||||
.#......#.#.......#.#..........
|
||||
.........#.#...#..........#.#..
|
||||
#..........#.##..#.##....#.....
|
||||
.#.#....#.....#..##.....#...#..
|
||||
..#........##...##..#..#....#..
|
||||
#...........##....#..###....#..
|
||||
...........##.........####...#.
|
||||
..#........###...#.#.........#.
|
||||
.#...............#.##.#.#...#..
|
||||
.#.##..#.....#.#.....##..#.....
|
||||
...#...#..#.##.##...#.......##.
|
||||
..#...#...#......##.##.##...#..
|
||||
##....#...#...#...............#
|
||||
...##...........#......#..#.#..
|
||||
#.........#......#.#.##.....#..
|
||||
........#..#.........##........
|
||||
..#.#....###.....##..#...#.....
|
||||
.........#...#.......#.....##..
|
||||
##.....................#...##..
|
||||
.#.#..#......#.................
|
||||
.....###..#......#..###..#.....
|
||||
...#.....##.........#......#..#
|
||||
......##.....#...#........#.#..
|
||||
..#.#...#......#...#.##.##.....
|
||||
...#..........#...#.......#..##
|
||||
.###........#........##........
|
||||
..#.#.#..........#.#...##......
|
||||
.........#........#......###..#
|
||||
....##..#.........#...........#
|
||||
..####..#............##.......#
|
||||
.....##.#..##.........#...#.#..
|
||||
...#.........#.....#.....#.....
|
||||
.......#...#..#...##.........#.
|
||||
...#...#..#...#....#..#........
|
||||
#............##.##...#.........
|
||||
.#.#.....#.......####.....#....
|
||||
..............#......#.#.......
|
||||
..............#...........#...#
|
||||
#...#........###....#.#....#.#.
|
||||
##.#..#..#......#......#.#.#...
|
||||
.#..#.....#..#.#..#.#.......##.
|
||||
......##.#...#...#......#...#..
|
||||
#...........##....#.#..........
|
||||
....#.......###.#...#..........
|
||||
.......................#.....#.
|
||||
........#...#..#...#.#.#.#.#...
|
||||
.#.#...........#......##...#...
|
||||
.........................#.....
|
||||
.................#.##.#...##...
|
||||
...#...##.....#.....##....#.#..
|
||||
...#...#...................#...
|
||||
...#..#..#...#...#....#........
|
||||
#....#...#.....#...............
|
||||
.......#...........#...#.......
|
||||
....#....#.....##.......#......
|
||||
.......#..........##...........
|
||||
.#.#........#..##....#......#..
|
||||
.....#.......#.#.........#...#.
|
||||
.#..####.#.#...............#..#
|
||||
.....###..#..#..........#.#..##
|
||||
..#.......#...#.....##..#..#.#.
|
||||
#....#......#..................
|
||||
........#.##.#....#...........#
|
||||
....#.#....##..#.#.....##......
|
||||
...#..#.......#....#.....#.#.#.
|
||||
#...#......#.....#.#..........#
|
||||
....#....#...............#.....
|
||||
..###......................###.
|
||||
.##....#..#.......###.....#..#.
|
||||
..###............#........#.##.
|
||||
.#........#......#.....#..#....
|
||||
....#..##...#...#.###.......#.#
|
||||
.......#.##...........#.#..#...
|
||||
.....#...##....................
|
||||
....#....#...##......#.........
|
||||
..#............##....###.#...#.
|
||||
.#........#...............#....
|
||||
#..#.#.##.........#..##....##..
|
||||
#.#....#..#.##....##...#.#.....
|
||||
.....#.....##....#.#........#..
|
||||
#..#...#...#....#....#.........
|
||||
...#........#..#.#.....##......
|
||||
..#...#...#................##..
|
||||
#........#.#.##.......#.#...#..
|
||||
#......#..####.##.....#.#..#.#.
|
||||
............#..#.#....#......##
|
||||
..#.....##....#...#.#..........
|
||||
...#...#.........#...#.#.......
|
||||
.###..#.......##.##.....#.#.#..
|
||||
...#....#...............##.#...
|
||||
....##..#..#..#.#......##.....#
|
||||
#.#..............##...##...####
|
||||
.....#.##...#.#...............#
|
||||
.##.....#.........#.......#.#.#
|
||||
#.#..#.....#.......#.......#..#
|
||||
...#.#.....#.....#......#......
|
||||
.......#....#..#.#..........#..
|
||||
......#......#.##...#..........
|
||||
.....#.......###...#...#.#.....
|
||||
#..#.#.........#.....#.##....#.
|
||||
..#.#.........#..#..#..#.....#.
|
||||
.#..##..#..#....#......#.##..#.
|
||||
...##......###.....#.##.##.....
|
||||
.#.....#...#..#...#............
|
||||
##..##..#.##....#..#...........
|
||||
...#..##..#..#.............#.##
|
||||
...............##............#.
|
||||
..#.....##........##.#...#....#
|
||||
.#.#...#.#.#..#.#.....#....#...
|
||||
.#....#...............#..#.....
|
||||
....#.##..#....#......#...###..
|
||||
#................###...#.#.....
|
||||
...#...#......##..#.#....#.....
|
||||
.#....#....#.#...##............
|
||||
....#...##..#..#........#.##...
|
||||
..##.....#..#..##..............
|
||||
..#..##..#.#..##....#....#....#
|
||||
...##.............#............
|
||||
#....#....#.#........#.....##.#
|
||||
.....#..#.#.....####...###.....
|
||||
................#......#.......
|
||||
.....#.#.#.#.#....#..#........#
|
||||
.##.#...#.#.......##....#....#.
|
||||
.....#........#................
|
||||
..#.....#..#...#..#...........#
|
||||
.#.....#...##.....##..#.#....##
|
||||
......#.......#..#......##.#...
|
||||
#.#..........#.##.#........#...
|
||||
...#..#.............#..........
|
||||
#..#..#..........#..##.#.......
|
||||
.#..#...............####..#....
|
||||
.......#.....#......#.....#.#..
|
||||
.#...............#...#.........
|
||||
.#..#..........#..#.#..##..#..#
|
||||
......##..#.....#..#......###..
|
||||
..........#...#..#.......#.....
|
||||
.#.#.#..#.....#.##.#...#..#....
|
||||
........#.......#.....#.#......
|
||||
......#.....##.....#....##.#...
|
||||
...............#......#.......#
|
||||
..#.#...#.....#.#...##......#..
|
||||
#.#.........#.#...#........####
|
||||
#..........##..#..#........##..
|
||||
.............#..#.......##.#..#
|
||||
..#........#.#....#........#.#.
|
||||
.#......####..#..#.............
|
||||
............###.......#.#..#...
|
||||
#.##......##...#...#.........#.
|
||||
....##.#.#.#......#....#..#...#
|
||||
.#..#.#....#...#.........#.....
|
||||
#...#.....##............#...#..
|
||||
#.#...#..#.................#...
|
||||
............#.#..#.....#.#.#..#
|
||||
...................#....#.##...
|
||||
.....#...#.#....#....#.#......#
|
||||
.......##.#.#......##..........
|
||||
.#..#...##.#...#..#......#.....
|
||||
......#.#..#..###..##..##......
|
||||
.#.#.#.#.....#...###.....#..#..
|
||||
.#....#.....#.......#.......#..
|
||||
..........##.........####......
|
||||
.#.#.............#..#.#...#....
|
||||
........#........##...#.#....#.
|
||||
........#......................
|
||||
..#.#....#...............#...##
|
||||
.......#.#...#..#.....##......#
|
||||
.#...#....#..........##........
|
||||
.#.........#.#............##...
|
||||
.....#......##...#.......#..#..
|
||||
#.#..#.............#...#...#...
|
||||
......#.......#............#...
|
||||
...........##....#......##.....
|
||||
.#.#..#.....................#..
|
||||
##..##.....###..##.#...........
|
||||
...##......##....#...##.....#..
|
||||
#...#.##.............#.........
|
||||
......#..#.........###.#......#
|
||||
#.#.....#.....................#
|
||||
....#####.....##........#.#..#.
|
||||
...........##..##.###..........
|
||||
..........##.....#........#...#
|
||||
.......#..#......#.....##..##.#
|
||||
.....##.#........#.........#...
|
||||
......##......................#
|
||||
.#.......#.#.#............#..#.
|
||||
.....##.#.......#.#........#...
|
38
2020/d04/ex1/ex1.py
Executable file
38
2020/d04/ex1/ex1.py
Executable file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def validate(passport: List[str]) -> int:
|
||||
fields = [
|
||||
"byr",
|
||||
"iyr",
|
||||
"eyr",
|
||||
"hgt",
|
||||
"hcl",
|
||||
"ecl",
|
||||
"pid",
|
||||
]
|
||||
for field in fields:
|
||||
if field not in passport:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def solve(passport_fields: List[List[str]]) -> int:
|
||||
return sum(validate(passport) for passport in passport_fields)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
passports: List[List[str]] = [[]]
|
||||
for line in sys.stdin:
|
||||
if line == "\n" or line == "":
|
||||
passports.append([])
|
||||
continue
|
||||
passports[-1] += [s.split(":")[0] for s in line.split(" ")]
|
||||
print(solve(passports))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1069
2020/d04/ex1/input
Normal file
1069
2020/d04/ex1/input
Normal file
File diff suppressed because it is too large
Load diff
109
2020/d04/ex2/ex2.py
Executable file
109
2020/d04/ex2/ex2.py
Executable file
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
|
||||
Field = Tuple[str, ...]
|
||||
|
||||
|
||||
def validate_byr(field: str) -> bool:
|
||||
pattern = "^[0-9]{4}$"
|
||||
if not re.fullmatch(pattern, field):
|
||||
return False
|
||||
val = int(field)
|
||||
return 1920 <= val <= 2002
|
||||
|
||||
|
||||
def validate_iyr(field: str) -> bool:
|
||||
pattern = "^[0-9]{4}$"
|
||||
if not re.fullmatch(pattern, field):
|
||||
return False
|
||||
val = int(field)
|
||||
return 2010 <= val <= 2020
|
||||
|
||||
|
||||
def validate_eyr(field: str) -> bool:
|
||||
pattern = "^[0-9]{4}$"
|
||||
if not re.fullmatch(pattern, field):
|
||||
return False
|
||||
val = int(field)
|
||||
return 2020 <= val <= 2030
|
||||
|
||||
|
||||
def validate_hgt(field: str) -> bool:
|
||||
pattern = "^[0-9]+(cm|in)$"
|
||||
if not re.fullmatch(pattern, field):
|
||||
return False
|
||||
val = int(field[:-2])
|
||||
if "cm" in field:
|
||||
return 150 <= val <= 193
|
||||
return 59 <= val <= 76
|
||||
|
||||
|
||||
def validate_hcl(field: str) -> bool:
|
||||
pattern = "^#[a-f0-9]{6}$"
|
||||
if not re.fullmatch(pattern, field):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def validate_ecl(field: str) -> bool:
|
||||
return field in {
|
||||
"amb",
|
||||
"blu",
|
||||
"brn",
|
||||
"gry",
|
||||
"grn",
|
||||
"hzl",
|
||||
"oth",
|
||||
}
|
||||
|
||||
|
||||
def validate_pid(field: str) -> bool:
|
||||
pattern = "^[0-9]{9}$"
|
||||
if not re.fullmatch(pattern, field):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def validate(passport: List[Field]) -> int:
|
||||
fields = {
|
||||
"byr": validate_byr,
|
||||
"iyr": validate_iyr,
|
||||
"eyr": validate_eyr,
|
||||
"hgt": validate_hgt,
|
||||
"hcl": validate_hcl,
|
||||
"ecl": validate_ecl,
|
||||
"pid": validate_pid,
|
||||
}
|
||||
tot = 0
|
||||
for field in passport:
|
||||
if len(field) != 2:
|
||||
continue
|
||||
if field[0] not in fields:
|
||||
if field[0] == "cid":
|
||||
continue
|
||||
return False
|
||||
if not fields[field[0]](field[1].strip()):
|
||||
return False
|
||||
tot += 1
|
||||
return tot == len(fields)
|
||||
|
||||
|
||||
def solve(passport_fields: List[List[Field]]) -> int:
|
||||
return sum(validate(passport) for passport in passport_fields)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
passports: List[List[Field]] = [[]]
|
||||
for line in sys.stdin:
|
||||
if line == "\n" or line == "":
|
||||
passports.append([])
|
||||
continue
|
||||
passports[-1] += [tuple(s.split(":")) for s in line.split(" ") if s]
|
||||
print(solve(passports))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1069
2020/d04/ex2/input
Normal file
1069
2020/d04/ex2/input
Normal file
File diff suppressed because it is too large
Load diff
35
2020/d05/ex1/ex1.py
Executable file
35
2020/d05/ex1/ex1.py
Executable file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def seat_id(boarding_pass: str) -> int:
|
||||
min_x = 0
|
||||
max_x = 128
|
||||
min_y = 0
|
||||
max_y = 8
|
||||
|
||||
for char in boarding_pass:
|
||||
if char == "F":
|
||||
max_x = (min_x + max_x) // 2
|
||||
elif char == "B":
|
||||
min_x = (min_x + max_x) // 2
|
||||
elif char == "L":
|
||||
max_y = (min_y + max_y) // 2
|
||||
elif char == "R":
|
||||
min_y = (min_y + max_y) // 2
|
||||
return min_x * 8 + min_y
|
||||
|
||||
|
||||
def solve(passes: List[str]) -> int:
|
||||
return max(seat_id(p) for p in passes)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
781
2020/d05/ex1/input
Normal file
781
2020/d05/ex1/input
Normal file
|
@ -0,0 +1,781 @@
|
|||
FBFFBFFRLL
|
||||
BFFFFBBRLR
|
||||
FFFBBBBRLR
|
||||
FBFFFBFLRL
|
||||
FFBFBFFRRL
|
||||
FFBBBBFRRR
|
||||
FBFFBFBLRR
|
||||
FFBBFBFRRL
|
||||
FFFFBBFRRL
|
||||
BFBBBBBLLL
|
||||
FFBFBFBLLL
|
||||
FFBFFFBLLL
|
||||
FBBBFBFRLL
|
||||
BBFFFBFRRR
|
||||
FFFBFBBLLR
|
||||
FBFBFBFRRR
|
||||
BBFFBFBRLL
|
||||
FBFBBBBLRL
|
||||
FBFFFFFLLL
|
||||
BFFFFFFRLL
|
||||
BFFFBFBLRL
|
||||
BFBBBFBRRL
|
||||
BFFFBFFRRL
|
||||
FBFFFFFRRR
|
||||
FFBBBBBLLR
|
||||
BFBBFFBLRL
|
||||
FBBFBBBRLR
|
||||
BFBFBFFRLL
|
||||
BFBFBFBRLL
|
||||
BFFBFBFLLL
|
||||
FFBBFFBLRL
|
||||
FBBFFBFLRR
|
||||
FBBBFBBRRR
|
||||
BFBFFBFRLR
|
||||
BFBBBFBLLL
|
||||
FFBFBBBLRR
|
||||
BFBFFBFLLL
|
||||
FBFBFBBLLL
|
||||
BFBBBFBLRL
|
||||
FBFBFBFLRL
|
||||
FFBFFBFRRL
|
||||
FBBFFBFLLL
|
||||
BFBBBBBLRL
|
||||
FBBBBBFRLR
|
||||
BFFFBBFRLL
|
||||
FBBBBFFLLR
|
||||
FBBBBBFRLL
|
||||
BFBBBFFRLR
|
||||
BFBBBFBRLL
|
||||
BFFFBFFLLL
|
||||
FFFBFBFLRL
|
||||
BFFBBFFLRL
|
||||
BBFFFBFRLL
|
||||
BFBBFFBRLR
|
||||
BFBFBFBRRL
|
||||
BBFFFBFRRL
|
||||
FBBFBBBLRR
|
||||
FFBFBBBLLL
|
||||
BFFFBFBRLR
|
||||
FFBBFBBLLL
|
||||
FBFBBFBLLL
|
||||
BFBBFBFLLR
|
||||
FFBFBBBRRL
|
||||
FFBFFFFLRL
|
||||
FFFBBFFLRR
|
||||
FBBBBBFRRR
|
||||
FFFFBBBRLL
|
||||
BFBFBBBRRR
|
||||
BBFFBFBRRL
|
||||
FBFBBFFRLR
|
||||
FBBFFBFRRR
|
||||
BBFFBFBRRR
|
||||
FBFBBFBLRR
|
||||
FBBFFBBLRR
|
||||
FBBBBFFRLL
|
||||
BFBFFFBRLR
|
||||
FBFBBFBRRL
|
||||
FFBFBBFRRR
|
||||
FBFBFFFRLL
|
||||
BFBBFFBLLR
|
||||
FBFFFFBRLR
|
||||
BFBBBFFRLL
|
||||
FFBBFFBRLR
|
||||
FFFBBFBRLL
|
||||
FBBBBBBLRR
|
||||
FBFFBBBLRR
|
||||
BFFFFBFLRL
|
||||
BBFFFFFLRR
|
||||
BFFBFFBLLR
|
||||
FFBBBFFRLL
|
||||
BFBFBFBRLR
|
||||
FBBFBFBLRR
|
||||
FBFBBBFRLR
|
||||
FBFFBBBRRR
|
||||
FBBFFBFRLL
|
||||
FBBBFFFRLR
|
||||
BFBBBBFLLR
|
||||
BFFFBFFLLR
|
||||
FFBFFFBRRR
|
||||
FBFFFBFLLR
|
||||
FFFFBBBLLR
|
||||
BFBFFFBRLL
|
||||
BFFBBFBLRL
|
||||
BFFBFBFLLR
|
||||
FFBFFBFRLR
|
||||
BFBFFFBRRL
|
||||
FFBBFBFLLL
|
||||
BFBBBBBRLR
|
||||
BFBFBFBLRR
|
||||
FBFFBFBLLR
|
||||
FBFBFBBRRL
|
||||
BFBFBBBLLL
|
||||
FFBBFBBLRL
|
||||
FBFFFBFRRL
|
||||
BFBBFFFLRR
|
||||
BFBFBBFRRR
|
||||
FBFFFFBLRL
|
||||
BBFFBBFRRR
|
||||
FFBFFBBRLR
|
||||
FBBFBFBLRL
|
||||
BFBFFFBRRR
|
||||
FFFBBBFLRL
|
||||
BFFBFFBRLL
|
||||
FBFBFFBLRR
|
||||
FFBFBBFLLL
|
||||
FFBBBFFLRL
|
||||
FFBBFFFRLR
|
||||
BBFFBFBLRL
|
||||
FFFFBBFRLR
|
||||
FFFBFFBLRR
|
||||
BFFBBBFLLR
|
||||
BFFFBBBRRL
|
||||
FBBFBFBRLL
|
||||
BFFBFFFRRR
|
||||
BBFFFFFLRL
|
||||
BBFFFBBRLL
|
||||
BFFFBBBRRR
|
||||
BFFFBBBLRL
|
||||
BBFFBFFRRR
|
||||
BFFBFFBLRL
|
||||
FBBBBFBRLR
|
||||
FFFBFBFRRL
|
||||
BFFBBBBRRL
|
||||
FBBBBBFLRR
|
||||
FBFBBBBLLR
|
||||
FBBBBFBLRR
|
||||
FFFBFFBRLL
|
||||
FFBBBBFLLR
|
||||
FFBBBBBRRL
|
||||
FBBFFFFLLL
|
||||
FBFFBBBRLL
|
||||
FBFBFFBLLR
|
||||
FBBBBBFRRL
|
||||
BFFFBFBLLL
|
||||
FFFBFFFLRL
|
||||
FFFFBBFRLL
|
||||
BFBBFFFRLR
|
||||
BFFFBBBRLR
|
||||
FFBBBFBLLR
|
||||
BFFFBFBRRR
|
||||
BFFBFBBLRL
|
||||
FFBFBFBLRR
|
||||
FBBBBFBRRR
|
||||
FFBFBFFLLR
|
||||
BBFFFFFLLR
|
||||
FBBBFBFRRR
|
||||
BBFFFFBRRL
|
||||
FBFBFBBLRL
|
||||
BFBBBFFLLR
|
||||
BBFFBBFLRL
|
||||
BFBFFBBRLR
|
||||
FBFBBBFRRL
|
||||
FBBBFFBRLL
|
||||
BBFFFFBLLR
|
||||
FFBBFBBLRR
|
||||
FBBBBBBRLR
|
||||
FFFFBBBRRL
|
||||
FBFBBBBRLR
|
||||
BBFFBFFRRL
|
||||
FBBBFFBLRL
|
||||
FFBBBFBLRR
|
||||
BFBFBBBRLL
|
||||
FBFFFBBLRL
|
||||
FBFBBBBRLL
|
||||
BBFFFBBLLL
|
||||
BFBBFFBLLL
|
||||
BFFBBBBRRR
|
||||
FBFBFFBLLL
|
||||
FBFBFBFRRL
|
||||
FBBFFFBLLL
|
||||
BBFFFBFRLR
|
||||
FBBBBFFLRR
|
||||
FBFFFBBRLL
|
||||
FFBBFBFRRR
|
||||
FBFFFFFLRR
|
||||
BFBFFBBLRR
|
||||
FFBFBFFRRR
|
||||
BFBFFBBRLL
|
||||
FBBFFFFRRL
|
||||
BFFBBFBRLL
|
||||
BFFFFFBLLR
|
||||
FBFBBFBLLR
|
||||
BFFBBFBRLR
|
||||
BFFBFBFRRR
|
||||
FFBFBBFRLL
|
||||
FFFBBBBLRR
|
||||
BFFFBFBLLR
|
||||
FBBBBFBLRL
|
||||
FBFBBFFLRL
|
||||
FFFBFFFRLL
|
||||
BFFFFBBRRL
|
||||
FBBFFFBRRR
|
||||
FBBFBFFLLR
|
||||
BFBBBBBRRR
|
||||
BFFBFBFRLL
|
||||
FFBFBBFRRL
|
||||
BFBFBFBLLR
|
||||
FFBFBBFLLR
|
||||
FFBFFFFLRR
|
||||
FBBBFBBRRL
|
||||
BFFBFBFRLR
|
||||
BFFBFFBRRL
|
||||
BFBBBFBRLR
|
||||
BBFFFFBLRL
|
||||
FBBBFFBRRL
|
||||
FBFFFBBRRL
|
||||
FBBBBBBLLL
|
||||
FFFBFFBLLL
|
||||
BFBBFBFRLL
|
||||
FBFBFFBRLR
|
||||
FFFFBBBRRR
|
||||
BBFFFBBRLR
|
||||
BFBBBBFRLR
|
||||
FBFFBBFLRR
|
||||
BFFFBFFRLR
|
||||
FFFBBBBLLR
|
||||
FBFFFFBLRR
|
||||
FBFBFBBRLL
|
||||
FBFFBBBRLR
|
||||
BFFFFFFLRR
|
||||
FBFFFFFRLL
|
||||
FFBFBFFRLL
|
||||
FFFBBFFRLR
|
||||
FBBFBFFRRL
|
||||
FBBBBBBRRR
|
||||
BFBFBBBLRL
|
||||
BBFFFFBRRR
|
||||
FFBFFBBLRL
|
||||
FBBBBBBLLR
|
||||
FFBBFFFLRL
|
||||
FBBBFBBLRR
|
||||
FFBBBBBRLR
|
||||
BFBFFFFLLR
|
||||
BFFBBBBRLL
|
||||
BFBFBFFLRL
|
||||
FBBFFFBLRL
|
||||
BFBFBBBRRL
|
||||
BFBFBFBLRL
|
||||
BFBBFBFLRR
|
||||
BFFFFBFRLR
|
||||
BFFFBFBRLL
|
||||
FBFBFBFLLL
|
||||
FBFFBFFLRL
|
||||
BFFFFFFRRL
|
||||
FBBFBFFRLR
|
||||
FFBBBFFLLR
|
||||
FBBBBFFLRL
|
||||
FBBBFBBRLR
|
||||
BFBBBFFLRL
|
||||
FBFFBBBLRL
|
||||
BFFFFBFRRL
|
||||
BFFFBFFLRR
|
||||
FFBFBBFLRL
|
||||
BFBFFFBLRL
|
||||
BFFFFFBLLL
|
||||
FBFFBFBLLL
|
||||
FBFBBBBRRL
|
||||
FBBFFBBRLR
|
||||
BFFFBBFRRL
|
||||
BFBBFBBRLR
|
||||
FFFBFBBLRR
|
||||
FFFBFBFRLR
|
||||
FBFBFBFRLR
|
||||
BFBFBBBRLR
|
||||
BFFFFBBLLL
|
||||
BFFBBFBRRR
|
||||
BFFBBBFLLL
|
||||
FFBBBFFRRL
|
||||
BFBBBFBLLR
|
||||
FBBFFBBLLR
|
||||
FBBFBBFLRL
|
||||
BFFFFFBRRR
|
||||
FBBBFBBRLL
|
||||
FBFBFFBRRR
|
||||
BFFBBBFRRR
|
||||
FBBBBBBLRL
|
||||
FFBBBFFLRR
|
||||
BFFBBBFRLL
|
||||
BBFFBBFRLL
|
||||
FBBFBBFRLR
|
||||
BFBFBFFRRR
|
||||
BFBFBBFLRL
|
||||
BFFFFBFRLL
|
||||
FFBBFBFLLR
|
||||
BFFBFBBLRR
|
||||
FBFFBBBRRL
|
||||
FBBFBBFRLL
|
||||
FBFFFBBLLR
|
||||
FFFBBBBRRR
|
||||
FFFFBBBLRL
|
||||
FFBBFFFRRL
|
||||
BFFBBFFRRL
|
||||
BFFFBBFLRL
|
||||
BFFFFBBLRR
|
||||
BBFFBBBLRR
|
||||
BFBFFFFLRR
|
||||
FBFBBBBLLL
|
||||
BBFFFBBLRR
|
||||
FFFBFBFLRR
|
||||
FBBFFFFLRL
|
||||
FFBBBBFRLL
|
||||
FBFFBFBLRL
|
||||
BFBBFBBLLL
|
||||
FBBFBBFLLL
|
||||
FFBFFBBRLL
|
||||
BFBFFFFRLR
|
||||
FBFFBBFRRR
|
||||
FFFBBFFRRR
|
||||
FFFBFFBRLR
|
||||
FBBBBBFLLL
|
||||
FBBBFFFLRL
|
||||
FFBBFFFLRR
|
||||
FFFBBBBRRL
|
||||
BFBFBBFRLL
|
||||
BFBFFBBRRL
|
||||
FBBFBBFRRL
|
||||
BFBFBBFLLR
|
||||
BBFFBBBRRR
|
||||
BFFFBBFRLR
|
||||
FFFBBBFRLR
|
||||
BFFBFFFRLL
|
||||
BFBFFFFRRL
|
||||
FFBBFFFLLL
|
||||
FBFBBBBLRR
|
||||
FBFBFFFLRR
|
||||
BBFFBFFLRR
|
||||
FBBBFBBLRL
|
||||
BFBFBFBLLL
|
||||
FBFBFFFLLR
|
||||
BFFBBFBLRR
|
||||
FBBFFFBRRL
|
||||
BFFBBFFRRR
|
||||
FBBFBBBRRL
|
||||
BFFFFBBLLR
|
||||
FFBBBBFLLL
|
||||
BFFBFFBRRR
|
||||
BFFFFBFRRR
|
||||
FFFBBBFRRR
|
||||
FBFBFFFRLR
|
||||
FBBBFBFLLR
|
||||
FFBBFFBRLL
|
||||
FBFBFFFLLL
|
||||
BFFBFBFRRL
|
||||
BFBFFBFRRL
|
||||
BFBBBBFLLL
|
||||
FBBBFBFRRL
|
||||
FFBFBFFLLL
|
||||
BFBBFFFRRL
|
||||
FFBBFFBLLR
|
||||
BFFBBBBRLR
|
||||
FFBBBBBLRR
|
||||
BFFBFFFRRL
|
||||
BFFBFBBRLL
|
||||
FBBBFBFRLR
|
||||
FBBFFFFLRR
|
||||
BFFFBBFLLR
|
||||
FFFBBFBRRL
|
||||
FFBBFFBLRR
|
||||
FBBFFFBRLR
|
||||
BFBBBBBRLL
|
||||
BBFFFFFRRL
|
||||
FFBFFBBRRL
|
||||
BFBFFBFLLR
|
||||
FBFBBBFLLL
|
||||
FBFFFFFRRL
|
||||
BFFFBFBLRR
|
||||
FBFFFFBLLR
|
||||
FBBFBFBRRR
|
||||
FBBBFFFLLR
|
||||
BBFFBFBLRR
|
||||
BBFFFBFLLL
|
||||
FBFFFBFRLR
|
||||
BFFFBFFLRL
|
||||
BBFFBFFLRL
|
||||
BFFFFFFLLR
|
||||
BBFFBBBLLL
|
||||
FFBFBBBLLR
|
||||
FBBFBBBLRL
|
||||
BFBBFBBLRR
|
||||
FFBFBFBLLR
|
||||
FFBFBFBRRL
|
||||
BFBBFBBRRL
|
||||
BFFBFFFLLR
|
||||
FFBBFFBRRL
|
||||
BBFFBBBRRL
|
||||
FFFBBFBRLR
|
||||
BFBBFBFRRR
|
||||
BFFFFFFRRR
|
||||
FBBBFFBLLL
|
||||
BFBFFFFLLL
|
||||
BBFFBFBLLR
|
||||
BFBFBBFRLR
|
||||
FFBFBBBRRR
|
||||
BFFFBBFLLL
|
||||
FBFFBBFRLL
|
||||
FFBBFBFRLL
|
||||
BFBFBBBLLR
|
||||
FBBFBFBLLL
|
||||
BBFFFFBRLL
|
||||
BBFFBFBLLL
|
||||
BFFBFFBLRR
|
||||
BFFBBFBLLL
|
||||
FFBFFFBLRR
|
||||
FBBFFBFRRL
|
||||
FBBBBFBLLL
|
||||
FFBFFBBLLR
|
||||
BFFBBBFLRR
|
||||
FBFBFFBRLL
|
||||
FFBFFFBRLL
|
||||
FFBFFBFLLL
|
||||
FBFBBFBLRL
|
||||
FBBFBFFRRR
|
||||
BFBFBFFLLR
|
||||
FBBFFFBLLR
|
||||
BFBBBBFRRR
|
||||
FBBFBBFRRR
|
||||
BBFFBFFRLR
|
||||
FBFBBBFRLL
|
||||
FBBFBBBLLR
|
||||
BFFFFFFLRL
|
||||
BFBFFBBRRR
|
||||
BFFFBFFRLL
|
||||
BFBBFBFLRL
|
||||
FFBFFFFRRR
|
||||
BFFBBFFRLR
|
||||
FBBBBBFLLR
|
||||
FBFBFFBLRL
|
||||
FFFBBFBLLR
|
||||
FBBFBFBLLR
|
||||
FFFBFFBRRR
|
||||
FBFFFFFRLR
|
||||
FBFBBFBRLR
|
||||
FBBBFBFLRR
|
||||
FBFBBBFLRL
|
||||
BFFBFFFLRL
|
||||
FFBBBFFRRR
|
||||
FFBBBBBLLL
|
||||
FBFFBBFLLR
|
||||
FFBFBFFLRR
|
||||
FFFBBBFLRR
|
||||
BFBFBBFLLL
|
||||
BBFFBFFLLR
|
||||
FFBBFBBRLL
|
||||
FBBFFBBLLL
|
||||
FBFFBFBRLL
|
||||
BFBFBFFLRR
|
||||
FBBBFFBRLR
|
||||
FFBFFBFRLL
|
||||
FFFFBBBLLL
|
||||
FFBFFBBRRR
|
||||
FBBBBFBRLL
|
||||
BFFFFBBRRR
|
||||
FFBBFFFRLL
|
||||
FFBFBFBRLL
|
||||
BBFFFFBLLL
|
||||
FFBBBFBRRL
|
||||
BFFFFBBLRL
|
||||
FBBBFBBLLR
|
||||
FBBBFBBLLL
|
||||
FFBFBFBLRL
|
||||
FBBBBFFRRR
|
||||
FBBFFFFRLR
|
||||
FFBFFFBRLR
|
||||
BFBFBFBRRR
|
||||
FFFBFBBRLL
|
||||
FBBBFFBRRR
|
||||
FBBFBFFRLL
|
||||
BFFBFBFLRR
|
||||
BFBBBFFRRL
|
||||
BFFBBFBLLR
|
||||
FFBBBFBRLL
|
||||
FBFBFBBLRR
|
||||
BFBBFFFLRL
|
||||
BFBFBBFLRR
|
||||
BFBBBFFRRR
|
||||
FBBBFFFRRL
|
||||
FBFBFBFLLR
|
||||
FBBFFFFLLR
|
||||
FFBFBBFRLR
|
||||
FFFBFBBLRL
|
||||
BBFFFBBLLR
|
||||
BFFBBBFRLR
|
||||
FFFFBBBRLR
|
||||
BBFFBBFRLR
|
||||
FBFFFFBRLL
|
||||
FBFBFFFRRR
|
||||
FBFFFBBLLL
|
||||
BFBBBBFRLL
|
||||
FBFBFFBRRL
|
||||
FFFBFFFRLR
|
||||
BFBBFBFRRL
|
||||
FBFFBFFLRR
|
||||
FBFFFBBLRR
|
||||
FFBFBBBRLR
|
||||
FBBFBFFLRR
|
||||
FBFFFBBRRR
|
||||
FFBFBBBRLL
|
||||
FFBBBBBRRR
|
||||
BFFBBFFLLL
|
||||
BFBBBBBRRL
|
||||
BBFFBBBRLL
|
||||
FBFFFFFLRL
|
||||
BFFBBFFLRR
|
||||
FBFFBBFLRL
|
||||
BFBFFBFRRR
|
||||
FBFBBFBRLL
|
||||
BFFFBFBRRL
|
||||
FBBFFBFLLR
|
||||
BFFFFFFLLL
|
||||
FBFBFBFRLL
|
||||
FBBBBFFRRL
|
||||
BFBFFBBLLR
|
||||
FBBFBFBRRL
|
||||
FFFBFFFLLR
|
||||
FFBBBBBLRL
|
||||
FFBFFBBLRR
|
||||
FFFBFBFRRR
|
||||
BFBBFBBRLL
|
||||
BFBBBFBLRR
|
||||
FFBBBBFLRR
|
||||
FBBBFFBLLR
|
||||
BBFFBBBLLR
|
||||
FBFBBFFRRL
|
||||
FBBBBBFLRL
|
||||
FFFBBFFRRL
|
||||
BFFBBBBLRR
|
||||
FFFFBBBLRR
|
||||
FFFFBBFLRR
|
||||
FBFFFBFLLL
|
||||
FBFBFBBLLR
|
||||
BFFBBBBLLL
|
||||
FFBFFFFRLR
|
||||
BFBBFFBLRR
|
||||
FFBBFBFLRL
|
||||
BFBFBFFLLL
|
||||
BFFBFBBLLR
|
||||
BFBBFBBLRL
|
||||
FFBBBBFLRL
|
||||
FBBBFFFLLL
|
||||
FFFBFFBRRL
|
||||
BFFFFBBRLL
|
||||
BFFFBBBRLL
|
||||
BFFBFFFLRR
|
||||
FFBFBFBRRR
|
||||
BBFFBBFLLR
|
||||
FFBBFBBLLR
|
||||
FFBFFBFRRR
|
||||
FFBBBFFRLR
|
||||
BFFBBBBLLR
|
||||
FFFBFFFLRR
|
||||
FBFFFFFLLR
|
||||
FBFFBBBLLL
|
||||
BBFFBBFLLL
|
||||
FFBBFBFLRR
|
||||
BFFBFBFLRL
|
||||
FBFBBBFRRR
|
||||
BFBBFBBLLR
|
||||
FBFFFFBRRL
|
||||
FFFBBFBLRR
|
||||
BBFFFFBLRR
|
||||
BFBBBBFRRL
|
||||
FFBBBFBLLL
|
||||
BFBBFBFRLR
|
||||
BFBBFFBRRL
|
||||
BFBFBFFRRL
|
||||
FBBFFBBLRL
|
||||
FFFBFFBLRL
|
||||
BFFBBFFRLL
|
||||
FBBBFFFRLL
|
||||
FBBFBBFLLR
|
||||
FFBFFFFLLR
|
||||
FBBBFBFLRL
|
||||
BFFFBBBLLR
|
||||
FBFBBBBRRR
|
||||
FBBFBFBRLR
|
||||
FFFBFBFLLR
|
||||
FFFFBBFRRR
|
||||
FFFBBFFLRL
|
||||
BFBFFBFRLL
|
||||
FFFBFFBLLR
|
||||
FBBFFFBRLL
|
||||
FFBBBFBRRR
|
||||
FFBBFBBRLR
|
||||
BBFFFFFRRR
|
||||
FFBFFFFRLL
|
||||
FBBFFBBRRL
|
||||
BBFFFBFLRR
|
||||
FBBFFFFRRR
|
||||
FFBFFFBRRL
|
||||
BFBBFBFLLL
|
||||
BFFFFBFLRR
|
||||
BBFFFFFLLL
|
||||
FFBBFBBRRL
|
||||
FFBFBFFLRL
|
||||
FBFFBBFRRL
|
||||
BBFFBFBRLR
|
||||
BBFFBBFLRR
|
||||
FBFFBFBRRR
|
||||
FBBFBBFLRR
|
||||
FBFFFBFRLL
|
||||
BFBFFFFLRL
|
||||
FFFBBFBRRR
|
||||
BFBBBBBLLR
|
||||
FBBFFBBRRR
|
||||
FFBBBFFLLL
|
||||
FBBBBFBLLR
|
||||
BBFFFFFRLL
|
||||
FFBBBBFRLR
|
||||
FBFBFBBRRR
|
||||
FBFFBFFLLL
|
||||
FBFFBBBLLR
|
||||
FBBBBFBRRL
|
||||
BFBFBFFRLR
|
||||
FBBFBBBRLL
|
||||
BFBBFFFRLL
|
||||
FBBBFBFLLL
|
||||
FFBFFFFRRL
|
||||
FBFBBFFRRR
|
||||
FBFFFFBLLL
|
||||
FBBBBBBRLL
|
||||
BFFBFBBRRR
|
||||
BBFFBBFRRL
|
||||
FBBFBFFLRL
|
||||
FBFFFFBRRR
|
||||
FBBFFFFRLL
|
||||
FFFBFFFRRR
|
||||
FBFFBBFLLL
|
||||
BFFFFBFLLL
|
||||
BFFFFBFLLR
|
||||
FFBFFBFLLR
|
||||
FFBFFBFLRR
|
||||
BFFBBBBLRL
|
||||
FFBBFFBLLL
|
||||
FBBFBBBLLL
|
||||
FBFBBBFLLR
|
||||
BFFBBBFLRL
|
||||
BFBBFFBRLL
|
||||
FBFFBFFRRR
|
||||
FFBFFFBLRL
|
||||
FFFBBBFRRL
|
||||
FFBFBBFLRR
|
||||
FFFBBBBLRL
|
||||
FFFBBFFLLL
|
||||
FFFBFBBRRR
|
||||
FBBFBFFLLL
|
||||
BFFFBBBLLL
|
||||
BFFBFFFRLR
|
||||
FFFBBBBLLL
|
||||
BFFFFFBRRL
|
||||
FFBBFFFLLR
|
||||
BFBBFFFRRR
|
||||
BFBFFBFLRR
|
||||
FFFBBBFLLR
|
||||
FBFBBBFLRR
|
||||
BBFFBBBRLR
|
||||
FBFBBFFLRR
|
||||
FFBBBFBLRL
|
||||
FFFBBBFRLL
|
||||
BFFBFFBRLR
|
||||
BBFFFBBRRR
|
||||
BFBBBBFLRL
|
||||
BFBBBFBRRR
|
||||
FBBBBFFLLL
|
||||
FFFBFBBLLL
|
||||
BBFFFFFRLR
|
||||
BBFFBFFLLL
|
||||
FFBFBBBLRL
|
||||
FFBBFBFRLR
|
||||
BFBBBBBLRR
|
||||
FFBFFFBLLR
|
||||
FFBFFBFLRL
|
||||
BFFBFBBRLR
|
||||
FBFBFFFRRL
|
||||
FBBBFFFLRR
|
||||
FFFBBFFLLR
|
||||
FBBBBFFRLR
|
||||
FFBBFBBRRR
|
||||
BFBBFBBRRR
|
||||
BFBFBBFRRL
|
||||
BFFBBBFRRL
|
||||
FFFBFFFLLL
|
||||
FBBFFBFLRL
|
||||
FFFBFBBRLR
|
||||
BFBBFFFLLR
|
||||
BFBBFFBRRR
|
||||
FBFFBFBRRL
|
||||
FFBBBBBRLL
|
||||
BFFBFFBLLL
|
||||
BFFFBBFRRR
|
||||
FBFFFBFRRR
|
||||
FFBFBFBRLR
|
||||
FBFBBFFLLR
|
||||
FBBFBBBRRR
|
||||
BFBFFFFRRR
|
||||
FFBFFFFLLL
|
||||
FBFBBFFRLL
|
||||
BFBFFBFLRL
|
||||
BFBBFFFLLL
|
||||
FBFBBFBRRR
|
||||
BFBFFFBLLR
|
||||
BFBFFFBLLL
|
||||
BBFFFBFLLR
|
||||
BBFFBFFRLL
|
||||
FFBBBBFRRL
|
||||
BBFFFBFLRL
|
||||
BBFFBBBLRL
|
||||
BFBFFFBLRR
|
||||
FFFBFBFRLL
|
||||
BFBFFBBLLL
|
||||
BBFFFBBRRL
|
||||
BFBBBFFLLL
|
||||
BFFBBFFLLR
|
||||
FFBFFBBLLL
|
||||
BFFBBFBRRL
|
||||
BFFFFFBLRL
|
||||
BBFFFFBRLR
|
||||
FBFBBFFLLL
|
||||
FFBBBFBRLR
|
||||
FFFBBFBLLL
|
||||
FBFFFBBRLR
|
||||
FFBFBFFRLR
|
||||
BFFFFFBLRR
|
||||
FFFBBBBRLL
|
||||
FFBBFFFRRR
|
||||
BFFFFFBRLR
|
||||
FBBBFFBLRR
|
||||
FBFBFBBRLR
|
||||
FBBFFFBLRR
|
||||
BFBFFBBLRL
|
||||
FBFFBFBRLR
|
||||
FBFBFFFLRL
|
||||
BFFFFFBRLL
|
||||
BFBBBBFLRR
|
||||
BFFBFFFLLL
|
||||
FBFFBFFRRL
|
||||
FFFBBFFRLL
|
||||
BFFFBFFRRR
|
||||
FBFFBFFLLR
|
||||
FFFBBBFLLL
|
||||
FBFFFBFLRR
|
||||
BFFBFBBLLL
|
||||
BFFFBBBLRR
|
||||
FBBBBBBRRL
|
||||
FBFFBFFRLR
|
||||
FBBFFBBRLL
|
||||
FBBBFFFRRR
|
||||
BFFBFBBRRL
|
||||
FFBBFFBRRR
|
||||
BFBBBFFLRR
|
||||
FFFBFBBRRL
|
||||
BFBFBBBLRR
|
||||
FFFBBFBLRL
|
||||
FBFFBBFRLR
|
||||
BFFFBBFLRR
|
||||
BBFFFBBLRL
|
||||
FBBFFBFRLR
|
||||
FFFBFBFLLL
|
||||
FFFBFFFRRL
|
||||
BBFBFFFLLL
|
||||
FBFBFBFLRR
|
||||
BFBFFFFRLL
|
41
2020/d05/ex2/ex2.py
Executable file
41
2020/d05/ex2/ex2.py
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def seat_id(boarding_pass: str) -> int:
|
||||
min_x = 0
|
||||
max_x = 128
|
||||
min_y = 0
|
||||
max_y = 8
|
||||
|
||||
for char in boarding_pass:
|
||||
if char == "F":
|
||||
max_x = (min_x + max_x) // 2
|
||||
elif char == "B":
|
||||
min_x = (min_x + max_x) // 2
|
||||
elif char == "L":
|
||||
max_y = (min_y + max_y) // 2
|
||||
elif char == "R":
|
||||
min_y = (min_y + max_y) // 2
|
||||
return min_x * 8 + min_y
|
||||
|
||||
|
||||
def solve(passes: List[str]) -> int:
|
||||
ids = sorted(seat_id(p) for p in passes)
|
||||
|
||||
for prev, cur in zip(ids, ids[1:]):
|
||||
if prev + 1 != cur:
|
||||
return prev + 1
|
||||
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
781
2020/d05/ex2/input
Normal file
781
2020/d05/ex2/input
Normal file
|
@ -0,0 +1,781 @@
|
|||
FBFFBFFRLL
|
||||
BFFFFBBRLR
|
||||
FFFBBBBRLR
|
||||
FBFFFBFLRL
|
||||
FFBFBFFRRL
|
||||
FFBBBBFRRR
|
||||
FBFFBFBLRR
|
||||
FFBBFBFRRL
|
||||
FFFFBBFRRL
|
||||
BFBBBBBLLL
|
||||
FFBFBFBLLL
|
||||
FFBFFFBLLL
|
||||
FBBBFBFRLL
|
||||
BBFFFBFRRR
|
||||
FFFBFBBLLR
|
||||
FBFBFBFRRR
|
||||
BBFFBFBRLL
|
||||
FBFBBBBLRL
|
||||
FBFFFFFLLL
|
||||
BFFFFFFRLL
|
||||
BFFFBFBLRL
|
||||
BFBBBFBRRL
|
||||
BFFFBFFRRL
|
||||
FBFFFFFRRR
|
||||
FFBBBBBLLR
|
||||
BFBBFFBLRL
|
||||
FBBFBBBRLR
|
||||
BFBFBFFRLL
|
||||
BFBFBFBRLL
|
||||
BFFBFBFLLL
|
||||
FFBBFFBLRL
|
||||
FBBFFBFLRR
|
||||
FBBBFBBRRR
|
||||
BFBFFBFRLR
|
||||
BFBBBFBLLL
|
||||
FFBFBBBLRR
|
||||
BFBFFBFLLL
|
||||
FBFBFBBLLL
|
||||
BFBBBFBLRL
|
||||
FBFBFBFLRL
|
||||
FFBFFBFRRL
|
||||
FBBFFBFLLL
|
||||
BFBBBBBLRL
|
||||
FBBBBBFRLR
|
||||
BFFFBBFRLL
|
||||
FBBBBFFLLR
|
||||
FBBBBBFRLL
|
||||
BFBBBFFRLR
|
||||
BFBBBFBRLL
|
||||
BFFFBFFLLL
|
||||
FFFBFBFLRL
|
||||
BFFBBFFLRL
|
||||
BBFFFBFRLL
|
||||
BFBBFFBRLR
|
||||
BFBFBFBRRL
|
||||
BBFFFBFRRL
|
||||
FBBFBBBLRR
|
||||
FFBFBBBLLL
|
||||
BFFFBFBRLR
|
||||
FFBBFBBLLL
|
||||
FBFBBFBLLL
|
||||
BFBBFBFLLR
|
||||
FFBFBBBRRL
|
||||
FFBFFFFLRL
|
||||
FFFBBFFLRR
|
||||
FBBBBBFRRR
|
||||
FFFFBBBRLL
|
||||
BFBFBBBRRR
|
||||
BBFFBFBRRL
|
||||
FBFBBFFRLR
|
||||
FBBFFBFRRR
|
||||
BBFFBFBRRR
|
||||
FBFBBFBLRR
|
||||
FBBFFBBLRR
|
||||
FBBBBFFRLL
|
||||
BFBFFFBRLR
|
||||
FBFBBFBRRL
|
||||
FFBFBBFRRR
|
||||
FBFBFFFRLL
|
||||
BFBBFFBLLR
|
||||
FBFFFFBRLR
|
||||
BFBBBFFRLL
|
||||
FFBBFFBRLR
|
||||
FFFBBFBRLL
|
||||
FBBBBBBLRR
|
||||
FBFFBBBLRR
|
||||
BFFFFBFLRL
|
||||
BBFFFFFLRR
|
||||
BFFBFFBLLR
|
||||
FFBBBFFRLL
|
||||
BFBFBFBRLR
|
||||
FBBFBFBLRR
|
||||
FBFBBBFRLR
|
||||
FBFFBBBRRR
|
||||
FBBFFBFRLL
|
||||
FBBBFFFRLR
|
||||
BFBBBBFLLR
|
||||
BFFFBFFLLR
|
||||
FFBFFFBRRR
|
||||
FBFFFBFLLR
|
||||
FFFFBBBLLR
|
||||
BFBFFFBRLL
|
||||
BFFBBFBLRL
|
||||
BFFBFBFLLR
|
||||
FFBFFBFRLR
|
||||
BFBFFFBRRL
|
||||
FFBBFBFLLL
|
||||
BFBBBBBRLR
|
||||
BFBFBFBLRR
|
||||
FBFFBFBLLR
|
||||
FBFBFBBRRL
|
||||
BFBFBBBLLL
|
||||
FFBBFBBLRL
|
||||
FBFFFBFRRL
|
||||
BFBBFFFLRR
|
||||
BFBFBBFRRR
|
||||
FBFFFFBLRL
|
||||
BBFFBBFRRR
|
||||
FFBFFBBRLR
|
||||
FBBFBFBLRL
|
||||
BFBFFFBRRR
|
||||
FFFBBBFLRL
|
||||
BFFBFFBRLL
|
||||
FBFBFFBLRR
|
||||
FFBFBBFLLL
|
||||
FFBBBFFLRL
|
||||
FFBBFFFRLR
|
||||
BBFFBFBLRL
|
||||
FFFFBBFRLR
|
||||
FFFBFFBLRR
|
||||
BFFBBBFLLR
|
||||
BFFFBBBRRL
|
||||
FBBFBFBRLL
|
||||
BFFBFFFRRR
|
||||
BBFFFFFLRL
|
||||
BBFFFBBRLL
|
||||
BFFFBBBRRR
|
||||
BFFFBBBLRL
|
||||
BBFFBFFRRR
|
||||
BFFBFFBLRL
|
||||
FBBBBFBRLR
|
||||
FFFBFBFRRL
|
||||
BFFBBBBRRL
|
||||
FBBBBBFLRR
|
||||
FBFBBBBLLR
|
||||
FBBBBFBLRR
|
||||
FFFBFFBRLL
|
||||
FFBBBBFLLR
|
||||
FFBBBBBRRL
|
||||
FBBFFFFLLL
|
||||
FBFFBBBRLL
|
||||
FBFBFFBLLR
|
||||
FBBBBBFRRL
|
||||
BFFFBFBLLL
|
||||
FFFBFFFLRL
|
||||
FFFFBBFRLL
|
||||
BFBBFFFRLR
|
||||
BFFFBBBRLR
|
||||
FFBBBFBLLR
|
||||
BFFFBFBRRR
|
||||
BFFBFBBLRL
|
||||
FFBFBFBLRR
|
||||
FBBBBFBRRR
|
||||
FFBFBFFLLR
|
||||
BBFFFFFLLR
|
||||
FBBBFBFRRR
|
||||
BBFFFFBRRL
|
||||
FBFBFBBLRL
|
||||
BFBBBFFLLR
|
||||
BBFFBBFLRL
|
||||
BFBFFBBRLR
|
||||
FBFBBBFRRL
|
||||
FBBBFFBRLL
|
||||
BBFFFFBLLR
|
||||
FFBBFBBLRR
|
||||
FBBBBBBRLR
|
||||
FFFFBBBRRL
|
||||
FBFBBBBRLR
|
||||
BBFFBFFRRL
|
||||
FBBBFFBLRL
|
||||
FFBBBFBLRR
|
||||
BFBFBBBRLL
|
||||
FBFFFBBLRL
|
||||
FBFBBBBRLL
|
||||
BBFFFBBLLL
|
||||
BFBBFFBLLL
|
||||
BFFBBBBRRR
|
||||
FBFBFFBLLL
|
||||
FBFBFBFRRL
|
||||
FBBFFFBLLL
|
||||
BBFFFBFRLR
|
||||
FBBBBFFLRR
|
||||
FBFFFBBRLL
|
||||
FFBBFBFRRR
|
||||
FBFFFFFLRR
|
||||
BFBFFBBLRR
|
||||
FFBFBFFRRR
|
||||
BFBFFBBRLL
|
||||
FBBFFFFRRL
|
||||
BFFBBFBRLL
|
||||
BFFFFFBLLR
|
||||
FBFBBFBLLR
|
||||
BFFBBFBRLR
|
||||
BFFBFBFRRR
|
||||
FFBFBBFRLL
|
||||
FFFBBBBLRR
|
||||
BFFFBFBLLR
|
||||
FBBBBFBLRL
|
||||
FBFBBFFLRL
|
||||
FFFBFFFRLL
|
||||
BFFFFBBRRL
|
||||
FBBFFFBRRR
|
||||
FBBFBFFLLR
|
||||
BFBBBBBRRR
|
||||
BFFBFBFRLL
|
||||
FFBFBBFRRL
|
||||
BFBFBFBLLR
|
||||
FFBFBBFLLR
|
||||
FFBFFFFLRR
|
||||
FBBBFBBRRL
|
||||
BFFBFBFRLR
|
||||
BFFBFFBRRL
|
||||
BFBBBFBRLR
|
||||
BBFFFFBLRL
|
||||
FBBBFFBRRL
|
||||
FBFFFBBRRL
|
||||
FBBBBBBLLL
|
||||
FFFBFFBLLL
|
||||
BFBBFBFRLL
|
||||
FBFBFFBRLR
|
||||
FFFFBBBRRR
|
||||
BBFFFBBRLR
|
||||
BFBBBBFRLR
|
||||
FBFFBBFLRR
|
||||
BFFFBFFRLR
|
||||
FFFBBBBLLR
|
||||
FBFFFFBLRR
|
||||
FBFBFBBRLL
|
||||
FBFFBBBRLR
|
||||
BFFFFFFLRR
|
||||
FBFFFFFRLL
|
||||
FFBFBFFRLL
|
||||
FFFBBFFRLR
|
||||
FBBFBFFRRL
|
||||
FBBBBBBRRR
|
||||
BFBFBBBLRL
|
||||
BBFFFFBRRR
|
||||
FFBFFBBLRL
|
||||
FBBBBBBLLR
|
||||
FFBBFFFLRL
|
||||
FBBBFBBLRR
|
||||
FFBBBBBRLR
|
||||
BFBFFFFLLR
|
||||
BFFBBBBRLL
|
||||
BFBFBFFLRL
|
||||
FBBFFFBLRL
|
||||
BFBFBBBRRL
|
||||
BFBFBFBLRL
|
||||
BFBBFBFLRR
|
||||
BFFFFBFRLR
|
||||
BFFFBFBRLL
|
||||
FBFBFBFLLL
|
||||
FBFFBFFLRL
|
||||
BFFFFFFRRL
|
||||
FBBFBFFRLR
|
||||
FFBBBFFLLR
|
||||
FBBBBFFLRL
|
||||
FBBBFBBRLR
|
||||
BFBBBFFLRL
|
||||
FBFFBBBLRL
|
||||
BFFFFBFRRL
|
||||
BFFFBFFLRR
|
||||
FFBFBBFLRL
|
||||
BFBFFFBLRL
|
||||
BFFFFFBLLL
|
||||
FBFFBFBLLL
|
||||
FBFBBBBRRL
|
||||
FBBFFBBRLR
|
||||
BFFFBBFRRL
|
||||
BFBBFBBRLR
|
||||
FFFBFBBLRR
|
||||
FFFBFBFRLR
|
||||
FBFBFBFRLR
|
||||
BFBFBBBRLR
|
||||
BFFFFBBLLL
|
||||
BFFBBFBRRR
|
||||
BFFBBBFLLL
|
||||
FFBBBFFRRL
|
||||
BFBBBFBLLR
|
||||
FBBFFBBLLR
|
||||
FBBFBBFLRL
|
||||
BFFFFFBRRR
|
||||
FBBBFBBRLL
|
||||
FBFBFFBRRR
|
||||
BFFBBBFRRR
|
||||
FBBBBBBLRL
|
||||
FFBBBFFLRR
|
||||
BFFBBBFRLL
|
||||
BBFFBBFRLL
|
||||
FBBFBBFRLR
|
||||
BFBFBFFRRR
|
||||
BFBFBBFLRL
|
||||
BFFFFBFRLL
|
||||
FFBBFBFLLR
|
||||
BFFBFBBLRR
|
||||
FBFFBBBRRL
|
||||
FBBFBBFRLL
|
||||
FBFFFBBLLR
|
||||
FFFBBBBRRR
|
||||
FFFFBBBLRL
|
||||
FFBBFFFRRL
|
||||
BFFBBFFRRL
|
||||
BFFFBBFLRL
|
||||
BFFFFBBLRR
|
||||
BBFFBBBLRR
|
||||
BFBFFFFLRR
|
||||
FBFBBBBLLL
|
||||
BBFFFBBLRR
|
||||
FFFBFBFLRR
|
||||
FBBFFFFLRL
|
||||
FFBBBBFRLL
|
||||
FBFFBFBLRL
|
||||
BFBBFBBLLL
|
||||
FBBFBBFLLL
|
||||
FFBFFBBRLL
|
||||
BFBFFFFRLR
|
||||
FBFFBBFRRR
|
||||
FFFBBFFRRR
|
||||
FFFBFFBRLR
|
||||
FBBBBBFLLL
|
||||
FBBBFFFLRL
|
||||
FFBBFFFLRR
|
||||
FFFBBBBRRL
|
||||
BFBFBBFRLL
|
||||
BFBFFBBRRL
|
||||
FBBFBBFRRL
|
||||
BFBFBBFLLR
|
||||
BBFFBBBRRR
|
||||
BFFFBBFRLR
|
||||
FFFBBBFRLR
|
||||
BFFBFFFRLL
|
||||
BFBFFFFRRL
|
||||
FFBBFFFLLL
|
||||
FBFBBBBLRR
|
||||
FBFBFFFLRR
|
||||
BBFFBFFLRR
|
||||
FBBBFBBLRL
|
||||
BFBFBFBLLL
|
||||
FBFBFFFLLR
|
||||
BFFBBFBLRR
|
||||
FBBFFFBRRL
|
||||
BFFBBFFRRR
|
||||
FBBFBBBRRL
|
||||
BFFFFBBLLR
|
||||
FFBBBBFLLL
|
||||
BFFBFFBRRR
|
||||
BFFFFBFRRR
|
||||
FFFBBBFRRR
|
||||
FBFBFFFRLR
|
||||
FBBBFBFLLR
|
||||
FFBBFFBRLL
|
||||
FBFBFFFLLL
|
||||
BFFBFBFRRL
|
||||
BFBFFBFRRL
|
||||
BFBBBBFLLL
|
||||
FBBBFBFRRL
|
||||
FFBFBFFLLL
|
||||
BFBBFFFRRL
|
||||
FFBBFFBLLR
|
||||
BFFBBBBRLR
|
||||
FFBBBBBLRR
|
||||
BFFBFFFRRL
|
||||
BFFBFBBRLL
|
||||
FBBBFBFRLR
|
||||
FBBFFFFLRR
|
||||
BFFFBBFLLR
|
||||
FFFBBFBRRL
|
||||
FFBBFFBLRR
|
||||
FBBFFFBRLR
|
||||
BFBBBBBRLL
|
||||
BBFFFFFRRL
|
||||
FFBFFBBRRL
|
||||
BFBFFBFLLR
|
||||
FBFBBBFLLL
|
||||
FBFFFFFRRL
|
||||
BFFFBFBLRR
|
||||
FBFFFFBLLR
|
||||
FBBFBFBRRR
|
||||
FBBBFFFLLR
|
||||
BBFFBFBLRR
|
||||
BBFFFBFLLL
|
||||
FBFFFBFRLR
|
||||
BFFFBFFLRL
|
||||
BBFFBFFLRL
|
||||
BFFFFFFLLR
|
||||
BBFFBBBLLL
|
||||
FFBFBBBLLR
|
||||
FBBFBBBLRL
|
||||
BFBBFBBLRR
|
||||
FFBFBFBLLR
|
||||
FFBFBFBRRL
|
||||
BFBBFBBRRL
|
||||
BFFBFFFLLR
|
||||
FFBBFFBRRL
|
||||
BBFFBBBRRL
|
||||
FFFBBFBRLR
|
||||
BFBBFBFRRR
|
||||
BFFFFFFRRR
|
||||
FBBBFFBLLL
|
||||
BFBFFFFLLL
|
||||
BBFFBFBLLR
|
||||
BFBFBBFRLR
|
||||
FFBFBBBRRR
|
||||
BFFFBBFLLL
|
||||
FBFFBBFRLL
|
||||
FFBBFBFRLL
|
||||
BFBFBBBLLR
|
||||
FBBFBFBLLL
|
||||
BBFFFFBRLL
|
||||
BBFFBFBLLL
|
||||
BFFBFFBLRR
|
||||
BFFBBFBLLL
|
||||
FFBFFFBLRR
|
||||
FBBFFBFRRL
|
||||
FBBBBFBLLL
|
||||
FFBFFBBLLR
|
||||
BFFBBBFLRR
|
||||
FBFBFFBRLL
|
||||
FFBFFFBRLL
|
||||
FFBFFBFLLL
|
||||
FBFBBFBLRL
|
||||
FBBFBFFRRR
|
||||
BFBFBFFLLR
|
||||
FBBFFFBLLR
|
||||
BFBBBBFRRR
|
||||
FBBFBBFRRR
|
||||
BBFFBFFRLR
|
||||
FBFBBBFRLL
|
||||
FBBFBBBLLR
|
||||
BFFFFFFLRL
|
||||
BFBFFBBRRR
|
||||
BFFFBFFRLL
|
||||
BFBBFBFLRL
|
||||
FFBFFFFRRR
|
||||
BFFBBFFRLR
|
||||
FBBBBBFLLR
|
||||
FBFBFFBLRL
|
||||
FFFBBFBLLR
|
||||
FBBFBFBLLR
|
||||
FFFBFFBRRR
|
||||
FBFFFFFRLR
|
||||
FBFBBFBRLR
|
||||
FBBBFBFLRR
|
||||
FBFBBBFLRL
|
||||
BFFBFFFLRL
|
||||
FFBBBFFRRR
|
||||
FFBBBBBLLL
|
||||
FBFFBBFLLR
|
||||
FFBFBFFLRR
|
||||
FFFBBBFLRR
|
||||
BFBFBBFLLL
|
||||
BBFFBFFLLR
|
||||
FFBBFBBRLL
|
||||
FBBFFBBLLL
|
||||
FBFFBFBRLL
|
||||
BFBFBFFLRR
|
||||
FBBBFFBRLR
|
||||
FFBFFBFRLL
|
||||
FFFFBBBLLL
|
||||
FFBFFBBRRR
|
||||
FBBBBFBRLL
|
||||
BFFFFBBRRR
|
||||
FFBBFFFRLL
|
||||
FFBFBFBRLL
|
||||
BBFFFFBLLL
|
||||
FFBBBFBRRL
|
||||
BFFFFBBLRL
|
||||
FBBBFBBLLR
|
||||
FBBBFBBLLL
|
||||
FFBFBFBLRL
|
||||
FBBBBFFRRR
|
||||
FBBFFFFRLR
|
||||
FFBFFFBRLR
|
||||
BFBFBFBRRR
|
||||
FFFBFBBRLL
|
||||
FBBBFFBRRR
|
||||
FBBFBFFRLL
|
||||
BFFBFBFLRR
|
||||
BFBBBFFRRL
|
||||
BFFBBFBLLR
|
||||
FFBBBFBRLL
|
||||
FBFBFBBLRR
|
||||
BFBBFFFLRL
|
||||
BFBFBBFLRR
|
||||
BFBBBFFRRR
|
||||
FBBBFFFRRL
|
||||
FBFBFBFLLR
|
||||
FBBFFFFLLR
|
||||
FFBFBBFRLR
|
||||
FFFBFBBLRL
|
||||
BBFFFBBLLR
|
||||
BFFBBBFRLR
|
||||
FFFFBBBRLR
|
||||
BBFFBBFRLR
|
||||
FBFFFFBRLL
|
||||
FBFBFFFRRR
|
||||
FBFFFBBLLL
|
||||
BFBBBBFRLL
|
||||
FBFBFFBRRL
|
||||
FFFBFFFRLR
|
||||
BFBBFBFRRL
|
||||
FBFFBFFLRR
|
||||
FBFFFBBLRR
|
||||
FFBFBBBRLR
|
||||
FBBFBFFLRR
|
||||
FBFFFBBRRR
|
||||
FFBFBBBRLL
|
||||
FFBBBBBRRR
|
||||
BFFBBFFLLL
|
||||
BFBBBBBRRL
|
||||
BBFFBBBRLL
|
||||
FBFFFFFLRL
|
||||
BFFBBFFLRR
|
||||
FBFFBBFLRL
|
||||
BFBFFBFRRR
|
||||
FBFBBFBRLL
|
||||
BFFFBFBRRL
|
||||
FBBFFBFLLR
|
||||
BFFFFFFLLL
|
||||
FBFBFBFRLL
|
||||
FBBBBFFRRL
|
||||
BFBFFBBLLR
|
||||
FBBFBFBRRL
|
||||
FFFBFFFLLR
|
||||
FFBBBBBLRL
|
||||
FFBFFBBLRR
|
||||
FFFBFBFRRR
|
||||
BFBBFBBRLL
|
||||
BFBBBFBLRR
|
||||
FFBBBBFLRR
|
||||
FBBBFFBLLR
|
||||
BBFFBBBLLR
|
||||
FBFBBFFRRL
|
||||
FBBBBBFLRL
|
||||
FFFBBFFRRL
|
||||
BFFBBBBLRR
|
||||
FFFFBBBLRR
|
||||
FFFFBBFLRR
|
||||
FBFFFBFLLL
|
||||
FBFBFBBLLR
|
||||
BFFBBBBLLL
|
||||
FFBFFFFRLR
|
||||
BFBBFFBLRR
|
||||
FFBBFBFLRL
|
||||
BFBFBFFLLL
|
||||
BFFBFBBLLR
|
||||
BFBBFBBLRL
|
||||
FFBBBBFLRL
|
||||
FBBBFFFLLL
|
||||
FFFBFFBRRL
|
||||
BFFFFBBRLL
|
||||
BFFFBBBRLL
|
||||
BFFBFFFLRR
|
||||
FFBFBFBRRR
|
||||
BBFFBBFLLR
|
||||
FFBBFBBLLR
|
||||
FFBFFBFRRR
|
||||
FFBBBFFRLR
|
||||
BFFBBBBLLR
|
||||
FFFBFFFLRR
|
||||
FBFFFFFLLR
|
||||
FBFFBBBLLL
|
||||
BBFFBBFLLL
|
||||
FFBBFBFLRR
|
||||
BFFBFBFLRL
|
||||
FBFBBBFRRR
|
||||
BFBBFBBLLR
|
||||
FBFFFFBRRL
|
||||
FFFBBFBLRR
|
||||
BBFFFFBLRR
|
||||
BFBBBBFRRL
|
||||
FFBBBFBLLL
|
||||
BFBBFBFRLR
|
||||
BFBBFFBRRL
|
||||
BFBFBFFRRL
|
||||
FBBFFBBLRL
|
||||
FFFBFFBLRL
|
||||
BFFBBFFRLL
|
||||
FBBBFFFRLL
|
||||
FBBFBBFLLR
|
||||
FFBFFFFLLR
|
||||
FBBBFBFLRL
|
||||
BFFFBBBLLR
|
||||
FBFBBBBRRR
|
||||
FBBFBFBRLR
|
||||
FFFBFBFLLR
|
||||
FFFFBBFRRR
|
||||
FFFBBFFLRL
|
||||
BFBFFBFRLL
|
||||
FFFBFFBLLR
|
||||
FBBFFFBRLL
|
||||
FFBBBFBRRR
|
||||
FFBBFBBRLR
|
||||
BBFFFFFRRR
|
||||
FFBFFFFRLL
|
||||
FBBFFBBRRL
|
||||
BBFFFBFLRR
|
||||
FBBFFFFRRR
|
||||
FFBFFFBRRL
|
||||
BFBBFBFLLL
|
||||
BFFFFBFLRR
|
||||
BBFFFFFLLL
|
||||
FFBBFBBRRL
|
||||
FFBFBFFLRL
|
||||
FBFFBBFRRL
|
||||
BBFFBFBRLR
|
||||
BBFFBBFLRR
|
||||
FBFFBFBRRR
|
||||
FBBFBBFLRR
|
||||
FBFFFBFRLL
|
||||
BFBFFFFLRL
|
||||
FFFBBFBRRR
|
||||
BFBBBBBLLR
|
||||
FBBFFBBRRR
|
||||
FFBBBFFLLL
|
||||
FBBBBFBLLR
|
||||
BBFFFFFRLL
|
||||
FFBBBBFRLR
|
||||
FBFBFBBRRR
|
||||
FBFFBFFLLL
|
||||
FBFFBBBLLR
|
||||
FBBBBFBRRL
|
||||
BFBFBFFRLR
|
||||
FBBFBBBRLL
|
||||
BFBBFFFRLL
|
||||
FBBBFBFLLL
|
||||
FFBFFFFRRL
|
||||
FBFBBFFRRR
|
||||
FBFFFFBLLL
|
||||
FBBBBBBRLL
|
||||
BFFBFBBRRR
|
||||
BBFFBBFRRL
|
||||
FBBFBFFLRL
|
||||
FBFFFFBRRR
|
||||
FBBFFFFRLL
|
||||
FFFBFFFRRR
|
||||
FBFFBBFLLL
|
||||
BFFFFBFLLL
|
||||
BFFFFBFLLR
|
||||
FFBFFBFLLR
|
||||
FFBFFBFLRR
|
||||
BFFBBBBLRL
|
||||
FFBBFFBLLL
|
||||
FBBFBBBLLL
|
||||
FBFBBBFLLR
|
||||
BFFBBBFLRL
|
||||
BFBBFFBRLL
|
||||
FBFFBFFRRR
|
||||
FFBFFFBLRL
|
||||
FFFBBBFRRL
|
||||
FFBFBBFLRR
|
||||
FFFBBBBLRL
|
||||
FFFBBFFLLL
|
||||
FFFBFBBRRR
|
||||
FBBFBFFLLL
|
||||
BFFFBBBLLL
|
||||
BFFBFFFRLR
|
||||
FFFBBBBLLL
|
||||
BFFFFFBRRL
|
||||
FFBBFFFLLR
|
||||
BFBBFFFRRR
|
||||
BFBFFBFLRR
|
||||
FFFBBBFLLR
|
||||
FBFBBBFLRR
|
||||
BBFFBBBRLR
|
||||
FBFBBFFLRR
|
||||
FFBBBFBLRL
|
||||
FFFBBBFRLL
|
||||
BFFBFFBRLR
|
||||
BBFFFBBRRR
|
||||
BFBBBBFLRL
|
||||
BFBBBFBRRR
|
||||
FBBBBFFLLL
|
||||
FFFBFBBLLL
|
||||
BBFFFFFRLR
|
||||
BBFFBFFLLL
|
||||
FFBFBBBLRL
|
||||
FFBBFBFRLR
|
||||
BFBBBBBLRR
|
||||
FFBFFFBLLR
|
||||
FFBFFBFLRL
|
||||
BFFBFBBRLR
|
||||
FBFBFFFRRL
|
||||
FBBBFFFLRR
|
||||
FFFBBFFLLR
|
||||
FBBBBFFRLR
|
||||
FFBBFBBRRR
|
||||
BFBBFBBRRR
|
||||
BFBFBBFRRL
|
||||
BFFBBBFRRL
|
||||
FFFBFFFLLL
|
||||
FBBFFBFLRL
|
||||
FFFBFBBRLR
|
||||
BFBBFFFLLR
|
||||
BFBBFFBRRR
|
||||
FBFFBFBRRL
|
||||
FFBBBBBRLL
|
||||
BFFBFFBLLL
|
||||
BFFFBBFRRR
|
||||
FBFFFBFRRR
|
||||
FFBFBFBRLR
|
||||
FBFBBFFLLR
|
||||
FBBFBBBRRR
|
||||
BFBFFFFRRR
|
||||
FFBFFFFLLL
|
||||
FBFBBFFRLL
|
||||
BFBFFBFLRL
|
||||
BFBBFFFLLL
|
||||
FBFBBFBRRR
|
||||
BFBFFFBLLR
|
||||
BFBFFFBLLL
|
||||
BBFFFBFLLR
|
||||
BBFFBFFRLL
|
||||
FFBBBBFRRL
|
||||
BBFFFBFLRL
|
||||
BBFFBBBLRL
|
||||
BFBFFFBLRR
|
||||
FFFBFBFRLL
|
||||
BFBFFBBLLL
|
||||
BBFFFBBRRL
|
||||
BFBBBFFLLL
|
||||
BFFBBFFLLR
|
||||
FFBFFBBLLL
|
||||
BFFBBFBRRL
|
||||
BFFFFFBLRL
|
||||
BBFFFFBRLR
|
||||
FBFBBFFLLL
|
||||
FFBBBFBRLR
|
||||
FFFBBFBLLL
|
||||
FBFFFBBRLR
|
||||
FFBFBFFRLR
|
||||
BFFFFFBLRR
|
||||
FFFBBBBRLL
|
||||
FFBBFFFRRR
|
||||
BFFFFFBRLR
|
||||
FBBBFFBLRR
|
||||
FBFBFBBRLR
|
||||
FBBFFFBLRR
|
||||
BFBFFBBLRL
|
||||
FBFFBFBRLR
|
||||
FBFBFFFLRL
|
||||
BFFFFFBRLL
|
||||
BFBBBBFLRR
|
||||
BFFBFFFLLL
|
||||
FBFFBFFRRL
|
||||
FFFBBFFRLL
|
||||
BFFFBFFRRR
|
||||
FBFFBFFLLR
|
||||
FFFBBBFLLL
|
||||
FBFFFBFLRR
|
||||
BFFBFBBLLL
|
||||
BFFFBBBLRR
|
||||
FBBBBBBRRL
|
||||
FBFFBFFRLR
|
||||
FBBFFBBRLL
|
||||
FBBBFFFRRR
|
||||
BFFBFBBRRL
|
||||
FFBBFFBRRR
|
||||
BFBBBFFLRR
|
||||
FFFBFBBRRL
|
||||
BFBFBBBLRR
|
||||
FFFBBFBLRL
|
||||
FBFFBBFRLR
|
||||
BFFFBBFLRR
|
||||
BBFFFBBLRL
|
||||
FBBFFBFRLR
|
||||
FFFBFBFLLL
|
||||
FFFBFFFRRL
|
||||
BBFBFFFLLL
|
||||
FBFBFBFLRR
|
||||
BFBFFFFRLL
|
25
2020/d06/ex1/ex1.py
Executable file
25
2020/d06/ex1/ex1.py
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict, List, Set
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
answers: DefaultDict[int, Set[str]] = defaultdict(set)
|
||||
group = 0
|
||||
for line in raw:
|
||||
if line == "":
|
||||
group += 1
|
||||
continue
|
||||
answers[group] |= {char for char in line}
|
||||
return sum(len(answer) for answer in answers.values())
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
2246
2020/d06/ex1/input
Normal file
2246
2020/d06/ex1/input
Normal file
File diff suppressed because it is too large
Load diff
31
2020/d06/ex2/ex2.py
Executable file
31
2020/d06/ex2/ex2.py
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from typing import DefaultDict, List, Set
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
answers: DefaultDict[int, Set[str]] = defaultdict(set)
|
||||
group = 0
|
||||
first = True
|
||||
for line in raw:
|
||||
if line == "":
|
||||
group += 1
|
||||
first = True
|
||||
continue
|
||||
if not first:
|
||||
answers[group] &= {char for char in line}
|
||||
else:
|
||||
answers[group] = {char for char in line}
|
||||
first = False
|
||||
return sum(len(answer) for answer in answers.values())
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
2246
2020/d06/ex2/input
Normal file
2246
2020/d06/ex2/input
Normal file
File diff suppressed because it is too large
Load diff
77
2020/d07/ex1/ex1.py
Executable file
77
2020/d07/ex1/ex1.py
Executable file
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Set, Tuple
|
||||
|
||||
|
||||
@dataclass(eq=True, frozen=True) # Hashable
|
||||
class ColorInfo:
|
||||
num: int
|
||||
color: str
|
||||
|
||||
|
||||
Graph = Dict[str, Set[ColorInfo]]
|
||||
|
||||
|
||||
def extract_info(line: str) -> Tuple[str, Set[ColorInfo]]:
|
||||
color_pattern = re.compile("(.*) contain ")
|
||||
match = color_pattern.search(line)
|
||||
assert match is not None
|
||||
color = match.group(1).replace("bags", "bag")
|
||||
|
||||
line = line[match.end() : -1] # Remove period at end of line
|
||||
|
||||
if line == "no other bags":
|
||||
return color, set()
|
||||
|
||||
colors: Set[ColorInfo] = set()
|
||||
pattern = re.compile("([0-9]+) (.*)")
|
||||
for col in line.split(", "):
|
||||
match = pattern.search(col)
|
||||
assert match is not None
|
||||
colors |= {
|
||||
ColorInfo(int(match.group(1)), match.group(2).replace("bags", "bag"))
|
||||
}
|
||||
|
||||
return color, colors
|
||||
|
||||
|
||||
def to_graph(raw: List[str]) -> Graph:
|
||||
return {color: inside for color, inside in map(extract_info, raw)}
|
||||
|
||||
|
||||
def reverse(graph: Graph) -> Graph:
|
||||
reverse: Graph = defaultdict(set)
|
||||
|
||||
for color, contained in graph.items():
|
||||
for col in contained:
|
||||
reverse[col.color] |= {ColorInfo(-1, color)}
|
||||
|
||||
return reverse
|
||||
|
||||
|
||||
def containing(graph: Graph, col: str) -> Set[ColorInfo]:
|
||||
res = deepcopy(graph[col])
|
||||
for contains in graph[col]:
|
||||
res |= containing(graph, contains.color)
|
||||
return res
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
graph = to_graph(raw)
|
||||
reverse_graph = reverse(graph)
|
||||
|
||||
return len(containing(reverse_graph, "shiny gold bag"))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
594
2020/d07/ex1/input
Normal file
594
2020/d07/ex1/input
Normal file
|
@ -0,0 +1,594 @@
|
|||
shiny aqua bags contain 1 dark white bag.
|
||||
muted blue bags contain 1 vibrant lavender bag, 4 dotted silver bags, 2 dim indigo bags.
|
||||
drab gray bags contain 5 mirrored white bags, 1 light green bag, 5 shiny lavender bags, 5 faded aqua bags.
|
||||
muted indigo bags contain 4 muted chartreuse bags, 2 dotted teal bags.
|
||||
drab white bags contain 2 dull fuchsia bags, 1 vibrant bronze bag.
|
||||
dim lavender bags contain 4 muted tan bags.
|
||||
dotted tomato bags contain 1 mirrored lime bag, 2 vibrant white bags.
|
||||
clear orange bags contain 5 clear violet bags, 2 dull beige bags, 2 dark chartreuse bags.
|
||||
bright lime bags contain no other bags.
|
||||
striped brown bags contain 3 bright orange bags.
|
||||
vibrant green bags contain 3 shiny fuchsia bags.
|
||||
plaid tomato bags contain 3 faded chartreuse bags, 2 wavy salmon bags, 1 faded white bag, 3 mirrored maroon bags.
|
||||
drab beige bags contain 2 shiny bronze bags, 4 pale violet bags, 3 bright tomato bags, 4 pale red bags.
|
||||
posh green bags contain 2 dull lavender bags, 4 clear plum bags, 2 dark gray bags.
|
||||
dull maroon bags contain 3 dull magenta bags, 1 dull tan bag, 1 faded cyan bag, 5 dull silver bags.
|
||||
faded crimson bags contain 2 muted purple bags, 4 dotted olive bags, 5 drab silver bags.
|
||||
wavy bronze bags contain 3 dark orange bags, 2 dark brown bags, 5 bright silver bags.
|
||||
dark turquoise bags contain 5 dull plum bags.
|
||||
dull lavender bags contain 4 dotted maroon bags, 3 muted brown bags, 4 drab black bags, 4 dull cyan bags.
|
||||
dotted plum bags contain 1 shiny bronze bag, 3 clear brown bags, 3 muted indigo bags.
|
||||
dull white bags contain 3 clear tan bags, 5 shiny gold bags, 2 drab crimson bags.
|
||||
dull teal bags contain 2 bright tomato bags.
|
||||
shiny crimson bags contain 3 light green bags, 5 striped brown bags, 3 faded fuchsia bags.
|
||||
wavy brown bags contain 1 drab crimson bag, 2 wavy indigo bags.
|
||||
dark tan bags contain 2 faded gray bags, 4 shiny salmon bags.
|
||||
shiny red bags contain 4 dull chartreuse bags, 5 pale tomato bags.
|
||||
bright orange bags contain no other bags.
|
||||
wavy yellow bags contain 5 light indigo bags, 5 dark gray bags, 5 plaid indigo bags, 4 faded red bags.
|
||||
faded bronze bags contain 4 faded cyan bags, 5 shiny beige bags, 5 muted red bags.
|
||||
dull bronze bags contain 1 mirrored beige bag, 5 muted violet bags, 1 wavy lime bag.
|
||||
dark lime bags contain 2 drab maroon bags, 5 bright indigo bags, 4 shiny black bags, 5 dotted turquoise bags.
|
||||
drab red bags contain 5 bright red bags, 2 vibrant brown bags.
|
||||
dotted salmon bags contain 3 vibrant turquoise bags, 2 dull beige bags, 3 light turquoise bags.
|
||||
dull gray bags contain 3 striped green bags, 3 wavy coral bags, 1 dark gray bag, 2 light indigo bags.
|
||||
faded black bags contain 4 muted fuchsia bags, 4 wavy coral bags, 1 drab tomato bag.
|
||||
muted magenta bags contain 2 posh chartreuse bags, 4 pale violet bags.
|
||||
light tan bags contain 2 posh turquoise bags, 3 vibrant white bags, 1 light black bag.
|
||||
dark blue bags contain 3 plaid indigo bags, 2 posh black bags.
|
||||
dull indigo bags contain 4 light gray bags, 3 dotted tan bags, 4 dull coral bags.
|
||||
dim fuchsia bags contain 3 vibrant yellow bags, 3 mirrored cyan bags, 4 mirrored brown bags.
|
||||
shiny beige bags contain 2 dull silver bags, 3 bright lime bags, 5 dull magenta bags.
|
||||
light cyan bags contain 3 vibrant violet bags, 2 mirrored tomato bags, 2 vibrant coral bags, 4 mirrored silver bags.
|
||||
clear turquoise bags contain 4 drab tomato bags, 3 shiny gold bags, 4 drab gold bags.
|
||||
pale teal bags contain 2 wavy maroon bags, 2 dotted olive bags, 4 shiny white bags, 2 drab turquoise bags.
|
||||
dark purple bags contain 1 wavy indigo bag, 3 bright black bags, 3 dotted teal bags.
|
||||
bright white bags contain 5 wavy red bags, 2 mirrored cyan bags, 3 drab green bags.
|
||||
mirrored aqua bags contain 1 faded violet bag, 5 dotted purple bags.
|
||||
shiny lime bags contain 4 dark aqua bags.
|
||||
pale bronze bags contain 1 clear crimson bag.
|
||||
vibrant white bags contain 5 plaid lavender bags, 1 drab red bag, 4 vibrant brown bags.
|
||||
plaid tan bags contain 5 dim crimson bags.
|
||||
posh olive bags contain 3 bright red bags.
|
||||
plaid brown bags contain 5 vibrant turquoise bags.
|
||||
mirrored tomato bags contain 2 dotted chartreuse bags, 3 light aqua bags, 3 posh beige bags.
|
||||
plaid blue bags contain 5 striped green bags, 1 plaid purple bag, 4 muted gold bags.
|
||||
shiny tan bags contain 5 striped coral bags, 1 dull brown bag.
|
||||
shiny gold bags contain 1 dull magenta bag, 5 dark white bags, 4 faded turquoise bags.
|
||||
dull salmon bags contain 2 plaid gold bags, 2 light indigo bags.
|
||||
striped tomato bags contain 2 striped tan bags, 4 light blue bags, 4 drab tan bags.
|
||||
drab tomato bags contain 3 dim teal bags, 4 striped yellow bags, 3 bright red bags.
|
||||
faded olive bags contain 1 drab plum bag, 1 pale aqua bag, 3 light blue bags.
|
||||
dotted indigo bags contain 2 clear tomato bags.
|
||||
dark white bags contain 5 light aqua bags, 2 dim teal bags, 2 muted fuchsia bags, 5 light purple bags.
|
||||
dull orange bags contain 4 pale gold bags, 5 posh brown bags, 2 mirrored brown bags, 3 dark bronze bags.
|
||||
bright maroon bags contain 1 mirrored yellow bag, 4 light teal bags.
|
||||
bright silver bags contain 1 vibrant coral bag, 3 dim teal bags, 5 light purple bags.
|
||||
muted olive bags contain 5 plaid orange bags, 1 muted magenta bag.
|
||||
dull silver bags contain no other bags.
|
||||
pale maroon bags contain 2 pale bronze bags.
|
||||
light gray bags contain 4 vibrant yellow bags, 2 pale red bags.
|
||||
drab teal bags contain 2 light crimson bags, 3 vibrant brown bags, 3 vibrant tan bags.
|
||||
bright gold bags contain 1 wavy red bag, 5 wavy coral bags.
|
||||
plaid chartreuse bags contain 2 dim coral bags, 4 drab silver bags, 5 dim chartreuse bags, 3 light purple bags.
|
||||
clear blue bags contain 2 pale tomato bags, 4 dull gold bags, 4 dim fuchsia bags, 4 pale coral bags.
|
||||
vibrant purple bags contain 5 faded orange bags.
|
||||
plaid aqua bags contain 3 muted cyan bags, 2 wavy gray bags, 4 drab green bags, 4 pale beige bags.
|
||||
muted lime bags contain 1 muted tan bag.
|
||||
faded coral bags contain 3 drab turquoise bags, 1 shiny plum bag, 5 mirrored green bags, 5 clear white bags.
|
||||
vibrant lime bags contain 5 posh coral bags.
|
||||
faded green bags contain 3 pale orange bags, 5 dull turquoise bags, 1 mirrored crimson bag.
|
||||
mirrored gray bags contain 5 dim indigo bags.
|
||||
wavy maroon bags contain 4 mirrored bronze bags, 1 striped olive bag, 2 dull salmon bags, 3 shiny crimson bags.
|
||||
dark violet bags contain 2 light purple bags.
|
||||
dark green bags contain 2 dim cyan bags.
|
||||
pale black bags contain 1 mirrored gold bag.
|
||||
bright yellow bags contain 2 vibrant crimson bags, 3 plaid lime bags, 2 dotted gold bags.
|
||||
muted teal bags contain 1 pale violet bag, 4 dull silver bags.
|
||||
dim beige bags contain 5 wavy red bags.
|
||||
muted purple bags contain 4 clear cyan bags.
|
||||
plaid fuchsia bags contain 3 dark coral bags.
|
||||
plaid bronze bags contain 5 plaid orange bags, 2 drab indigo bags.
|
||||
faded indigo bags contain 1 dark chartreuse bag, 4 dull green bags, 1 mirrored magenta bag.
|
||||
posh plum bags contain 3 dark chartreuse bags, 3 dotted turquoise bags, 4 dull maroon bags, 1 posh bronze bag.
|
||||
pale gold bags contain 4 striped brown bags.
|
||||
mirrored chartreuse bags contain 4 bright silver bags, 3 mirrored tomato bags, 4 wavy orange bags.
|
||||
pale orange bags contain 2 posh fuchsia bags, 2 clear salmon bags, 2 bright green bags.
|
||||
clear brown bags contain 4 light lime bags, 4 bright green bags, 5 pale yellow bags, 2 drab cyan bags.
|
||||
shiny plum bags contain 5 vibrant gray bags, 3 bright blue bags, 5 dark tomato bags.
|
||||
wavy white bags contain 4 plaid lime bags, 4 posh maroon bags, 5 drab lime bags, 1 vibrant crimson bag.
|
||||
faded red bags contain 1 dull coral bag, 5 clear cyan bags, 4 plaid chartreuse bags, 3 plaid orange bags.
|
||||
plaid red bags contain 5 pale blue bags, 4 light crimson bags, 3 faded fuchsia bags.
|
||||
bright cyan bags contain 3 dark white bags, 2 light crimson bags, 1 bright aqua bag.
|
||||
muted lavender bags contain 1 light green bag, 4 striped silver bags, 3 posh crimson bags.
|
||||
wavy crimson bags contain 1 light purple bag, 4 bright blue bags, 2 dull coral bags, 1 wavy beige bag.
|
||||
faded aqua bags contain 5 muted brown bags.
|
||||
mirrored fuchsia bags contain 1 faded beige bag, 3 muted gold bags.
|
||||
dark chartreuse bags contain 5 bright lime bags.
|
||||
plaid green bags contain 4 mirrored tan bags, 1 mirrored tomato bag, 5 pale indigo bags, 1 mirrored plum bag.
|
||||
shiny black bags contain 3 plaid chartreuse bags.
|
||||
dotted purple bags contain 2 dim teal bags.
|
||||
faded tan bags contain 2 bright fuchsia bags, 5 shiny fuchsia bags, 1 muted fuchsia bag, 1 mirrored brown bag.
|
||||
drab brown bags contain 1 striped orange bag, 4 dotted tomato bags.
|
||||
dull olive bags contain 1 striped black bag, 1 vibrant magenta bag.
|
||||
mirrored plum bags contain 1 clear gold bag, 5 pale green bags.
|
||||
dim tomato bags contain 4 drab gold bags, 2 shiny aqua bags.
|
||||
light lavender bags contain 1 muted violet bag.
|
||||
dim gray bags contain 3 light purple bags, 1 posh crimson bag, 1 faded brown bag.
|
||||
muted aqua bags contain 4 dull beige bags, 4 dull red bags.
|
||||
faded silver bags contain 1 mirrored cyan bag.
|
||||
shiny green bags contain 5 dull maroon bags.
|
||||
muted chartreuse bags contain 2 clear tan bags.
|
||||
plaid plum bags contain 1 dotted lime bag, 4 clear brown bags, 4 dull red bags.
|
||||
dotted silver bags contain 1 posh coral bag.
|
||||
dim crimson bags contain 4 faded violet bags, 1 striped silver bag.
|
||||
bright brown bags contain 1 bright coral bag, 3 posh brown bags, 4 drab tan bags.
|
||||
wavy cyan bags contain 3 clear gold bags, 1 mirrored salmon bag, 3 bright fuchsia bags, 2 light bronze bags.
|
||||
dull violet bags contain 5 striped white bags, 4 light blue bags, 4 dim black bags.
|
||||
vibrant olive bags contain 2 vibrant coral bags.
|
||||
bright coral bags contain 2 vibrant tan bags, 3 shiny indigo bags, 2 plaid indigo bags.
|
||||
dim turquoise bags contain 1 pale violet bag.
|
||||
striped crimson bags contain 2 faded gray bags.
|
||||
clear green bags contain 3 mirrored olive bags, 3 shiny tomato bags.
|
||||
faded violet bags contain 2 wavy coral bags, 2 dull tan bags, 1 dull silver bag, 1 bright orange bag.
|
||||
pale chartreuse bags contain 4 shiny crimson bags, 2 clear bronze bags.
|
||||
light plum bags contain 3 drab bronze bags, 1 bright bronze bag, 1 posh yellow bag.
|
||||
pale tomato bags contain 1 dim teal bag, 5 drab cyan bags, 3 muted coral bags, 2 dim chartreuse bags.
|
||||
plaid coral bags contain 1 striped tan bag, 3 vibrant cyan bags, 3 light beige bags, 2 dotted green bags.
|
||||
bright gray bags contain 4 mirrored teal bags, 4 striped brown bags, 1 dim green bag, 4 clear cyan bags.
|
||||
drab fuchsia bags contain 2 mirrored salmon bags, 4 posh orange bags, 3 faded crimson bags, 3 pale plum bags.
|
||||
light tomato bags contain 2 dotted gold bags, 1 dotted bronze bag.
|
||||
muted violet bags contain 2 light chartreuse bags.
|
||||
drab tan bags contain 2 light green bags, 5 bright red bags, 4 shiny beige bags.
|
||||
drab chartreuse bags contain 2 drab salmon bags, 2 dark brown bags, 4 clear turquoise bags.
|
||||
drab violet bags contain 4 faded red bags.
|
||||
posh cyan bags contain 4 bright violet bags.
|
||||
posh orange bags contain 4 pale plum bags, 5 posh aqua bags.
|
||||
plaid silver bags contain 1 dotted brown bag, 3 drab gold bags, 4 clear yellow bags.
|
||||
mirrored silver bags contain 3 shiny beige bags, 1 drab silver bag.
|
||||
faded gray bags contain no other bags.
|
||||
wavy tomato bags contain 1 bright brown bag, 3 striped red bags, 2 vibrant maroon bags.
|
||||
posh violet bags contain 2 dim aqua bags.
|
||||
bright blue bags contain 5 light lime bags, 2 faded violet bags, 3 light aqua bags, 4 vibrant coral bags.
|
||||
dark teal bags contain 5 muted fuchsia bags.
|
||||
striped fuchsia bags contain 1 wavy turquoise bag, 5 wavy green bags, 4 posh gold bags.
|
||||
posh maroon bags contain 2 dull red bags.
|
||||
shiny purple bags contain 2 clear tan bags.
|
||||
wavy lime bags contain 2 dark coral bags, 1 shiny gold bag.
|
||||
wavy silver bags contain 4 dotted white bags.
|
||||
shiny silver bags contain 2 plaid gold bags, 2 dim green bags, 5 plaid lime bags, 3 dull red bags.
|
||||
wavy red bags contain 3 vibrant brown bags, 4 bright indigo bags.
|
||||
dull chartreuse bags contain 4 dotted lime bags, 2 bright silver bags, 3 dull red bags, 4 wavy maroon bags.
|
||||
vibrant silver bags contain 1 bright fuchsia bag, 3 drab lavender bags, 2 drab olive bags, 3 dotted teal bags.
|
||||
striped gray bags contain 5 plaid orange bags, 1 wavy coral bag.
|
||||
striped green bags contain 4 wavy coral bags, 4 shiny gold bags, 3 dark brown bags, 5 vibrant brown bags.
|
||||
mirrored violet bags contain 3 dim silver bags, 1 posh tomato bag, 1 light salmon bag.
|
||||
dull purple bags contain 1 light gray bag, 3 wavy yellow bags, 1 wavy salmon bag.
|
||||
mirrored beige bags contain 4 dark cyan bags, 5 dull green bags.
|
||||
posh lime bags contain 3 posh chartreuse bags.
|
||||
vibrant tan bags contain 2 dull plum bags, 1 striped brown bag, 4 vibrant coral bags.
|
||||
dotted orange bags contain 1 mirrored olive bag, 5 drab silver bags.
|
||||
clear indigo bags contain 3 light lime bags, 4 dull coral bags.
|
||||
pale gray bags contain 1 faded black bag, 3 dim green bags, 4 wavy lavender bags, 2 posh brown bags.
|
||||
posh gold bags contain 5 dark tan bags, 2 dotted olive bags, 5 dark aqua bags.
|
||||
striped chartreuse bags contain 2 dull magenta bags, 1 posh tomato bag.
|
||||
mirrored bronze bags contain 2 faded fuchsia bags.
|
||||
clear salmon bags contain 4 posh bronze bags, 5 clear plum bags, 5 dull blue bags.
|
||||
posh purple bags contain 5 dim gray bags, 3 faded brown bags.
|
||||
faded lime bags contain 5 dim turquoise bags, 3 dark indigo bags, 2 vibrant gray bags, 1 muted silver bag.
|
||||
wavy beige bags contain 1 dark bronze bag, 4 dull plum bags, 4 mirrored silver bags.
|
||||
clear yellow bags contain 2 vibrant teal bags.
|
||||
vibrant plum bags contain 4 muted chartreuse bags, 4 posh silver bags.
|
||||
striped yellow bags contain 2 dull maroon bags, 5 bright red bags, 2 posh chartreuse bags.
|
||||
dark coral bags contain 3 dull tan bags.
|
||||
dull magenta bags contain no other bags.
|
||||
dark gold bags contain 1 dotted indigo bag, 4 shiny teal bags, 4 dotted silver bags.
|
||||
dim tan bags contain 1 striped lavender bag, 1 shiny tomato bag.
|
||||
muted maroon bags contain 2 dull salmon bags, 4 dim chartreuse bags, 3 bright aqua bags, 2 faded indigo bags.
|
||||
vibrant tomato bags contain 2 dark silver bags, 3 plaid purple bags.
|
||||
dotted lime bags contain 3 shiny crimson bags, 2 pale yellow bags.
|
||||
muted fuchsia bags contain 1 dull tan bag.
|
||||
bright tan bags contain 5 pale gold bags, 5 drab teal bags, 2 light blue bags.
|
||||
dark crimson bags contain 4 shiny orange bags, 3 faded purple bags, 3 bright white bags.
|
||||
striped tan bags contain 4 dotted turquoise bags, 4 drab lime bags, 5 dim teal bags.
|
||||
posh fuchsia bags contain 2 dotted olive bags, 2 mirrored beige bags, 3 shiny bronze bags.
|
||||
pale silver bags contain 4 vibrant lavender bags, 4 clear beige bags, 4 striped gold bags.
|
||||
posh aqua bags contain 4 drab lime bags, 4 dull tan bags, 5 vibrant tan bags.
|
||||
plaid salmon bags contain 5 dim coral bags, 2 wavy bronze bags.
|
||||
mirrored orange bags contain 4 vibrant gray bags.
|
||||
dim yellow bags contain 5 pale tan bags, 4 dark black bags.
|
||||
dotted coral bags contain 4 dotted chartreuse bags, 2 bright red bags, 1 vibrant white bag, 1 vibrant brown bag.
|
||||
muted crimson bags contain 4 striped orange bags, 5 pale yellow bags, 3 posh blue bags, 1 muted red bag.
|
||||
striped lavender bags contain 3 striped brown bags.
|
||||
striped maroon bags contain 2 shiny yellow bags.
|
||||
vibrant blue bags contain 3 faded cyan bags, 1 shiny lime bag, 3 dark tomato bags.
|
||||
pale lavender bags contain 4 plaid magenta bags, 4 striped blue bags.
|
||||
dull tan bags contain 4 shiny indigo bags, 2 light purple bags, 4 faded cyan bags.
|
||||
dotted beige bags contain 3 drab indigo bags.
|
||||
light indigo bags contain 1 faded cyan bag, 5 bright aqua bags, 1 shiny indigo bag.
|
||||
vibrant crimson bags contain 4 dotted fuchsia bags.
|
||||
wavy blue bags contain 4 wavy teal bags, 1 dull blue bag.
|
||||
vibrant chartreuse bags contain 4 striped orange bags.
|
||||
vibrant cyan bags contain 5 wavy coral bags.
|
||||
faded brown bags contain 5 faded turquoise bags.
|
||||
faded magenta bags contain 1 dull indigo bag, 4 plaid aqua bags, 4 dim crimson bags.
|
||||
mirrored coral bags contain 4 drab crimson bags, 2 light salmon bags, 2 clear indigo bags.
|
||||
faded cyan bags contain no other bags.
|
||||
dark brown bags contain 5 light purple bags.
|
||||
wavy violet bags contain 3 dull coral bags, 1 bright aqua bag, 3 shiny lavender bags.
|
||||
posh tomato bags contain 4 vibrant chartreuse bags, 4 mirrored teal bags.
|
||||
pale crimson bags contain 1 plaid orange bag, 1 dark violet bag, 3 plaid lavender bags.
|
||||
dark fuchsia bags contain 4 plaid beige bags, 2 plaid chartreuse bags.
|
||||
plaid magenta bags contain 3 clear lavender bags, 5 mirrored brown bags, 5 shiny bronze bags.
|
||||
striped blue bags contain 1 dull bronze bag, 1 dotted fuchsia bag, 1 light lavender bag, 1 clear turquoise bag.
|
||||
dotted olive bags contain 4 dotted turquoise bags, 5 dotted bronze bags, 3 pale yellow bags, 4 pale red bags.
|
||||
posh silver bags contain 3 pale violet bags, 1 plaid salmon bag, 1 posh coral bag.
|
||||
dotted chartreuse bags contain 3 bright blue bags.
|
||||
light coral bags contain 4 shiny fuchsia bags, 2 pale red bags, 1 muted silver bag, 2 bright cyan bags.
|
||||
pale brown bags contain 5 light aqua bags.
|
||||
dotted black bags contain 2 plaid purple bags, 1 mirrored aqua bag, 5 posh beige bags.
|
||||
posh coral bags contain 3 dark aqua bags, 2 pale yellow bags, 5 plaid blue bags, 4 dim aqua bags.
|
||||
shiny gray bags contain 1 bright gold bag, 1 muted bronze bag, 5 striped green bags, 5 shiny teal bags.
|
||||
drab orange bags contain 5 plaid salmon bags, 2 vibrant beige bags.
|
||||
plaid yellow bags contain 4 clear teal bags, 2 bright red bags.
|
||||
striped violet bags contain 4 mirrored fuchsia bags, 4 vibrant white bags, 3 dim teal bags.
|
||||
dim aqua bags contain 1 muted fuchsia bag, 1 dull tan bag.
|
||||
light orange bags contain 2 bright red bags, 4 dark white bags, 1 dim chartreuse bag, 5 faded fuchsia bags.
|
||||
faded salmon bags contain 5 wavy gray bags.
|
||||
shiny yellow bags contain 2 vibrant plum bags, 3 dim teal bags, 1 plaid tan bag, 5 posh plum bags.
|
||||
vibrant beige bags contain 2 wavy lavender bags, 4 posh chartreuse bags, 3 pale teal bags, 5 wavy lime bags.
|
||||
light fuchsia bags contain 3 clear brown bags, 3 bright lavender bags.
|
||||
pale magenta bags contain 4 posh silver bags.
|
||||
dark maroon bags contain 3 drab turquoise bags.
|
||||
faded beige bags contain 1 vibrant white bag, 4 drab red bags, 1 drab lavender bag.
|
||||
bright bronze bags contain 1 pale bronze bag, 3 muted silver bags, 2 striped coral bags, 3 clear gray bags.
|
||||
light silver bags contain 3 dotted lavender bags, 2 wavy lavender bags.
|
||||
muted salmon bags contain 2 drab tan bags, 5 wavy tomato bags.
|
||||
bright black bags contain 5 plaid tan bags.
|
||||
dim chartreuse bags contain 5 muted gold bags, 5 bright blue bags, 5 faded cyan bags.
|
||||
shiny white bags contain 4 bright tan bags.
|
||||
bright red bags contain 3 dull silver bags.
|
||||
dark aqua bags contain 2 dull red bags.
|
||||
drab plum bags contain 4 muted brown bags, 5 muted plum bags.
|
||||
muted yellow bags contain 5 light purple bags, 3 dotted silver bags, 3 faded turquoise bags.
|
||||
light violet bags contain 1 pale red bag, 4 dim silver bags, 2 mirrored bronze bags.
|
||||
pale lime bags contain 4 bright lavender bags.
|
||||
pale tan bags contain 4 striped green bags, 2 dotted chartreuse bags.
|
||||
dim green bags contain 1 light lime bag, 1 shiny beige bag.
|
||||
mirrored gold bags contain 4 mirrored white bags.
|
||||
dim silver bags contain 5 pale coral bags, 3 wavy coral bags.
|
||||
dull aqua bags contain 3 posh indigo bags, 5 dotted coral bags, 1 dark salmon bag, 3 striped crimson bags.
|
||||
posh yellow bags contain 1 dark bronze bag, 2 mirrored white bags, 2 light crimson bags.
|
||||
mirrored magenta bags contain 1 bright violet bag, 2 drab lavender bags, 3 pale violet bags, 2 plaid salmon bags.
|
||||
shiny chartreuse bags contain 2 dotted purple bags, 5 wavy red bags, 3 plaid beige bags.
|
||||
light black bags contain 1 dark chartreuse bag, 3 faded tomato bags.
|
||||
clear plum bags contain 5 vibrant brown bags, 3 dim coral bags, 4 mirrored brown bags, 1 faded black bag.
|
||||
pale violet bags contain 2 dull tan bags.
|
||||
bright fuchsia bags contain 4 dull orange bags.
|
||||
dotted teal bags contain 5 bright red bags, 3 wavy red bags, 1 dull coral bag, 3 clear plum bags.
|
||||
dotted blue bags contain 2 wavy beige bags, 3 muted purple bags.
|
||||
muted gray bags contain 3 faded aqua bags, 1 shiny olive bag, 5 clear salmon bags, 1 vibrant violet bag.
|
||||
dull beige bags contain 1 wavy lavender bag, 4 dark bronze bags, 5 dull tan bags.
|
||||
drab turquoise bags contain 3 posh gray bags, 5 drab red bags.
|
||||
vibrant yellow bags contain 2 shiny aqua bags, 4 light chartreuse bags.
|
||||
posh brown bags contain 3 bright green bags, 5 posh lavender bags.
|
||||
faded gold bags contain 4 vibrant maroon bags, 4 dotted purple bags.
|
||||
dotted turquoise bags contain 5 clear plum bags, 3 muted gold bags, 4 dark violet bags.
|
||||
dotted tan bags contain 5 dim aqua bags, 4 striped violet bags.
|
||||
posh crimson bags contain 4 striped blue bags, 5 dull magenta bags, 2 bright coral bags.
|
||||
muted white bags contain 5 dull olive bags.
|
||||
vibrant teal bags contain 5 dotted turquoise bags, 1 striped tan bag, 1 drab tan bag.
|
||||
dotted yellow bags contain 3 plaid turquoise bags, 2 posh yellow bags, 4 striped blue bags, 5 posh black bags.
|
||||
posh magenta bags contain 5 mirrored black bags.
|
||||
dotted green bags contain 4 dim crimson bags, 1 shiny lavender bag, 4 bright salmon bags, 1 plaid gray bag.
|
||||
bright green bags contain 3 bright aqua bags, 3 dull maroon bags, 4 dark brown bags.
|
||||
dark gray bags contain 5 muted purple bags, 2 striped blue bags, 4 faded lavender bags.
|
||||
bright crimson bags contain 2 striped olive bags, 3 muted blue bags.
|
||||
muted cyan bags contain 3 shiny tomato bags.
|
||||
light yellow bags contain 2 striped red bags, 4 shiny crimson bags.
|
||||
pale aqua bags contain 5 shiny yellow bags, 3 dark lavender bags, 3 posh white bags.
|
||||
clear red bags contain 1 dotted silver bag, 1 dull teal bag, 1 faded maroon bag, 1 dotted salmon bag.
|
||||
pale red bags contain 2 faded gray bags.
|
||||
dotted maroon bags contain 5 posh aqua bags, 3 dull silver bags.
|
||||
dull blue bags contain 4 light crimson bags, 3 light lime bags, 1 dark orange bag, 5 light indigo bags.
|
||||
posh turquoise bags contain 1 muted gold bag, 5 striped lavender bags, 3 dull salmon bags, 5 vibrant chartreuse bags.
|
||||
striped magenta bags contain 1 posh silver bag, 5 dark brown bags.
|
||||
pale blue bags contain 2 muted gold bags, 4 vibrant brown bags, 1 light lavender bag.
|
||||
vibrant violet bags contain 5 bright red bags.
|
||||
faded fuchsia bags contain 2 light lime bags, 4 bright lime bags, 3 pale violet bags.
|
||||
shiny coral bags contain 1 clear plum bag, 5 muted chartreuse bags, 1 muted violet bag, 5 striped yellow bags.
|
||||
pale olive bags contain 4 plaid lime bags, 1 posh salmon bag.
|
||||
wavy tan bags contain 3 faded gray bags.
|
||||
faded chartreuse bags contain 3 dim coral bags, 1 mirrored bronze bag, 3 posh bronze bags.
|
||||
mirrored brown bags contain 1 faded violet bag, 4 dull maroon bags, 5 dotted magenta bags.
|
||||
clear white bags contain 5 muted magenta bags, 4 dull magenta bags, 3 pale plum bags, 4 drab indigo bags.
|
||||
drab maroon bags contain 2 clear beige bags, 3 wavy beige bags, 5 faded purple bags.
|
||||
striped silver bags contain 3 drab tomato bags.
|
||||
faded plum bags contain 1 clear teal bag, 3 bright aqua bags.
|
||||
plaid violet bags contain 2 drab violet bags, 4 muted turquoise bags, 5 muted indigo bags.
|
||||
clear black bags contain 5 muted fuchsia bags, 1 muted coral bag, 2 light black bags.
|
||||
vibrant maroon bags contain 1 dark lavender bag, 1 pale crimson bag, 4 bright indigo bags, 5 mirrored maroon bags.
|
||||
drab indigo bags contain 2 dim coral bags, 1 drab green bag, 2 shiny lavender bags.
|
||||
drab olive bags contain 2 dark aqua bags, 4 striped brown bags.
|
||||
dull crimson bags contain 3 dull cyan bags.
|
||||
wavy teal bags contain 4 striped orange bags, 2 drab cyan bags.
|
||||
dark red bags contain 2 dull maroon bags, 4 muted plum bags, 4 dull plum bags.
|
||||
striped salmon bags contain 3 bright red bags, 1 light aqua bag, 4 wavy gold bags.
|
||||
mirrored tan bags contain 5 dotted olive bags, 2 dim tomato bags, 2 mirrored tomato bags, 4 clear teal bags.
|
||||
striped white bags contain 2 pale coral bags, 2 shiny green bags.
|
||||
shiny tomato bags contain 5 pale coral bags, 5 dull beige bags.
|
||||
vibrant indigo bags contain 2 dim black bags, 4 dim blue bags, 3 dim white bags.
|
||||
wavy lavender bags contain 4 faded bronze bags, 4 muted red bags, 3 light lime bags, 4 muted gold bags.
|
||||
shiny turquoise bags contain 2 dull red bags, 5 faded gray bags, 1 muted turquoise bag.
|
||||
shiny lavender bags contain 5 bright aqua bags.
|
||||
posh tan bags contain 1 shiny yellow bag, 3 drab magenta bags.
|
||||
light green bags contain 4 bright red bags, 1 vibrant coral bag.
|
||||
drab black bags contain 5 faded tomato bags, 3 dotted chartreuse bags.
|
||||
clear chartreuse bags contain 3 wavy bronze bags, 4 plaid purple bags, 3 dark orange bags.
|
||||
dull black bags contain 1 wavy teal bag, 3 light lavender bags, 2 striped indigo bags.
|
||||
wavy black bags contain 2 clear orange bags, 4 muted purple bags.
|
||||
pale plum bags contain 1 bright coral bag, 1 drab tan bag, 1 plaid fuchsia bag, 1 dotted fuchsia bag.
|
||||
dotted violet bags contain 3 bright black bags.
|
||||
posh red bags contain 3 bright black bags.
|
||||
plaid lime bags contain 5 posh beige bags, 1 dotted turquoise bag.
|
||||
wavy aqua bags contain 1 dark yellow bag, 3 drab indigo bags.
|
||||
dim magenta bags contain 3 dark violet bags.
|
||||
drab aqua bags contain 5 posh orange bags, 1 dark silver bag, 4 plaid purple bags, 2 wavy teal bags.
|
||||
dull brown bags contain 4 light lime bags.
|
||||
striped orange bags contain 5 light crimson bags, 3 muted tan bags, 5 dotted coral bags, 3 plaid blue bags.
|
||||
muted brown bags contain 1 posh blue bag, 4 dotted magenta bags, 3 dull coral bags.
|
||||
faded blue bags contain 5 striped black bags, 1 vibrant yellow bag.
|
||||
plaid indigo bags contain 3 dark brown bags, 5 light purple bags, 4 light aqua bags, 3 light green bags.
|
||||
plaid turquoise bags contain 5 dotted teal bags.
|
||||
light turquoise bags contain 2 dull salmon bags, 5 dotted tan bags.
|
||||
dim purple bags contain 4 muted white bags, 5 drab purple bags.
|
||||
pale coral bags contain 5 posh gray bags.
|
||||
clear lime bags contain 3 dim magenta bags, 3 plaid tomato bags, 1 drab magenta bag, 3 shiny purple bags.
|
||||
dim black bags contain 3 clear gold bags, 4 muted violet bags.
|
||||
light maroon bags contain 4 muted yellow bags, 1 pale cyan bag, 2 mirrored turquoise bags, 4 dull lavender bags.
|
||||
clear magenta bags contain 2 shiny magenta bags, 2 muted chartreuse bags.
|
||||
striped bronze bags contain 5 clear tan bags, 1 drab lavender bag, 2 pale crimson bags.
|
||||
dark salmon bags contain 1 vibrant plum bag, 5 drab tan bags, 4 drab coral bags, 4 dull tan bags.
|
||||
vibrant salmon bags contain 2 muted olive bags.
|
||||
dim gold bags contain 2 dim olive bags, 5 plaid olive bags, 2 posh orange bags.
|
||||
wavy chartreuse bags contain 4 shiny yellow bags, 4 vibrant blue bags.
|
||||
vibrant brown bags contain 3 striped brown bags, 4 muted red bags, 2 shiny indigo bags.
|
||||
plaid maroon bags contain 2 muted teal bags, 2 pale yellow bags, 2 bright beige bags, 5 striped yellow bags.
|
||||
dim indigo bags contain 4 dull tomato bags, 4 clear cyan bags, 2 shiny salmon bags, 1 bright aqua bag.
|
||||
muted red bags contain 3 dull tan bags, 4 dull magenta bags, 1 bright aqua bag.
|
||||
posh beige bags contain 5 shiny black bags, 3 dotted magenta bags, 3 drab blue bags, 2 muted coral bags.
|
||||
pale fuchsia bags contain 3 dark brown bags, 5 posh gold bags.
|
||||
dark bronze bags contain 1 dim green bag, 5 posh chartreuse bags.
|
||||
dim coral bags contain 3 dull coral bags, 3 striped brown bags.
|
||||
drab crimson bags contain 2 dark bronze bags, 4 shiny indigo bags, 3 dull tan bags.
|
||||
bright indigo bags contain 3 bright blue bags.
|
||||
pale yellow bags contain 5 dim aqua bags, 1 vibrant brown bag, 2 vibrant tan bags, 3 wavy lavender bags.
|
||||
drab salmon bags contain 1 dotted indigo bag, 3 muted chartreuse bags, 5 dark olive bags.
|
||||
muted orange bags contain 4 faded lime bags, 2 dull coral bags, 5 vibrant magenta bags, 4 dull magenta bags.
|
||||
striped gold bags contain 2 dull silver bags, 5 bright lavender bags, 5 dim teal bags, 5 dark coral bags.
|
||||
posh chartreuse bags contain 3 dim teal bags, 5 light aqua bags.
|
||||
shiny blue bags contain 3 dull tan bags, 5 muted magenta bags.
|
||||
muted silver bags contain 3 wavy blue bags, 2 dim teal bags, 5 muted bronze bags.
|
||||
shiny bronze bags contain 1 light green bag, 4 vibrant magenta bags.
|
||||
wavy coral bags contain no other bags.
|
||||
shiny orange bags contain 2 muted purple bags.
|
||||
posh teal bags contain 4 clear plum bags.
|
||||
striped turquoise bags contain 3 muted indigo bags.
|
||||
dim bronze bags contain 2 shiny silver bags, 1 light silver bag, 2 dim indigo bags, 4 dim tomato bags.
|
||||
plaid white bags contain 4 drab turquoise bags.
|
||||
wavy indigo bags contain 3 clear gold bags, 5 mirrored bronze bags.
|
||||
faded teal bags contain 4 mirrored white bags.
|
||||
shiny fuchsia bags contain 3 drab indigo bags.
|
||||
dim red bags contain 3 clear bronze bags.
|
||||
dotted brown bags contain 4 wavy maroon bags, 5 drab green bags, 3 dark purple bags.
|
||||
dark tomato bags contain 3 vibrant coral bags, 5 dull coral bags, 2 drab cyan bags, 1 posh blue bag.
|
||||
clear teal bags contain 3 dark white bags.
|
||||
dark silver bags contain 3 dark cyan bags, 4 plaid salmon bags.
|
||||
wavy fuchsia bags contain 4 bright brown bags, 4 bright aqua bags, 5 light orange bags.
|
||||
light bronze bags contain 4 clear plum bags.
|
||||
striped purple bags contain 1 dim indigo bag.
|
||||
clear tomato bags contain 4 mirrored tomato bags, 3 muted indigo bags, 1 striped tan bag.
|
||||
muted turquoise bags contain 5 faded beige bags, 4 clear crimson bags, 2 bright teal bags.
|
||||
dull cyan bags contain 5 mirrored aqua bags, 2 shiny aqua bags, 3 light black bags, 4 bright coral bags.
|
||||
plaid crimson bags contain 2 mirrored teal bags, 2 dull fuchsia bags.
|
||||
shiny maroon bags contain 1 posh gold bag.
|
||||
dim white bags contain 5 striped brown bags, 2 dull magenta bags, 5 plaid tan bags.
|
||||
muted green bags contain 2 dull magenta bags, 5 clear cyan bags.
|
||||
plaid teal bags contain 2 dark tan bags, 3 pale lime bags.
|
||||
dotted lavender bags contain 2 posh aqua bags, 3 dull cyan bags.
|
||||
light salmon bags contain 5 dark silver bags.
|
||||
faded white bags contain 2 wavy maroon bags, 3 dull cyan bags.
|
||||
dull tomato bags contain 2 dim aqua bags, 4 posh lavender bags, 1 faded red bag.
|
||||
dark olive bags contain 5 clear bronze bags, 2 drab plum bags.
|
||||
pale indigo bags contain 2 mirrored beige bags, 5 wavy turquoise bags, 4 striped green bags, 2 dotted lavender bags.
|
||||
plaid purple bags contain 1 light lime bag.
|
||||
clear purple bags contain 3 vibrant white bags.
|
||||
dark yellow bags contain 2 pale olive bags, 4 pale cyan bags, 5 bright teal bags.
|
||||
muted beige bags contain 2 posh lime bags, 5 shiny gray bags, 2 dull blue bags.
|
||||
vibrant orange bags contain 5 posh crimson bags, 4 light chartreuse bags.
|
||||
light magenta bags contain 2 plaid maroon bags, 1 posh beige bag, 5 pale salmon bags.
|
||||
dotted crimson bags contain 5 dark chartreuse bags.
|
||||
striped coral bags contain 2 dim aqua bags.
|
||||
striped aqua bags contain 3 posh salmon bags, 3 dull red bags.
|
||||
mirrored salmon bags contain 5 bright red bags, 2 light green bags, 3 clear black bags, 5 posh brown bags.
|
||||
posh white bags contain 4 drab violet bags, 2 dotted silver bags.
|
||||
posh blue bags contain 4 dull maroon bags, 3 vibrant coral bags.
|
||||
dim orange bags contain 2 dull olive bags.
|
||||
shiny teal bags contain 1 faded tomato bag, 4 muted violet bags.
|
||||
mirrored maroon bags contain 3 dull blue bags.
|
||||
dark lavender bags contain 1 drab red bag, 3 shiny indigo bags, 4 faded beige bags, 1 drab turquoise bag.
|
||||
shiny olive bags contain 3 dark violet bags, 1 striped gold bag, 2 mirrored lime bags.
|
||||
bright violet bags contain 2 wavy bronze bags, 3 drab olive bags, 5 mirrored olive bags, 2 wavy lavender bags.
|
||||
clear olive bags contain 5 faded turquoise bags.
|
||||
mirrored lavender bags contain 1 light white bag, 4 light purple bags, 3 wavy lavender bags, 2 shiny lime bags.
|
||||
pale turquoise bags contain 4 dark tan bags.
|
||||
shiny salmon bags contain 1 shiny gold bag, 5 drab turquoise bags.
|
||||
vibrant gray bags contain 3 posh brown bags.
|
||||
dark indigo bags contain 1 mirrored black bag, 5 dull beige bags, 4 shiny beige bags, 3 drab lavender bags.
|
||||
light teal bags contain 5 dark olive bags, 5 vibrant chartreuse bags, 3 plaid salmon bags, 5 light yellow bags.
|
||||
clear violet bags contain 3 light crimson bags.
|
||||
clear tan bags contain 3 striped orange bags, 4 wavy lavender bags, 3 striped silver bags.
|
||||
clear bronze bags contain 2 plaid beige bags.
|
||||
clear gray bags contain 4 dotted cyan bags, 4 vibrant plum bags.
|
||||
drab cyan bags contain 1 light aqua bag, 1 drab teal bag, 3 bright orange bags, 3 dark white bags.
|
||||
plaid beige bags contain 3 dull green bags.
|
||||
wavy gold bags contain 4 shiny olive bags, 3 bright tan bags.
|
||||
clear aqua bags contain 3 posh chartreuse bags, 4 drab silver bags, 5 clear gray bags.
|
||||
bright chartreuse bags contain 2 light violet bags, 3 vibrant gray bags.
|
||||
plaid black bags contain 2 posh gray bags.
|
||||
light beige bags contain 4 dotted olive bags, 5 dull olive bags, 1 faded orange bag.
|
||||
mirrored teal bags contain 4 mirrored aqua bags.
|
||||
bright magenta bags contain 1 mirrored magenta bag, 3 bright blue bags, 1 vibrant blue bag, 2 drab gold bags.
|
||||
dim maroon bags contain 4 light bronze bags, 5 clear violet bags.
|
||||
light lime bags contain 4 plaid indigo bags.
|
||||
posh lavender bags contain 4 dark brown bags.
|
||||
clear beige bags contain 4 posh silver bags, 3 dull coral bags, 2 posh gray bags.
|
||||
drab bronze bags contain 4 plaid maroon bags.
|
||||
mirrored purple bags contain 3 dim magenta bags.
|
||||
dark magenta bags contain 4 faded maroon bags, 1 drab crimson bag, 5 dotted brown bags, 2 bright teal bags.
|
||||
dim brown bags contain 3 muted olive bags, 5 drab green bags, 1 mirrored olive bag.
|
||||
dark plum bags contain 2 vibrant tan bags.
|
||||
bright turquoise bags contain 1 mirrored aqua bag, 3 clear plum bags.
|
||||
muted black bags contain 5 faded cyan bags, 5 pale tan bags, 2 dotted chartreuse bags.
|
||||
dotted gray bags contain 3 posh plum bags.
|
||||
vibrant black bags contain 2 vibrant magenta bags, 5 faded cyan bags.
|
||||
mirrored cyan bags contain 2 clear cyan bags, 4 light aqua bags, 5 drab blue bags, 1 drab gold bag.
|
||||
wavy purple bags contain 5 striped magenta bags, 3 clear maroon bags, 1 mirrored green bag, 1 pale black bag.
|
||||
drab blue bags contain 3 mirrored lime bags, 1 mirrored blue bag.
|
||||
clear maroon bags contain 5 bright orange bags.
|
||||
shiny cyan bags contain 2 clear gray bags, 5 pale crimson bags.
|
||||
pale cyan bags contain 2 wavy turquoise bags, 5 wavy salmon bags.
|
||||
plaid gold bags contain 1 clear lavender bag, 1 bright beige bag.
|
||||
mirrored lime bags contain 2 dull tan bags, 3 shiny beige bags.
|
||||
drab green bags contain 1 vibrant yellow bag.
|
||||
dull red bags contain 5 plaid blue bags, 5 clear brown bags, 3 pale salmon bags, 2 dark orange bags.
|
||||
bright beige bags contain 4 dull silver bags, 5 vibrant brown bags, 4 drab red bags, 2 pale violet bags.
|
||||
clear silver bags contain 4 drab indigo bags, 2 clear salmon bags.
|
||||
posh bronze bags contain 5 bright indigo bags, 5 dotted purple bags, 1 dark violet bag, 2 dark orange bags.
|
||||
posh salmon bags contain 5 bright red bags, 3 striped green bags, 3 dark brown bags.
|
||||
clear cyan bags contain 5 dark chartreuse bags, 1 bright indigo bag, 4 pale yellow bags, 2 vibrant coral bags.
|
||||
mirrored blue bags contain 2 vibrant white bags.
|
||||
mirrored yellow bags contain 5 dotted gray bags, 4 dull maroon bags, 2 striped violet bags, 5 clear tomato bags.
|
||||
striped teal bags contain 2 clear black bags, 3 pale coral bags.
|
||||
faded orange bags contain 2 dark bronze bags.
|
||||
mirrored indigo bags contain 3 light tomato bags, 2 shiny crimson bags.
|
||||
pale green bags contain 4 light chartreuse bags.
|
||||
plaid cyan bags contain 4 plaid fuchsia bags, 2 shiny teal bags, 3 dotted fuchsia bags, 3 dim red bags.
|
||||
muted gold bags contain 2 dull tan bags, 1 faded bronze bag, 4 dull maroon bags.
|
||||
wavy green bags contain 5 pale coral bags, 1 dull blue bag, 4 drab blue bags, 1 striped tan bag.
|
||||
light chartreuse bags contain 4 striped brown bags, 5 plaid purple bags, 4 drab cyan bags, 3 dull plum bags.
|
||||
dotted cyan bags contain 4 shiny black bags.
|
||||
light purple bags contain no other bags.
|
||||
dotted aqua bags contain 4 light gray bags, 2 light purple bags, 5 mirrored lime bags.
|
||||
drab gold bags contain 2 bright green bags, 5 bright indigo bags.
|
||||
posh gray bags contain 5 bright orange bags, 5 bright blue bags.
|
||||
striped red bags contain 4 drab green bags, 1 clear cyan bag.
|
||||
dotted bronze bags contain 5 light orange bags.
|
||||
muted plum bags contain 2 bright black bags, 3 dotted tomato bags, 2 vibrant brown bags.
|
||||
mirrored black bags contain 3 plaid chartreuse bags, 2 shiny indigo bags, 2 shiny beige bags.
|
||||
drab lavender bags contain 5 drab cyan bags, 1 muted purple bag, 1 wavy red bag, 3 drab crimson bags.
|
||||
vibrant turquoise bags contain 3 shiny beige bags, 3 striped brown bags, 5 dim teal bags.
|
||||
muted tan bags contain 1 plaid purple bag, 3 shiny beige bags, 1 drab gold bag.
|
||||
pale beige bags contain 5 bright silver bags.
|
||||
wavy olive bags contain 4 dotted turquoise bags, 4 dull silver bags, 1 bright gold bag.
|
||||
dim olive bags contain 5 light lavender bags, 4 shiny tomato bags, 4 clear cyan bags.
|
||||
wavy salmon bags contain 4 bright aqua bags.
|
||||
dotted gold bags contain 3 shiny red bags, 3 dull fuchsia bags.
|
||||
shiny violet bags contain 3 dotted tomato bags, 1 drab coral bag.
|
||||
striped plum bags contain 4 drab beige bags, 3 clear tan bags, 5 light aqua bags, 1 shiny fuchsia bag.
|
||||
clear lavender bags contain 2 bright aqua bags, 3 dull silver bags, 3 bright green bags, 2 bright orange bags.
|
||||
faded maroon bags contain 5 dark indigo bags, 1 posh fuchsia bag.
|
||||
vibrant red bags contain 4 striped fuchsia bags, 3 drab orange bags, 1 clear brown bag, 1 plaid turquoise bag.
|
||||
dull coral bags contain 2 dim teal bags, 3 faded bronze bags.
|
||||
pale salmon bags contain 3 dull magenta bags, 1 light crimson bag.
|
||||
dotted magenta bags contain 4 dull maroon bags, 2 bright lime bags, 4 plaid indigo bags, 4 faded cyan bags.
|
||||
wavy gray bags contain 4 muted gray bags, 3 shiny magenta bags, 1 posh teal bag.
|
||||
light red bags contain 4 shiny chartreuse bags.
|
||||
dim blue bags contain 4 vibrant orange bags.
|
||||
muted bronze bags contain 5 mirrored aqua bags, 4 dim green bags.
|
||||
drab lime bags contain 1 drab cyan bag, 3 pale crimson bags, 4 bright green bags, 3 drab lavender bags.
|
||||
light white bags contain 5 bright green bags.
|
||||
bright teal bags contain 4 shiny brown bags, 4 dark silver bags.
|
||||
striped beige bags contain 2 shiny magenta bags.
|
||||
wavy magenta bags contain 5 pale bronze bags, 5 pale plum bags, 3 muted silver bags.
|
||||
dark orange bags contain 1 drab tomato bag, 3 striped brown bags, 1 dim teal bag, 5 bright beige bags.
|
||||
striped indigo bags contain 1 vibrant gold bag, 1 shiny green bag.
|
||||
clear coral bags contain 2 shiny gray bags.
|
||||
faded yellow bags contain 4 faded gold bags, 2 bright turquoise bags, 5 dark silver bags, 3 wavy coral bags.
|
||||
dim plum bags contain 1 clear purple bag, 4 light brown bags.
|
||||
mirrored turquoise bags contain 5 wavy indigo bags, 3 dark fuchsia bags, 5 plaid white bags, 2 dim turquoise bags.
|
||||
posh black bags contain 2 striped black bags, 5 dim teal bags, 3 bright silver bags, 5 posh beige bags.
|
||||
dotted fuchsia bags contain 1 faded turquoise bag, 2 shiny lavender bags, 4 posh salmon bags, 1 clear olive bag.
|
||||
faded lavender bags contain 2 striped yellow bags, 1 posh lavender bag.
|
||||
dim lime bags contain 2 wavy gray bags, 5 clear gray bags.
|
||||
vibrant bronze bags contain 3 drab tomato bags, 5 bright tan bags.
|
||||
dull plum bags contain 5 bright red bags, 4 dull magenta bags.
|
||||
dim teal bags contain 4 light purple bags, 4 plaid lavender bags, 1 dull magenta bag.
|
||||
dull yellow bags contain 4 vibrant orange bags, 1 dark tomato bag, 5 pale tan bags.
|
||||
dull green bags contain 2 bright blue bags, 5 dull red bags.
|
||||
light crimson bags contain 5 dull maroon bags, 4 muted gold bags.
|
||||
dark black bags contain 1 dim silver bag, 3 plaid magenta bags.
|
||||
bright lavender bags contain 4 muted fuchsia bags.
|
||||
drab coral bags contain 4 shiny chartreuse bags, 3 posh yellow bags, 3 wavy indigo bags.
|
||||
mirrored crimson bags contain 3 posh maroon bags, 5 striped olive bags, 3 mirrored magenta bags.
|
||||
muted coral bags contain 3 wavy violet bags, 1 dotted chartreuse bag, 1 shiny beige bag.
|
||||
vibrant gold bags contain 2 dull orange bags, 1 clear chartreuse bag.
|
||||
wavy orange bags contain 5 dark bronze bags.
|
||||
mirrored white bags contain 5 clear gold bags, 3 drab tomato bags, 4 dotted bronze bags, 3 striped orange bags.
|
||||
clear gold bags contain 3 drab indigo bags, 4 wavy violet bags, 2 shiny salmon bags, 4 light brown bags.
|
||||
shiny magenta bags contain 5 drab silver bags, 2 muted gold bags.
|
||||
dim violet bags contain 1 posh lime bag, 4 shiny orange bags, 2 posh chartreuse bags.
|
||||
striped olive bags contain 4 plaid indigo bags, 5 dim chartreuse bags, 4 clear lavender bags.
|
||||
plaid gray bags contain 3 shiny gold bags, 2 dull coral bags.
|
||||
clear crimson bags contain 4 shiny aqua bags, 3 light crimson bags, 5 dim chartreuse bags.
|
||||
drab silver bags contain 1 dim teal bag, 3 faded cyan bags, 1 shiny indigo bag.
|
||||
mirrored green bags contain 5 dotted lime bags, 4 pale cyan bags.
|
||||
bright aqua bags contain no other bags.
|
||||
bright plum bags contain 4 dim aqua bags, 2 dull crimson bags, 1 wavy maroon bag.
|
||||
vibrant lavender bags contain 1 plaid tan bag, 3 vibrant brown bags, 3 drab gold bags, 4 faded red bags.
|
||||
pale white bags contain 3 bright brown bags, 4 mirrored beige bags.
|
||||
plaid lavender bags contain 1 dull magenta bag, 2 dull silver bags, 1 shiny indigo bag.
|
||||
bright salmon bags contain 1 striped coral bag, 4 plaid lavender bags, 1 muted red bag, 1 drab red bag.
|
||||
plaid olive bags contain 5 faded turquoise bags, 4 dim green bags, 2 striped beige bags.
|
||||
wavy plum bags contain 1 clear lavender bag, 2 faded brown bags.
|
||||
clear fuchsia bags contain 1 muted bronze bag.
|
||||
wavy turquoise bags contain 5 shiny lime bags, 1 drab olive bag, 4 dim white bags, 1 dotted gray bag.
|
||||
vibrant aqua bags contain 2 faded lavender bags.
|
||||
dotted white bags contain 3 muted crimson bags, 5 mirrored white bags, 1 mirrored fuchsia bag.
|
||||
bright purple bags contain 2 dotted chartreuse bags, 4 posh cyan bags, 3 bright plum bags.
|
||||
light aqua bags contain 1 plaid lavender bag, 3 wavy coral bags, 5 shiny indigo bags.
|
||||
drab yellow bags contain 4 shiny teal bags, 2 dotted green bags, 5 vibrant silver bags, 3 dotted turquoise bags.
|
||||
mirrored olive bags contain 1 dull plum bag.
|
||||
light olive bags contain 1 shiny coral bag, 4 drab white bags, 3 dim turquoise bags, 4 dull gold bags.
|
||||
shiny indigo bags contain no other bags.
|
||||
dull gold bags contain 3 dark indigo bags.
|
||||
bright tomato bags contain 5 muted blue bags.
|
||||
faded purple bags contain 4 bright orange bags, 2 faded violet bags.
|
||||
drab magenta bags contain 3 wavy lavender bags, 2 drab cyan bags, 2 clear beige bags, 4 bright indigo bags.
|
||||
striped lime bags contain 4 light tan bags.
|
||||
light gold bags contain 2 pale plum bags.
|
||||
striped black bags contain 1 plaid salmon bag, 2 plaid beige bags, 4 dotted teal bags, 2 posh chartreuse bags.
|
||||
faded tomato bags contain 2 striped yellow bags, 4 muted red bags.
|
||||
dull fuchsia bags contain 5 dotted olive bags, 2 muted purple bags.
|
||||
pale purple bags contain 4 posh silver bags, 4 wavy yellow bags.
|
||||
bright olive bags contain 5 shiny fuchsia bags, 5 dull crimson bags, 5 drab red bags, 5 posh turquoise bags.
|
||||
vibrant fuchsia bags contain 1 vibrant beige bag, 5 shiny magenta bags.
|
||||
faded turquoise bags contain 5 light lime bags, 4 dark white bags.
|
||||
plaid orange bags contain 5 vibrant coral bags, 4 light crimson bags, 4 plaid chartreuse bags, 1 dull green bag.
|
||||
posh indigo bags contain 3 wavy green bags, 2 shiny orange bags, 5 faded violet bags, 2 dotted coral bags.
|
||||
mirrored red bags contain 4 mirrored olive bags, 1 dark silver bag, 1 dull red bag.
|
||||
dim salmon bags contain 1 striped salmon bag, 5 faded gray bags.
|
||||
dim cyan bags contain 3 wavy olive bags, 5 drab purple bags, 3 mirrored bronze bags.
|
||||
light blue bags contain 2 striped bronze bags, 4 dull white bags, 1 posh bronze bag.
|
||||
dull turquoise bags contain 4 striped red bags, 1 light lavender bag, 5 plaid bronze bags, 1 mirrored brown bag.
|
||||
vibrant coral bags contain 1 bright orange bag.
|
||||
striped cyan bags contain 2 dark white bags, 4 drab red bags, 2 plaid salmon bags.
|
||||
muted tomato bags contain 4 drab red bags, 3 vibrant silver bags, 4 clear fuchsia bags, 3 wavy white bags.
|
||||
dotted red bags contain 1 light blue bag.
|
||||
dark beige bags contain 2 posh lime bags, 3 striped black bags.
|
||||
dark cyan bags contain 1 dim chartreuse bag, 2 shiny beige bags, 4 dotted magenta bags, 4 light chartreuse bags.
|
||||
dull lime bags contain 3 muted chartreuse bags.
|
||||
light brown bags contain 3 mirrored brown bags.
|
||||
vibrant magenta bags contain 1 dim green bag.
|
||||
shiny brown bags contain 5 bright brown bags, 3 faded cyan bags, 5 clear tan bags, 2 plaid maroon bags.
|
||||
drab purple bags contain 1 shiny indigo bag, 4 striped yellow bags.
|
64
2020/d07/ex2/ex2.py
Executable file
64
2020/d07/ex2/ex2.py
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import re
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Set, Tuple
|
||||
|
||||
|
||||
@dataclass(eq=True, frozen=True) # Hashable
|
||||
class ColorInfo:
|
||||
num: int
|
||||
color: str
|
||||
|
||||
|
||||
Graph = Dict[str, Set[ColorInfo]]
|
||||
|
||||
|
||||
def extract_info(line: str) -> Tuple[str, Set[ColorInfo]]:
|
||||
color_pattern = re.compile("(.*) contain ")
|
||||
match = color_pattern.search(line)
|
||||
assert match is not None
|
||||
color = match.group(1).replace("bags", "bag")
|
||||
|
||||
line = line[match.end() : -1] # Remove period at end of line
|
||||
|
||||
if line == "no other bags":
|
||||
return color, set()
|
||||
|
||||
colors: Set[ColorInfo] = set()
|
||||
pattern = re.compile("([0-9]+) (.*)")
|
||||
for col in line.split(", "):
|
||||
match = pattern.search(col)
|
||||
assert match is not None
|
||||
colors |= {
|
||||
ColorInfo(int(match.group(1)), match.group(2).replace("bags", "bag"))
|
||||
}
|
||||
|
||||
return color, colors
|
||||
|
||||
|
||||
def to_graph(raw: List[str]) -> Graph:
|
||||
return {color: inside for color, inside in map(extract_info, raw)}
|
||||
|
||||
|
||||
def num_bags(graph: Graph, col: str) -> int:
|
||||
return sum(
|
||||
contained.num * (1 + num_bags(graph, contained.color))
|
||||
for contained in graph[col]
|
||||
)
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
graph = to_graph(raw)
|
||||
|
||||
return num_bags(graph, "shiny gold bag")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
594
2020/d07/ex2/input
Normal file
594
2020/d07/ex2/input
Normal file
|
@ -0,0 +1,594 @@
|
|||
shiny aqua bags contain 1 dark white bag.
|
||||
muted blue bags contain 1 vibrant lavender bag, 4 dotted silver bags, 2 dim indigo bags.
|
||||
drab gray bags contain 5 mirrored white bags, 1 light green bag, 5 shiny lavender bags, 5 faded aqua bags.
|
||||
muted indigo bags contain 4 muted chartreuse bags, 2 dotted teal bags.
|
||||
drab white bags contain 2 dull fuchsia bags, 1 vibrant bronze bag.
|
||||
dim lavender bags contain 4 muted tan bags.
|
||||
dotted tomato bags contain 1 mirrored lime bag, 2 vibrant white bags.
|
||||
clear orange bags contain 5 clear violet bags, 2 dull beige bags, 2 dark chartreuse bags.
|
||||
bright lime bags contain no other bags.
|
||||
striped brown bags contain 3 bright orange bags.
|
||||
vibrant green bags contain 3 shiny fuchsia bags.
|
||||
plaid tomato bags contain 3 faded chartreuse bags, 2 wavy salmon bags, 1 faded white bag, 3 mirrored maroon bags.
|
||||
drab beige bags contain 2 shiny bronze bags, 4 pale violet bags, 3 bright tomato bags, 4 pale red bags.
|
||||
posh green bags contain 2 dull lavender bags, 4 clear plum bags, 2 dark gray bags.
|
||||
dull maroon bags contain 3 dull magenta bags, 1 dull tan bag, 1 faded cyan bag, 5 dull silver bags.
|
||||
faded crimson bags contain 2 muted purple bags, 4 dotted olive bags, 5 drab silver bags.
|
||||
wavy bronze bags contain 3 dark orange bags, 2 dark brown bags, 5 bright silver bags.
|
||||
dark turquoise bags contain 5 dull plum bags.
|
||||
dull lavender bags contain 4 dotted maroon bags, 3 muted brown bags, 4 drab black bags, 4 dull cyan bags.
|
||||
dotted plum bags contain 1 shiny bronze bag, 3 clear brown bags, 3 muted indigo bags.
|
||||
dull white bags contain 3 clear tan bags, 5 shiny gold bags, 2 drab crimson bags.
|
||||
dull teal bags contain 2 bright tomato bags.
|
||||
shiny crimson bags contain 3 light green bags, 5 striped brown bags, 3 faded fuchsia bags.
|
||||
wavy brown bags contain 1 drab crimson bag, 2 wavy indigo bags.
|
||||
dark tan bags contain 2 faded gray bags, 4 shiny salmon bags.
|
||||
shiny red bags contain 4 dull chartreuse bags, 5 pale tomato bags.
|
||||
bright orange bags contain no other bags.
|
||||
wavy yellow bags contain 5 light indigo bags, 5 dark gray bags, 5 plaid indigo bags, 4 faded red bags.
|
||||
faded bronze bags contain 4 faded cyan bags, 5 shiny beige bags, 5 muted red bags.
|
||||
dull bronze bags contain 1 mirrored beige bag, 5 muted violet bags, 1 wavy lime bag.
|
||||
dark lime bags contain 2 drab maroon bags, 5 bright indigo bags, 4 shiny black bags, 5 dotted turquoise bags.
|
||||
drab red bags contain 5 bright red bags, 2 vibrant brown bags.
|
||||
dotted salmon bags contain 3 vibrant turquoise bags, 2 dull beige bags, 3 light turquoise bags.
|
||||
dull gray bags contain 3 striped green bags, 3 wavy coral bags, 1 dark gray bag, 2 light indigo bags.
|
||||
faded black bags contain 4 muted fuchsia bags, 4 wavy coral bags, 1 drab tomato bag.
|
||||
muted magenta bags contain 2 posh chartreuse bags, 4 pale violet bags.
|
||||
light tan bags contain 2 posh turquoise bags, 3 vibrant white bags, 1 light black bag.
|
||||
dark blue bags contain 3 plaid indigo bags, 2 posh black bags.
|
||||
dull indigo bags contain 4 light gray bags, 3 dotted tan bags, 4 dull coral bags.
|
||||
dim fuchsia bags contain 3 vibrant yellow bags, 3 mirrored cyan bags, 4 mirrored brown bags.
|
||||
shiny beige bags contain 2 dull silver bags, 3 bright lime bags, 5 dull magenta bags.
|
||||
light cyan bags contain 3 vibrant violet bags, 2 mirrored tomato bags, 2 vibrant coral bags, 4 mirrored silver bags.
|
||||
clear turquoise bags contain 4 drab tomato bags, 3 shiny gold bags, 4 drab gold bags.
|
||||
pale teal bags contain 2 wavy maroon bags, 2 dotted olive bags, 4 shiny white bags, 2 drab turquoise bags.
|
||||
dark purple bags contain 1 wavy indigo bag, 3 bright black bags, 3 dotted teal bags.
|
||||
bright white bags contain 5 wavy red bags, 2 mirrored cyan bags, 3 drab green bags.
|
||||
mirrored aqua bags contain 1 faded violet bag, 5 dotted purple bags.
|
||||
shiny lime bags contain 4 dark aqua bags.
|
||||
pale bronze bags contain 1 clear crimson bag.
|
||||
vibrant white bags contain 5 plaid lavender bags, 1 drab red bag, 4 vibrant brown bags.
|
||||
plaid tan bags contain 5 dim crimson bags.
|
||||
posh olive bags contain 3 bright red bags.
|
||||
plaid brown bags contain 5 vibrant turquoise bags.
|
||||
mirrored tomato bags contain 2 dotted chartreuse bags, 3 light aqua bags, 3 posh beige bags.
|
||||
plaid blue bags contain 5 striped green bags, 1 plaid purple bag, 4 muted gold bags.
|
||||
shiny tan bags contain 5 striped coral bags, 1 dull brown bag.
|
||||
shiny gold bags contain 1 dull magenta bag, 5 dark white bags, 4 faded turquoise bags.
|
||||
dull salmon bags contain 2 plaid gold bags, 2 light indigo bags.
|
||||
striped tomato bags contain 2 striped tan bags, 4 light blue bags, 4 drab tan bags.
|
||||
drab tomato bags contain 3 dim teal bags, 4 striped yellow bags, 3 bright red bags.
|
||||
faded olive bags contain 1 drab plum bag, 1 pale aqua bag, 3 light blue bags.
|
||||
dotted indigo bags contain 2 clear tomato bags.
|
||||
dark white bags contain 5 light aqua bags, 2 dim teal bags, 2 muted fuchsia bags, 5 light purple bags.
|
||||
dull orange bags contain 4 pale gold bags, 5 posh brown bags, 2 mirrored brown bags, 3 dark bronze bags.
|
||||
bright maroon bags contain 1 mirrored yellow bag, 4 light teal bags.
|
||||
bright silver bags contain 1 vibrant coral bag, 3 dim teal bags, 5 light purple bags.
|
||||
muted olive bags contain 5 plaid orange bags, 1 muted magenta bag.
|
||||
dull silver bags contain no other bags.
|
||||
pale maroon bags contain 2 pale bronze bags.
|
||||
light gray bags contain 4 vibrant yellow bags, 2 pale red bags.
|
||||
drab teal bags contain 2 light crimson bags, 3 vibrant brown bags, 3 vibrant tan bags.
|
||||
bright gold bags contain 1 wavy red bag, 5 wavy coral bags.
|
||||
plaid chartreuse bags contain 2 dim coral bags, 4 drab silver bags, 5 dim chartreuse bags, 3 light purple bags.
|
||||
clear blue bags contain 2 pale tomato bags, 4 dull gold bags, 4 dim fuchsia bags, 4 pale coral bags.
|
||||
vibrant purple bags contain 5 faded orange bags.
|
||||
plaid aqua bags contain 3 muted cyan bags, 2 wavy gray bags, 4 drab green bags, 4 pale beige bags.
|
||||
muted lime bags contain 1 muted tan bag.
|
||||
faded coral bags contain 3 drab turquoise bags, 1 shiny plum bag, 5 mirrored green bags, 5 clear white bags.
|
||||
vibrant lime bags contain 5 posh coral bags.
|
||||
faded green bags contain 3 pale orange bags, 5 dull turquoise bags, 1 mirrored crimson bag.
|
||||
mirrored gray bags contain 5 dim indigo bags.
|
||||
wavy maroon bags contain 4 mirrored bronze bags, 1 striped olive bag, 2 dull salmon bags, 3 shiny crimson bags.
|
||||
dark violet bags contain 2 light purple bags.
|
||||
dark green bags contain 2 dim cyan bags.
|
||||
pale black bags contain 1 mirrored gold bag.
|
||||
bright yellow bags contain 2 vibrant crimson bags, 3 plaid lime bags, 2 dotted gold bags.
|
||||
muted teal bags contain 1 pale violet bag, 4 dull silver bags.
|
||||
dim beige bags contain 5 wavy red bags.
|
||||
muted purple bags contain 4 clear cyan bags.
|
||||
plaid fuchsia bags contain 3 dark coral bags.
|
||||
plaid bronze bags contain 5 plaid orange bags, 2 drab indigo bags.
|
||||
faded indigo bags contain 1 dark chartreuse bag, 4 dull green bags, 1 mirrored magenta bag.
|
||||
posh plum bags contain 3 dark chartreuse bags, 3 dotted turquoise bags, 4 dull maroon bags, 1 posh bronze bag.
|
||||
pale gold bags contain 4 striped brown bags.
|
||||
mirrored chartreuse bags contain 4 bright silver bags, 3 mirrored tomato bags, 4 wavy orange bags.
|
||||
pale orange bags contain 2 posh fuchsia bags, 2 clear salmon bags, 2 bright green bags.
|
||||
clear brown bags contain 4 light lime bags, 4 bright green bags, 5 pale yellow bags, 2 drab cyan bags.
|
||||
shiny plum bags contain 5 vibrant gray bags, 3 bright blue bags, 5 dark tomato bags.
|
||||
wavy white bags contain 4 plaid lime bags, 4 posh maroon bags, 5 drab lime bags, 1 vibrant crimson bag.
|
||||
faded red bags contain 1 dull coral bag, 5 clear cyan bags, 4 plaid chartreuse bags, 3 plaid orange bags.
|
||||
plaid red bags contain 5 pale blue bags, 4 light crimson bags, 3 faded fuchsia bags.
|
||||
bright cyan bags contain 3 dark white bags, 2 light crimson bags, 1 bright aqua bag.
|
||||
muted lavender bags contain 1 light green bag, 4 striped silver bags, 3 posh crimson bags.
|
||||
wavy crimson bags contain 1 light purple bag, 4 bright blue bags, 2 dull coral bags, 1 wavy beige bag.
|
||||
faded aqua bags contain 5 muted brown bags.
|
||||
mirrored fuchsia bags contain 1 faded beige bag, 3 muted gold bags.
|
||||
dark chartreuse bags contain 5 bright lime bags.
|
||||
plaid green bags contain 4 mirrored tan bags, 1 mirrored tomato bag, 5 pale indigo bags, 1 mirrored plum bag.
|
||||
shiny black bags contain 3 plaid chartreuse bags.
|
||||
dotted purple bags contain 2 dim teal bags.
|
||||
faded tan bags contain 2 bright fuchsia bags, 5 shiny fuchsia bags, 1 muted fuchsia bag, 1 mirrored brown bag.
|
||||
drab brown bags contain 1 striped orange bag, 4 dotted tomato bags.
|
||||
dull olive bags contain 1 striped black bag, 1 vibrant magenta bag.
|
||||
mirrored plum bags contain 1 clear gold bag, 5 pale green bags.
|
||||
dim tomato bags contain 4 drab gold bags, 2 shiny aqua bags.
|
||||
light lavender bags contain 1 muted violet bag.
|
||||
dim gray bags contain 3 light purple bags, 1 posh crimson bag, 1 faded brown bag.
|
||||
muted aqua bags contain 4 dull beige bags, 4 dull red bags.
|
||||
faded silver bags contain 1 mirrored cyan bag.
|
||||
shiny green bags contain 5 dull maroon bags.
|
||||
muted chartreuse bags contain 2 clear tan bags.
|
||||
plaid plum bags contain 1 dotted lime bag, 4 clear brown bags, 4 dull red bags.
|
||||
dotted silver bags contain 1 posh coral bag.
|
||||
dim crimson bags contain 4 faded violet bags, 1 striped silver bag.
|
||||
bright brown bags contain 1 bright coral bag, 3 posh brown bags, 4 drab tan bags.
|
||||
wavy cyan bags contain 3 clear gold bags, 1 mirrored salmon bag, 3 bright fuchsia bags, 2 light bronze bags.
|
||||
dull violet bags contain 5 striped white bags, 4 light blue bags, 4 dim black bags.
|
||||
vibrant olive bags contain 2 vibrant coral bags.
|
||||
bright coral bags contain 2 vibrant tan bags, 3 shiny indigo bags, 2 plaid indigo bags.
|
||||
dim turquoise bags contain 1 pale violet bag.
|
||||
striped crimson bags contain 2 faded gray bags.
|
||||
clear green bags contain 3 mirrored olive bags, 3 shiny tomato bags.
|
||||
faded violet bags contain 2 wavy coral bags, 2 dull tan bags, 1 dull silver bag, 1 bright orange bag.
|
||||
pale chartreuse bags contain 4 shiny crimson bags, 2 clear bronze bags.
|
||||
light plum bags contain 3 drab bronze bags, 1 bright bronze bag, 1 posh yellow bag.
|
||||
pale tomato bags contain 1 dim teal bag, 5 drab cyan bags, 3 muted coral bags, 2 dim chartreuse bags.
|
||||
plaid coral bags contain 1 striped tan bag, 3 vibrant cyan bags, 3 light beige bags, 2 dotted green bags.
|
||||
bright gray bags contain 4 mirrored teal bags, 4 striped brown bags, 1 dim green bag, 4 clear cyan bags.
|
||||
drab fuchsia bags contain 2 mirrored salmon bags, 4 posh orange bags, 3 faded crimson bags, 3 pale plum bags.
|
||||
light tomato bags contain 2 dotted gold bags, 1 dotted bronze bag.
|
||||
muted violet bags contain 2 light chartreuse bags.
|
||||
drab tan bags contain 2 light green bags, 5 bright red bags, 4 shiny beige bags.
|
||||
drab chartreuse bags contain 2 drab salmon bags, 2 dark brown bags, 4 clear turquoise bags.
|
||||
drab violet bags contain 4 faded red bags.
|
||||
posh cyan bags contain 4 bright violet bags.
|
||||
posh orange bags contain 4 pale plum bags, 5 posh aqua bags.
|
||||
plaid silver bags contain 1 dotted brown bag, 3 drab gold bags, 4 clear yellow bags.
|
||||
mirrored silver bags contain 3 shiny beige bags, 1 drab silver bag.
|
||||
faded gray bags contain no other bags.
|
||||
wavy tomato bags contain 1 bright brown bag, 3 striped red bags, 2 vibrant maroon bags.
|
||||
posh violet bags contain 2 dim aqua bags.
|
||||
bright blue bags contain 5 light lime bags, 2 faded violet bags, 3 light aqua bags, 4 vibrant coral bags.
|
||||
dark teal bags contain 5 muted fuchsia bags.
|
||||
striped fuchsia bags contain 1 wavy turquoise bag, 5 wavy green bags, 4 posh gold bags.
|
||||
posh maroon bags contain 2 dull red bags.
|
||||
shiny purple bags contain 2 clear tan bags.
|
||||
wavy lime bags contain 2 dark coral bags, 1 shiny gold bag.
|
||||
wavy silver bags contain 4 dotted white bags.
|
||||
shiny silver bags contain 2 plaid gold bags, 2 dim green bags, 5 plaid lime bags, 3 dull red bags.
|
||||
wavy red bags contain 3 vibrant brown bags, 4 bright indigo bags.
|
||||
dull chartreuse bags contain 4 dotted lime bags, 2 bright silver bags, 3 dull red bags, 4 wavy maroon bags.
|
||||
vibrant silver bags contain 1 bright fuchsia bag, 3 drab lavender bags, 2 drab olive bags, 3 dotted teal bags.
|
||||
striped gray bags contain 5 plaid orange bags, 1 wavy coral bag.
|
||||
striped green bags contain 4 wavy coral bags, 4 shiny gold bags, 3 dark brown bags, 5 vibrant brown bags.
|
||||
mirrored violet bags contain 3 dim silver bags, 1 posh tomato bag, 1 light salmon bag.
|
||||
dull purple bags contain 1 light gray bag, 3 wavy yellow bags, 1 wavy salmon bag.
|
||||
mirrored beige bags contain 4 dark cyan bags, 5 dull green bags.
|
||||
posh lime bags contain 3 posh chartreuse bags.
|
||||
vibrant tan bags contain 2 dull plum bags, 1 striped brown bag, 4 vibrant coral bags.
|
||||
dotted orange bags contain 1 mirrored olive bag, 5 drab silver bags.
|
||||
clear indigo bags contain 3 light lime bags, 4 dull coral bags.
|
||||
pale gray bags contain 1 faded black bag, 3 dim green bags, 4 wavy lavender bags, 2 posh brown bags.
|
||||
posh gold bags contain 5 dark tan bags, 2 dotted olive bags, 5 dark aqua bags.
|
||||
striped chartreuse bags contain 2 dull magenta bags, 1 posh tomato bag.
|
||||
mirrored bronze bags contain 2 faded fuchsia bags.
|
||||
clear salmon bags contain 4 posh bronze bags, 5 clear plum bags, 5 dull blue bags.
|
||||
posh purple bags contain 5 dim gray bags, 3 faded brown bags.
|
||||
faded lime bags contain 5 dim turquoise bags, 3 dark indigo bags, 2 vibrant gray bags, 1 muted silver bag.
|
||||
wavy beige bags contain 1 dark bronze bag, 4 dull plum bags, 4 mirrored silver bags.
|
||||
clear yellow bags contain 2 vibrant teal bags.
|
||||
vibrant plum bags contain 4 muted chartreuse bags, 4 posh silver bags.
|
||||
striped yellow bags contain 2 dull maroon bags, 5 bright red bags, 2 posh chartreuse bags.
|
||||
dark coral bags contain 3 dull tan bags.
|
||||
dull magenta bags contain no other bags.
|
||||
dark gold bags contain 1 dotted indigo bag, 4 shiny teal bags, 4 dotted silver bags.
|
||||
dim tan bags contain 1 striped lavender bag, 1 shiny tomato bag.
|
||||
muted maroon bags contain 2 dull salmon bags, 4 dim chartreuse bags, 3 bright aqua bags, 2 faded indigo bags.
|
||||
vibrant tomato bags contain 2 dark silver bags, 3 plaid purple bags.
|
||||
dotted lime bags contain 3 shiny crimson bags, 2 pale yellow bags.
|
||||
muted fuchsia bags contain 1 dull tan bag.
|
||||
bright tan bags contain 5 pale gold bags, 5 drab teal bags, 2 light blue bags.
|
||||
dark crimson bags contain 4 shiny orange bags, 3 faded purple bags, 3 bright white bags.
|
||||
striped tan bags contain 4 dotted turquoise bags, 4 drab lime bags, 5 dim teal bags.
|
||||
posh fuchsia bags contain 2 dotted olive bags, 2 mirrored beige bags, 3 shiny bronze bags.
|
||||
pale silver bags contain 4 vibrant lavender bags, 4 clear beige bags, 4 striped gold bags.
|
||||
posh aqua bags contain 4 drab lime bags, 4 dull tan bags, 5 vibrant tan bags.
|
||||
plaid salmon bags contain 5 dim coral bags, 2 wavy bronze bags.
|
||||
mirrored orange bags contain 4 vibrant gray bags.
|
||||
dim yellow bags contain 5 pale tan bags, 4 dark black bags.
|
||||
dotted coral bags contain 4 dotted chartreuse bags, 2 bright red bags, 1 vibrant white bag, 1 vibrant brown bag.
|
||||
muted crimson bags contain 4 striped orange bags, 5 pale yellow bags, 3 posh blue bags, 1 muted red bag.
|
||||
striped lavender bags contain 3 striped brown bags.
|
||||
striped maroon bags contain 2 shiny yellow bags.
|
||||
vibrant blue bags contain 3 faded cyan bags, 1 shiny lime bag, 3 dark tomato bags.
|
||||
pale lavender bags contain 4 plaid magenta bags, 4 striped blue bags.
|
||||
dull tan bags contain 4 shiny indigo bags, 2 light purple bags, 4 faded cyan bags.
|
||||
dotted beige bags contain 3 drab indigo bags.
|
||||
light indigo bags contain 1 faded cyan bag, 5 bright aqua bags, 1 shiny indigo bag.
|
||||
vibrant crimson bags contain 4 dotted fuchsia bags.
|
||||
wavy blue bags contain 4 wavy teal bags, 1 dull blue bag.
|
||||
vibrant chartreuse bags contain 4 striped orange bags.
|
||||
vibrant cyan bags contain 5 wavy coral bags.
|
||||
faded brown bags contain 5 faded turquoise bags.
|
||||
faded magenta bags contain 1 dull indigo bag, 4 plaid aqua bags, 4 dim crimson bags.
|
||||
mirrored coral bags contain 4 drab crimson bags, 2 light salmon bags, 2 clear indigo bags.
|
||||
faded cyan bags contain no other bags.
|
||||
dark brown bags contain 5 light purple bags.
|
||||
wavy violet bags contain 3 dull coral bags, 1 bright aqua bag, 3 shiny lavender bags.
|
||||
posh tomato bags contain 4 vibrant chartreuse bags, 4 mirrored teal bags.
|
||||
pale crimson bags contain 1 plaid orange bag, 1 dark violet bag, 3 plaid lavender bags.
|
||||
dark fuchsia bags contain 4 plaid beige bags, 2 plaid chartreuse bags.
|
||||
plaid magenta bags contain 3 clear lavender bags, 5 mirrored brown bags, 5 shiny bronze bags.
|
||||
striped blue bags contain 1 dull bronze bag, 1 dotted fuchsia bag, 1 light lavender bag, 1 clear turquoise bag.
|
||||
dotted olive bags contain 4 dotted turquoise bags, 5 dotted bronze bags, 3 pale yellow bags, 4 pale red bags.
|
||||
posh silver bags contain 3 pale violet bags, 1 plaid salmon bag, 1 posh coral bag.
|
||||
dotted chartreuse bags contain 3 bright blue bags.
|
||||
light coral bags contain 4 shiny fuchsia bags, 2 pale red bags, 1 muted silver bag, 2 bright cyan bags.
|
||||
pale brown bags contain 5 light aqua bags.
|
||||
dotted black bags contain 2 plaid purple bags, 1 mirrored aqua bag, 5 posh beige bags.
|
||||
posh coral bags contain 3 dark aqua bags, 2 pale yellow bags, 5 plaid blue bags, 4 dim aqua bags.
|
||||
shiny gray bags contain 1 bright gold bag, 1 muted bronze bag, 5 striped green bags, 5 shiny teal bags.
|
||||
drab orange bags contain 5 plaid salmon bags, 2 vibrant beige bags.
|
||||
plaid yellow bags contain 4 clear teal bags, 2 bright red bags.
|
||||
striped violet bags contain 4 mirrored fuchsia bags, 4 vibrant white bags, 3 dim teal bags.
|
||||
dim aqua bags contain 1 muted fuchsia bag, 1 dull tan bag.
|
||||
light orange bags contain 2 bright red bags, 4 dark white bags, 1 dim chartreuse bag, 5 faded fuchsia bags.
|
||||
faded salmon bags contain 5 wavy gray bags.
|
||||
shiny yellow bags contain 2 vibrant plum bags, 3 dim teal bags, 1 plaid tan bag, 5 posh plum bags.
|
||||
vibrant beige bags contain 2 wavy lavender bags, 4 posh chartreuse bags, 3 pale teal bags, 5 wavy lime bags.
|
||||
light fuchsia bags contain 3 clear brown bags, 3 bright lavender bags.
|
||||
pale magenta bags contain 4 posh silver bags.
|
||||
dark maroon bags contain 3 drab turquoise bags.
|
||||
faded beige bags contain 1 vibrant white bag, 4 drab red bags, 1 drab lavender bag.
|
||||
bright bronze bags contain 1 pale bronze bag, 3 muted silver bags, 2 striped coral bags, 3 clear gray bags.
|
||||
light silver bags contain 3 dotted lavender bags, 2 wavy lavender bags.
|
||||
muted salmon bags contain 2 drab tan bags, 5 wavy tomato bags.
|
||||
bright black bags contain 5 plaid tan bags.
|
||||
dim chartreuse bags contain 5 muted gold bags, 5 bright blue bags, 5 faded cyan bags.
|
||||
shiny white bags contain 4 bright tan bags.
|
||||
bright red bags contain 3 dull silver bags.
|
||||
dark aqua bags contain 2 dull red bags.
|
||||
drab plum bags contain 4 muted brown bags, 5 muted plum bags.
|
||||
muted yellow bags contain 5 light purple bags, 3 dotted silver bags, 3 faded turquoise bags.
|
||||
light violet bags contain 1 pale red bag, 4 dim silver bags, 2 mirrored bronze bags.
|
||||
pale lime bags contain 4 bright lavender bags.
|
||||
pale tan bags contain 4 striped green bags, 2 dotted chartreuse bags.
|
||||
dim green bags contain 1 light lime bag, 1 shiny beige bag.
|
||||
mirrored gold bags contain 4 mirrored white bags.
|
||||
dim silver bags contain 5 pale coral bags, 3 wavy coral bags.
|
||||
dull aqua bags contain 3 posh indigo bags, 5 dotted coral bags, 1 dark salmon bag, 3 striped crimson bags.
|
||||
posh yellow bags contain 1 dark bronze bag, 2 mirrored white bags, 2 light crimson bags.
|
||||
mirrored magenta bags contain 1 bright violet bag, 2 drab lavender bags, 3 pale violet bags, 2 plaid salmon bags.
|
||||
shiny chartreuse bags contain 2 dotted purple bags, 5 wavy red bags, 3 plaid beige bags.
|
||||
light black bags contain 1 dark chartreuse bag, 3 faded tomato bags.
|
||||
clear plum bags contain 5 vibrant brown bags, 3 dim coral bags, 4 mirrored brown bags, 1 faded black bag.
|
||||
pale violet bags contain 2 dull tan bags.
|
||||
bright fuchsia bags contain 4 dull orange bags.
|
||||
dotted teal bags contain 5 bright red bags, 3 wavy red bags, 1 dull coral bag, 3 clear plum bags.
|
||||
dotted blue bags contain 2 wavy beige bags, 3 muted purple bags.
|
||||
muted gray bags contain 3 faded aqua bags, 1 shiny olive bag, 5 clear salmon bags, 1 vibrant violet bag.
|
||||
dull beige bags contain 1 wavy lavender bag, 4 dark bronze bags, 5 dull tan bags.
|
||||
drab turquoise bags contain 3 posh gray bags, 5 drab red bags.
|
||||
vibrant yellow bags contain 2 shiny aqua bags, 4 light chartreuse bags.
|
||||
posh brown bags contain 3 bright green bags, 5 posh lavender bags.
|
||||
faded gold bags contain 4 vibrant maroon bags, 4 dotted purple bags.
|
||||
dotted turquoise bags contain 5 clear plum bags, 3 muted gold bags, 4 dark violet bags.
|
||||
dotted tan bags contain 5 dim aqua bags, 4 striped violet bags.
|
||||
posh crimson bags contain 4 striped blue bags, 5 dull magenta bags, 2 bright coral bags.
|
||||
muted white bags contain 5 dull olive bags.
|
||||
vibrant teal bags contain 5 dotted turquoise bags, 1 striped tan bag, 1 drab tan bag.
|
||||
dotted yellow bags contain 3 plaid turquoise bags, 2 posh yellow bags, 4 striped blue bags, 5 posh black bags.
|
||||
posh magenta bags contain 5 mirrored black bags.
|
||||
dotted green bags contain 4 dim crimson bags, 1 shiny lavender bag, 4 bright salmon bags, 1 plaid gray bag.
|
||||
bright green bags contain 3 bright aqua bags, 3 dull maroon bags, 4 dark brown bags.
|
||||
dark gray bags contain 5 muted purple bags, 2 striped blue bags, 4 faded lavender bags.
|
||||
bright crimson bags contain 2 striped olive bags, 3 muted blue bags.
|
||||
muted cyan bags contain 3 shiny tomato bags.
|
||||
light yellow bags contain 2 striped red bags, 4 shiny crimson bags.
|
||||
pale aqua bags contain 5 shiny yellow bags, 3 dark lavender bags, 3 posh white bags.
|
||||
clear red bags contain 1 dotted silver bag, 1 dull teal bag, 1 faded maroon bag, 1 dotted salmon bag.
|
||||
pale red bags contain 2 faded gray bags.
|
||||
dotted maroon bags contain 5 posh aqua bags, 3 dull silver bags.
|
||||
dull blue bags contain 4 light crimson bags, 3 light lime bags, 1 dark orange bag, 5 light indigo bags.
|
||||
posh turquoise bags contain 1 muted gold bag, 5 striped lavender bags, 3 dull salmon bags, 5 vibrant chartreuse bags.
|
||||
striped magenta bags contain 1 posh silver bag, 5 dark brown bags.
|
||||
pale blue bags contain 2 muted gold bags, 4 vibrant brown bags, 1 light lavender bag.
|
||||
vibrant violet bags contain 5 bright red bags.
|
||||
faded fuchsia bags contain 2 light lime bags, 4 bright lime bags, 3 pale violet bags.
|
||||
shiny coral bags contain 1 clear plum bag, 5 muted chartreuse bags, 1 muted violet bag, 5 striped yellow bags.
|
||||
pale olive bags contain 4 plaid lime bags, 1 posh salmon bag.
|
||||
wavy tan bags contain 3 faded gray bags.
|
||||
faded chartreuse bags contain 3 dim coral bags, 1 mirrored bronze bag, 3 posh bronze bags.
|
||||
mirrored brown bags contain 1 faded violet bag, 4 dull maroon bags, 5 dotted magenta bags.
|
||||
clear white bags contain 5 muted magenta bags, 4 dull magenta bags, 3 pale plum bags, 4 drab indigo bags.
|
||||
drab maroon bags contain 2 clear beige bags, 3 wavy beige bags, 5 faded purple bags.
|
||||
striped silver bags contain 3 drab tomato bags.
|
||||
faded plum bags contain 1 clear teal bag, 3 bright aqua bags.
|
||||
plaid violet bags contain 2 drab violet bags, 4 muted turquoise bags, 5 muted indigo bags.
|
||||
clear black bags contain 5 muted fuchsia bags, 1 muted coral bag, 2 light black bags.
|
||||
vibrant maroon bags contain 1 dark lavender bag, 1 pale crimson bag, 4 bright indigo bags, 5 mirrored maroon bags.
|
||||
drab indigo bags contain 2 dim coral bags, 1 drab green bag, 2 shiny lavender bags.
|
||||
drab olive bags contain 2 dark aqua bags, 4 striped brown bags.
|
||||
dull crimson bags contain 3 dull cyan bags.
|
||||
wavy teal bags contain 4 striped orange bags, 2 drab cyan bags.
|
||||
dark red bags contain 2 dull maroon bags, 4 muted plum bags, 4 dull plum bags.
|
||||
striped salmon bags contain 3 bright red bags, 1 light aqua bag, 4 wavy gold bags.
|
||||
mirrored tan bags contain 5 dotted olive bags, 2 dim tomato bags, 2 mirrored tomato bags, 4 clear teal bags.
|
||||
striped white bags contain 2 pale coral bags, 2 shiny green bags.
|
||||
shiny tomato bags contain 5 pale coral bags, 5 dull beige bags.
|
||||
vibrant indigo bags contain 2 dim black bags, 4 dim blue bags, 3 dim white bags.
|
||||
wavy lavender bags contain 4 faded bronze bags, 4 muted red bags, 3 light lime bags, 4 muted gold bags.
|
||||
shiny turquoise bags contain 2 dull red bags, 5 faded gray bags, 1 muted turquoise bag.
|
||||
shiny lavender bags contain 5 bright aqua bags.
|
||||
posh tan bags contain 1 shiny yellow bag, 3 drab magenta bags.
|
||||
light green bags contain 4 bright red bags, 1 vibrant coral bag.
|
||||
drab black bags contain 5 faded tomato bags, 3 dotted chartreuse bags.
|
||||
clear chartreuse bags contain 3 wavy bronze bags, 4 plaid purple bags, 3 dark orange bags.
|
||||
dull black bags contain 1 wavy teal bag, 3 light lavender bags, 2 striped indigo bags.
|
||||
wavy black bags contain 2 clear orange bags, 4 muted purple bags.
|
||||
pale plum bags contain 1 bright coral bag, 1 drab tan bag, 1 plaid fuchsia bag, 1 dotted fuchsia bag.
|
||||
dotted violet bags contain 3 bright black bags.
|
||||
posh red bags contain 3 bright black bags.
|
||||
plaid lime bags contain 5 posh beige bags, 1 dotted turquoise bag.
|
||||
wavy aqua bags contain 1 dark yellow bag, 3 drab indigo bags.
|
||||
dim magenta bags contain 3 dark violet bags.
|
||||
drab aqua bags contain 5 posh orange bags, 1 dark silver bag, 4 plaid purple bags, 2 wavy teal bags.
|
||||
dull brown bags contain 4 light lime bags.
|
||||
striped orange bags contain 5 light crimson bags, 3 muted tan bags, 5 dotted coral bags, 3 plaid blue bags.
|
||||
muted brown bags contain 1 posh blue bag, 4 dotted magenta bags, 3 dull coral bags.
|
||||
faded blue bags contain 5 striped black bags, 1 vibrant yellow bag.
|
||||
plaid indigo bags contain 3 dark brown bags, 5 light purple bags, 4 light aqua bags, 3 light green bags.
|
||||
plaid turquoise bags contain 5 dotted teal bags.
|
||||
light turquoise bags contain 2 dull salmon bags, 5 dotted tan bags.
|
||||
dim purple bags contain 4 muted white bags, 5 drab purple bags.
|
||||
pale coral bags contain 5 posh gray bags.
|
||||
clear lime bags contain 3 dim magenta bags, 3 plaid tomato bags, 1 drab magenta bag, 3 shiny purple bags.
|
||||
dim black bags contain 3 clear gold bags, 4 muted violet bags.
|
||||
light maroon bags contain 4 muted yellow bags, 1 pale cyan bag, 2 mirrored turquoise bags, 4 dull lavender bags.
|
||||
clear magenta bags contain 2 shiny magenta bags, 2 muted chartreuse bags.
|
||||
striped bronze bags contain 5 clear tan bags, 1 drab lavender bag, 2 pale crimson bags.
|
||||
dark salmon bags contain 1 vibrant plum bag, 5 drab tan bags, 4 drab coral bags, 4 dull tan bags.
|
||||
vibrant salmon bags contain 2 muted olive bags.
|
||||
dim gold bags contain 2 dim olive bags, 5 plaid olive bags, 2 posh orange bags.
|
||||
wavy chartreuse bags contain 4 shiny yellow bags, 4 vibrant blue bags.
|
||||
vibrant brown bags contain 3 striped brown bags, 4 muted red bags, 2 shiny indigo bags.
|
||||
plaid maroon bags contain 2 muted teal bags, 2 pale yellow bags, 2 bright beige bags, 5 striped yellow bags.
|
||||
dim indigo bags contain 4 dull tomato bags, 4 clear cyan bags, 2 shiny salmon bags, 1 bright aqua bag.
|
||||
muted red bags contain 3 dull tan bags, 4 dull magenta bags, 1 bright aqua bag.
|
||||
posh beige bags contain 5 shiny black bags, 3 dotted magenta bags, 3 drab blue bags, 2 muted coral bags.
|
||||
pale fuchsia bags contain 3 dark brown bags, 5 posh gold bags.
|
||||
dark bronze bags contain 1 dim green bag, 5 posh chartreuse bags.
|
||||
dim coral bags contain 3 dull coral bags, 3 striped brown bags.
|
||||
drab crimson bags contain 2 dark bronze bags, 4 shiny indigo bags, 3 dull tan bags.
|
||||
bright indigo bags contain 3 bright blue bags.
|
||||
pale yellow bags contain 5 dim aqua bags, 1 vibrant brown bag, 2 vibrant tan bags, 3 wavy lavender bags.
|
||||
drab salmon bags contain 1 dotted indigo bag, 3 muted chartreuse bags, 5 dark olive bags.
|
||||
muted orange bags contain 4 faded lime bags, 2 dull coral bags, 5 vibrant magenta bags, 4 dull magenta bags.
|
||||
striped gold bags contain 2 dull silver bags, 5 bright lavender bags, 5 dim teal bags, 5 dark coral bags.
|
||||
posh chartreuse bags contain 3 dim teal bags, 5 light aqua bags.
|
||||
shiny blue bags contain 3 dull tan bags, 5 muted magenta bags.
|
||||
muted silver bags contain 3 wavy blue bags, 2 dim teal bags, 5 muted bronze bags.
|
||||
shiny bronze bags contain 1 light green bag, 4 vibrant magenta bags.
|
||||
wavy coral bags contain no other bags.
|
||||
shiny orange bags contain 2 muted purple bags.
|
||||
posh teal bags contain 4 clear plum bags.
|
||||
striped turquoise bags contain 3 muted indigo bags.
|
||||
dim bronze bags contain 2 shiny silver bags, 1 light silver bag, 2 dim indigo bags, 4 dim tomato bags.
|
||||
plaid white bags contain 4 drab turquoise bags.
|
||||
wavy indigo bags contain 3 clear gold bags, 5 mirrored bronze bags.
|
||||
faded teal bags contain 4 mirrored white bags.
|
||||
shiny fuchsia bags contain 3 drab indigo bags.
|
||||
dim red bags contain 3 clear bronze bags.
|
||||
dotted brown bags contain 4 wavy maroon bags, 5 drab green bags, 3 dark purple bags.
|
||||
dark tomato bags contain 3 vibrant coral bags, 5 dull coral bags, 2 drab cyan bags, 1 posh blue bag.
|
||||
clear teal bags contain 3 dark white bags.
|
||||
dark silver bags contain 3 dark cyan bags, 4 plaid salmon bags.
|
||||
wavy fuchsia bags contain 4 bright brown bags, 4 bright aqua bags, 5 light orange bags.
|
||||
light bronze bags contain 4 clear plum bags.
|
||||
striped purple bags contain 1 dim indigo bag.
|
||||
clear tomato bags contain 4 mirrored tomato bags, 3 muted indigo bags, 1 striped tan bag.
|
||||
muted turquoise bags contain 5 faded beige bags, 4 clear crimson bags, 2 bright teal bags.
|
||||
dull cyan bags contain 5 mirrored aqua bags, 2 shiny aqua bags, 3 light black bags, 4 bright coral bags.
|
||||
plaid crimson bags contain 2 mirrored teal bags, 2 dull fuchsia bags.
|
||||
shiny maroon bags contain 1 posh gold bag.
|
||||
dim white bags contain 5 striped brown bags, 2 dull magenta bags, 5 plaid tan bags.
|
||||
muted green bags contain 2 dull magenta bags, 5 clear cyan bags.
|
||||
plaid teal bags contain 2 dark tan bags, 3 pale lime bags.
|
||||
dotted lavender bags contain 2 posh aqua bags, 3 dull cyan bags.
|
||||
light salmon bags contain 5 dark silver bags.
|
||||
faded white bags contain 2 wavy maroon bags, 3 dull cyan bags.
|
||||
dull tomato bags contain 2 dim aqua bags, 4 posh lavender bags, 1 faded red bag.
|
||||
dark olive bags contain 5 clear bronze bags, 2 drab plum bags.
|
||||
pale indigo bags contain 2 mirrored beige bags, 5 wavy turquoise bags, 4 striped green bags, 2 dotted lavender bags.
|
||||
plaid purple bags contain 1 light lime bag.
|
||||
clear purple bags contain 3 vibrant white bags.
|
||||
dark yellow bags contain 2 pale olive bags, 4 pale cyan bags, 5 bright teal bags.
|
||||
muted beige bags contain 2 posh lime bags, 5 shiny gray bags, 2 dull blue bags.
|
||||
vibrant orange bags contain 5 posh crimson bags, 4 light chartreuse bags.
|
||||
light magenta bags contain 2 plaid maroon bags, 1 posh beige bag, 5 pale salmon bags.
|
||||
dotted crimson bags contain 5 dark chartreuse bags.
|
||||
striped coral bags contain 2 dim aqua bags.
|
||||
striped aqua bags contain 3 posh salmon bags, 3 dull red bags.
|
||||
mirrored salmon bags contain 5 bright red bags, 2 light green bags, 3 clear black bags, 5 posh brown bags.
|
||||
posh white bags contain 4 drab violet bags, 2 dotted silver bags.
|
||||
posh blue bags contain 4 dull maroon bags, 3 vibrant coral bags.
|
||||
dim orange bags contain 2 dull olive bags.
|
||||
shiny teal bags contain 1 faded tomato bag, 4 muted violet bags.
|
||||
mirrored maroon bags contain 3 dull blue bags.
|
||||
dark lavender bags contain 1 drab red bag, 3 shiny indigo bags, 4 faded beige bags, 1 drab turquoise bag.
|
||||
shiny olive bags contain 3 dark violet bags, 1 striped gold bag, 2 mirrored lime bags.
|
||||
bright violet bags contain 2 wavy bronze bags, 3 drab olive bags, 5 mirrored olive bags, 2 wavy lavender bags.
|
||||
clear olive bags contain 5 faded turquoise bags.
|
||||
mirrored lavender bags contain 1 light white bag, 4 light purple bags, 3 wavy lavender bags, 2 shiny lime bags.
|
||||
pale turquoise bags contain 4 dark tan bags.
|
||||
shiny salmon bags contain 1 shiny gold bag, 5 drab turquoise bags.
|
||||
vibrant gray bags contain 3 posh brown bags.
|
||||
dark indigo bags contain 1 mirrored black bag, 5 dull beige bags, 4 shiny beige bags, 3 drab lavender bags.
|
||||
light teal bags contain 5 dark olive bags, 5 vibrant chartreuse bags, 3 plaid salmon bags, 5 light yellow bags.
|
||||
clear violet bags contain 3 light crimson bags.
|
||||
clear tan bags contain 3 striped orange bags, 4 wavy lavender bags, 3 striped silver bags.
|
||||
clear bronze bags contain 2 plaid beige bags.
|
||||
clear gray bags contain 4 dotted cyan bags, 4 vibrant plum bags.
|
||||
drab cyan bags contain 1 light aqua bag, 1 drab teal bag, 3 bright orange bags, 3 dark white bags.
|
||||
plaid beige bags contain 3 dull green bags.
|
||||
wavy gold bags contain 4 shiny olive bags, 3 bright tan bags.
|
||||
clear aqua bags contain 3 posh chartreuse bags, 4 drab silver bags, 5 clear gray bags.
|
||||
bright chartreuse bags contain 2 light violet bags, 3 vibrant gray bags.
|
||||
plaid black bags contain 2 posh gray bags.
|
||||
light beige bags contain 4 dotted olive bags, 5 dull olive bags, 1 faded orange bag.
|
||||
mirrored teal bags contain 4 mirrored aqua bags.
|
||||
bright magenta bags contain 1 mirrored magenta bag, 3 bright blue bags, 1 vibrant blue bag, 2 drab gold bags.
|
||||
dim maroon bags contain 4 light bronze bags, 5 clear violet bags.
|
||||
light lime bags contain 4 plaid indigo bags.
|
||||
posh lavender bags contain 4 dark brown bags.
|
||||
clear beige bags contain 4 posh silver bags, 3 dull coral bags, 2 posh gray bags.
|
||||
drab bronze bags contain 4 plaid maroon bags.
|
||||
mirrored purple bags contain 3 dim magenta bags.
|
||||
dark magenta bags contain 4 faded maroon bags, 1 drab crimson bag, 5 dotted brown bags, 2 bright teal bags.
|
||||
dim brown bags contain 3 muted olive bags, 5 drab green bags, 1 mirrored olive bag.
|
||||
dark plum bags contain 2 vibrant tan bags.
|
||||
bright turquoise bags contain 1 mirrored aqua bag, 3 clear plum bags.
|
||||
muted black bags contain 5 faded cyan bags, 5 pale tan bags, 2 dotted chartreuse bags.
|
||||
dotted gray bags contain 3 posh plum bags.
|
||||
vibrant black bags contain 2 vibrant magenta bags, 5 faded cyan bags.
|
||||
mirrored cyan bags contain 2 clear cyan bags, 4 light aqua bags, 5 drab blue bags, 1 drab gold bag.
|
||||
wavy purple bags contain 5 striped magenta bags, 3 clear maroon bags, 1 mirrored green bag, 1 pale black bag.
|
||||
drab blue bags contain 3 mirrored lime bags, 1 mirrored blue bag.
|
||||
clear maroon bags contain 5 bright orange bags.
|
||||
shiny cyan bags contain 2 clear gray bags, 5 pale crimson bags.
|
||||
pale cyan bags contain 2 wavy turquoise bags, 5 wavy salmon bags.
|
||||
plaid gold bags contain 1 clear lavender bag, 1 bright beige bag.
|
||||
mirrored lime bags contain 2 dull tan bags, 3 shiny beige bags.
|
||||
drab green bags contain 1 vibrant yellow bag.
|
||||
dull red bags contain 5 plaid blue bags, 5 clear brown bags, 3 pale salmon bags, 2 dark orange bags.
|
||||
bright beige bags contain 4 dull silver bags, 5 vibrant brown bags, 4 drab red bags, 2 pale violet bags.
|
||||
clear silver bags contain 4 drab indigo bags, 2 clear salmon bags.
|
||||
posh bronze bags contain 5 bright indigo bags, 5 dotted purple bags, 1 dark violet bag, 2 dark orange bags.
|
||||
posh salmon bags contain 5 bright red bags, 3 striped green bags, 3 dark brown bags.
|
||||
clear cyan bags contain 5 dark chartreuse bags, 1 bright indigo bag, 4 pale yellow bags, 2 vibrant coral bags.
|
||||
mirrored blue bags contain 2 vibrant white bags.
|
||||
mirrored yellow bags contain 5 dotted gray bags, 4 dull maroon bags, 2 striped violet bags, 5 clear tomato bags.
|
||||
striped teal bags contain 2 clear black bags, 3 pale coral bags.
|
||||
faded orange bags contain 2 dark bronze bags.
|
||||
mirrored indigo bags contain 3 light tomato bags, 2 shiny crimson bags.
|
||||
pale green bags contain 4 light chartreuse bags.
|
||||
plaid cyan bags contain 4 plaid fuchsia bags, 2 shiny teal bags, 3 dotted fuchsia bags, 3 dim red bags.
|
||||
muted gold bags contain 2 dull tan bags, 1 faded bronze bag, 4 dull maroon bags.
|
||||
wavy green bags contain 5 pale coral bags, 1 dull blue bag, 4 drab blue bags, 1 striped tan bag.
|
||||
light chartreuse bags contain 4 striped brown bags, 5 plaid purple bags, 4 drab cyan bags, 3 dull plum bags.
|
||||
dotted cyan bags contain 4 shiny black bags.
|
||||
light purple bags contain no other bags.
|
||||
dotted aqua bags contain 4 light gray bags, 2 light purple bags, 5 mirrored lime bags.
|
||||
drab gold bags contain 2 bright green bags, 5 bright indigo bags.
|
||||
posh gray bags contain 5 bright orange bags, 5 bright blue bags.
|
||||
striped red bags contain 4 drab green bags, 1 clear cyan bag.
|
||||
dotted bronze bags contain 5 light orange bags.
|
||||
muted plum bags contain 2 bright black bags, 3 dotted tomato bags, 2 vibrant brown bags.
|
||||
mirrored black bags contain 3 plaid chartreuse bags, 2 shiny indigo bags, 2 shiny beige bags.
|
||||
drab lavender bags contain 5 drab cyan bags, 1 muted purple bag, 1 wavy red bag, 3 drab crimson bags.
|
||||
vibrant turquoise bags contain 3 shiny beige bags, 3 striped brown bags, 5 dim teal bags.
|
||||
muted tan bags contain 1 plaid purple bag, 3 shiny beige bags, 1 drab gold bag.
|
||||
pale beige bags contain 5 bright silver bags.
|
||||
wavy olive bags contain 4 dotted turquoise bags, 4 dull silver bags, 1 bright gold bag.
|
||||
dim olive bags contain 5 light lavender bags, 4 shiny tomato bags, 4 clear cyan bags.
|
||||
wavy salmon bags contain 4 bright aqua bags.
|
||||
dotted gold bags contain 3 shiny red bags, 3 dull fuchsia bags.
|
||||
shiny violet bags contain 3 dotted tomato bags, 1 drab coral bag.
|
||||
striped plum bags contain 4 drab beige bags, 3 clear tan bags, 5 light aqua bags, 1 shiny fuchsia bag.
|
||||
clear lavender bags contain 2 bright aqua bags, 3 dull silver bags, 3 bright green bags, 2 bright orange bags.
|
||||
faded maroon bags contain 5 dark indigo bags, 1 posh fuchsia bag.
|
||||
vibrant red bags contain 4 striped fuchsia bags, 3 drab orange bags, 1 clear brown bag, 1 plaid turquoise bag.
|
||||
dull coral bags contain 2 dim teal bags, 3 faded bronze bags.
|
||||
pale salmon bags contain 3 dull magenta bags, 1 light crimson bag.
|
||||
dotted magenta bags contain 4 dull maroon bags, 2 bright lime bags, 4 plaid indigo bags, 4 faded cyan bags.
|
||||
wavy gray bags contain 4 muted gray bags, 3 shiny magenta bags, 1 posh teal bag.
|
||||
light red bags contain 4 shiny chartreuse bags.
|
||||
dim blue bags contain 4 vibrant orange bags.
|
||||
muted bronze bags contain 5 mirrored aqua bags, 4 dim green bags.
|
||||
drab lime bags contain 1 drab cyan bag, 3 pale crimson bags, 4 bright green bags, 3 drab lavender bags.
|
||||
light white bags contain 5 bright green bags.
|
||||
bright teal bags contain 4 shiny brown bags, 4 dark silver bags.
|
||||
striped beige bags contain 2 shiny magenta bags.
|
||||
wavy magenta bags contain 5 pale bronze bags, 5 pale plum bags, 3 muted silver bags.
|
||||
dark orange bags contain 1 drab tomato bag, 3 striped brown bags, 1 dim teal bag, 5 bright beige bags.
|
||||
striped indigo bags contain 1 vibrant gold bag, 1 shiny green bag.
|
||||
clear coral bags contain 2 shiny gray bags.
|
||||
faded yellow bags contain 4 faded gold bags, 2 bright turquoise bags, 5 dark silver bags, 3 wavy coral bags.
|
||||
dim plum bags contain 1 clear purple bag, 4 light brown bags.
|
||||
mirrored turquoise bags contain 5 wavy indigo bags, 3 dark fuchsia bags, 5 plaid white bags, 2 dim turquoise bags.
|
||||
posh black bags contain 2 striped black bags, 5 dim teal bags, 3 bright silver bags, 5 posh beige bags.
|
||||
dotted fuchsia bags contain 1 faded turquoise bag, 2 shiny lavender bags, 4 posh salmon bags, 1 clear olive bag.
|
||||
faded lavender bags contain 2 striped yellow bags, 1 posh lavender bag.
|
||||
dim lime bags contain 2 wavy gray bags, 5 clear gray bags.
|
||||
vibrant bronze bags contain 3 drab tomato bags, 5 bright tan bags.
|
||||
dull plum bags contain 5 bright red bags, 4 dull magenta bags.
|
||||
dim teal bags contain 4 light purple bags, 4 plaid lavender bags, 1 dull magenta bag.
|
||||
dull yellow bags contain 4 vibrant orange bags, 1 dark tomato bag, 5 pale tan bags.
|
||||
dull green bags contain 2 bright blue bags, 5 dull red bags.
|
||||
light crimson bags contain 5 dull maroon bags, 4 muted gold bags.
|
||||
dark black bags contain 1 dim silver bag, 3 plaid magenta bags.
|
||||
bright lavender bags contain 4 muted fuchsia bags.
|
||||
drab coral bags contain 4 shiny chartreuse bags, 3 posh yellow bags, 3 wavy indigo bags.
|
||||
mirrored crimson bags contain 3 posh maroon bags, 5 striped olive bags, 3 mirrored magenta bags.
|
||||
muted coral bags contain 3 wavy violet bags, 1 dotted chartreuse bag, 1 shiny beige bag.
|
||||
vibrant gold bags contain 2 dull orange bags, 1 clear chartreuse bag.
|
||||
wavy orange bags contain 5 dark bronze bags.
|
||||
mirrored white bags contain 5 clear gold bags, 3 drab tomato bags, 4 dotted bronze bags, 3 striped orange bags.
|
||||
clear gold bags contain 3 drab indigo bags, 4 wavy violet bags, 2 shiny salmon bags, 4 light brown bags.
|
||||
shiny magenta bags contain 5 drab silver bags, 2 muted gold bags.
|
||||
dim violet bags contain 1 posh lime bag, 4 shiny orange bags, 2 posh chartreuse bags.
|
||||
striped olive bags contain 4 plaid indigo bags, 5 dim chartreuse bags, 4 clear lavender bags.
|
||||
plaid gray bags contain 3 shiny gold bags, 2 dull coral bags.
|
||||
clear crimson bags contain 4 shiny aqua bags, 3 light crimson bags, 5 dim chartreuse bags.
|
||||
drab silver bags contain 1 dim teal bag, 3 faded cyan bags, 1 shiny indigo bag.
|
||||
mirrored green bags contain 5 dotted lime bags, 4 pale cyan bags.
|
||||
bright aqua bags contain no other bags.
|
||||
bright plum bags contain 4 dim aqua bags, 2 dull crimson bags, 1 wavy maroon bag.
|
||||
vibrant lavender bags contain 1 plaid tan bag, 3 vibrant brown bags, 3 drab gold bags, 4 faded red bags.
|
||||
pale white bags contain 3 bright brown bags, 4 mirrored beige bags.
|
||||
plaid lavender bags contain 1 dull magenta bag, 2 dull silver bags, 1 shiny indigo bag.
|
||||
bright salmon bags contain 1 striped coral bag, 4 plaid lavender bags, 1 muted red bag, 1 drab red bag.
|
||||
plaid olive bags contain 5 faded turquoise bags, 4 dim green bags, 2 striped beige bags.
|
||||
wavy plum bags contain 1 clear lavender bag, 2 faded brown bags.
|
||||
clear fuchsia bags contain 1 muted bronze bag.
|
||||
wavy turquoise bags contain 5 shiny lime bags, 1 drab olive bag, 4 dim white bags, 1 dotted gray bag.
|
||||
vibrant aqua bags contain 2 faded lavender bags.
|
||||
dotted white bags contain 3 muted crimson bags, 5 mirrored white bags, 1 mirrored fuchsia bag.
|
||||
bright purple bags contain 2 dotted chartreuse bags, 4 posh cyan bags, 3 bright plum bags.
|
||||
light aqua bags contain 1 plaid lavender bag, 3 wavy coral bags, 5 shiny indigo bags.
|
||||
drab yellow bags contain 4 shiny teal bags, 2 dotted green bags, 5 vibrant silver bags, 3 dotted turquoise bags.
|
||||
mirrored olive bags contain 1 dull plum bag.
|
||||
light olive bags contain 1 shiny coral bag, 4 drab white bags, 3 dim turquoise bags, 4 dull gold bags.
|
||||
shiny indigo bags contain no other bags.
|
||||
dull gold bags contain 3 dark indigo bags.
|
||||
bright tomato bags contain 5 muted blue bags.
|
||||
faded purple bags contain 4 bright orange bags, 2 faded violet bags.
|
||||
drab magenta bags contain 3 wavy lavender bags, 2 drab cyan bags, 2 clear beige bags, 4 bright indigo bags.
|
||||
striped lime bags contain 4 light tan bags.
|
||||
light gold bags contain 2 pale plum bags.
|
||||
striped black bags contain 1 plaid salmon bag, 2 plaid beige bags, 4 dotted teal bags, 2 posh chartreuse bags.
|
||||
faded tomato bags contain 2 striped yellow bags, 4 muted red bags.
|
||||
dull fuchsia bags contain 5 dotted olive bags, 2 muted purple bags.
|
||||
pale purple bags contain 4 posh silver bags, 4 wavy yellow bags.
|
||||
bright olive bags contain 5 shiny fuchsia bags, 5 dull crimson bags, 5 drab red bags, 5 posh turquoise bags.
|
||||
vibrant fuchsia bags contain 1 vibrant beige bag, 5 shiny magenta bags.
|
||||
faded turquoise bags contain 5 light lime bags, 4 dark white bags.
|
||||
plaid orange bags contain 5 vibrant coral bags, 4 light crimson bags, 4 plaid chartreuse bags, 1 dull green bag.
|
||||
posh indigo bags contain 3 wavy green bags, 2 shiny orange bags, 5 faded violet bags, 2 dotted coral bags.
|
||||
mirrored red bags contain 4 mirrored olive bags, 1 dark silver bag, 1 dull red bag.
|
||||
dim salmon bags contain 1 striped salmon bag, 5 faded gray bags.
|
||||
dim cyan bags contain 3 wavy olive bags, 5 drab purple bags, 3 mirrored bronze bags.
|
||||
light blue bags contain 2 striped bronze bags, 4 dull white bags, 1 posh bronze bag.
|
||||
dull turquoise bags contain 4 striped red bags, 1 light lavender bag, 5 plaid bronze bags, 1 mirrored brown bag.
|
||||
vibrant coral bags contain 1 bright orange bag.
|
||||
striped cyan bags contain 2 dark white bags, 4 drab red bags, 2 plaid salmon bags.
|
||||
muted tomato bags contain 4 drab red bags, 3 vibrant silver bags, 4 clear fuchsia bags, 3 wavy white bags.
|
||||
dotted red bags contain 1 light blue bag.
|
||||
dark beige bags contain 2 posh lime bags, 3 striped black bags.
|
||||
dark cyan bags contain 1 dim chartreuse bag, 2 shiny beige bags, 4 dotted magenta bags, 4 light chartreuse bags.
|
||||
dull lime bags contain 3 muted chartreuse bags.
|
||||
light brown bags contain 3 mirrored brown bags.
|
||||
vibrant magenta bags contain 1 dim green bag.
|
||||
shiny brown bags contain 5 bright brown bags, 3 faded cyan bags, 5 clear tan bags, 2 plaid maroon bags.
|
||||
drab purple bags contain 1 shiny indigo bag, 4 striped yellow bags.
|
51
2020/d08/ex1/ex1.py
Executable file
51
2020/d08/ex1/ex1.py
Executable file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
def run(code: List[Tuple[str, int]]) -> int:
|
||||
accumulator = 0
|
||||
rip = 0
|
||||
|
||||
def acc(val: int) -> None:
|
||||
nonlocal accumulator
|
||||
nonlocal rip
|
||||
accumulator += val
|
||||
rip += 1
|
||||
|
||||
def nop(val: int) -> None:
|
||||
nonlocal rip
|
||||
rip += 1
|
||||
|
||||
def jmp(val: int) -> None:
|
||||
nonlocal rip
|
||||
rip += val
|
||||
|
||||
instrs = {
|
||||
"acc": acc,
|
||||
"jmp": jmp,
|
||||
"nop": nop,
|
||||
}
|
||||
seen = set()
|
||||
|
||||
while rip not in seen:
|
||||
seen |= {rip}
|
||||
func = instrs[code[rip][0]]
|
||||
func(code[rip][1])
|
||||
|
||||
return accumulator
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
return run([(line[:3], int(line[3:])) for line in raw])
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
675
2020/d08/ex1/input
Normal file
675
2020/d08/ex1/input
Normal file
|
@ -0,0 +1,675 @@
|
|||
acc -8
|
||||
jmp +5
|
||||
acc +0
|
||||
acc +44
|
||||
acc +42
|
||||
jmp +324
|
||||
acc -17
|
||||
jmp +1
|
||||
acc -17
|
||||
jmp +51
|
||||
acc -13
|
||||
acc +4
|
||||
jmp +1
|
||||
nop +608
|
||||
jmp +274
|
||||
acc -17
|
||||
jmp +169
|
||||
acc +28
|
||||
nop +508
|
||||
jmp +1
|
||||
jmp +570
|
||||
acc +22
|
||||
acc -14
|
||||
jmp +377
|
||||
acc -13
|
||||
acc +27
|
||||
jmp +474
|
||||
acc -5
|
||||
jmp +1
|
||||
acc +12
|
||||
jmp +37
|
||||
jmp +184
|
||||
acc +36
|
||||
acc +32
|
||||
acc -8
|
||||
jmp +465
|
||||
acc -13
|
||||
acc +18
|
||||
jmp +169
|
||||
acc +20
|
||||
acc +26
|
||||
acc +23
|
||||
jmp +333
|
||||
jmp +584
|
||||
acc +9
|
||||
acc +28
|
||||
acc +28
|
||||
nop +571
|
||||
jmp +143
|
||||
acc +39
|
||||
acc +39
|
||||
acc -16
|
||||
jmp +361
|
||||
acc +48
|
||||
acc +3
|
||||
acc +15
|
||||
nop +4
|
||||
jmp +504
|
||||
acc +6
|
||||
jmp +285
|
||||
acc +26
|
||||
acc +33
|
||||
jmp +1
|
||||
acc +36
|
||||
jmp +577
|
||||
acc +36
|
||||
jmp +6
|
||||
nop +498
|
||||
acc +42
|
||||
jmp +496
|
||||
acc +10
|
||||
jmp +74
|
||||
acc +17
|
||||
acc +16
|
||||
acc +30
|
||||
jmp +254
|
||||
acc -3
|
||||
acc +16
|
||||
acc -2
|
||||
nop +106
|
||||
jmp +541
|
||||
acc -15
|
||||
jmp +579
|
||||
jmp +165
|
||||
acc +22
|
||||
acc -6
|
||||
acc +29
|
||||
acc -19
|
||||
jmp +342
|
||||
acc -19
|
||||
jmp +340
|
||||
acc +13
|
||||
acc +25
|
||||
acc +29
|
||||
jmp +269
|
||||
acc -14
|
||||
acc +27
|
||||
acc +41
|
||||
acc +49
|
||||
jmp +181
|
||||
nop +350
|
||||
jmp +1
|
||||
nop +437
|
||||
acc +34
|
||||
jmp +494
|
||||
acc +19
|
||||
acc +2
|
||||
acc +44
|
||||
jmp +558
|
||||
acc +10
|
||||
jmp +44
|
||||
nop +4
|
||||
nop -80
|
||||
nop +540
|
||||
jmp +16
|
||||
acc +28
|
||||
jmp +14
|
||||
acc +13
|
||||
nop +399
|
||||
acc +29
|
||||
nop -60
|
||||
jmp -6
|
||||
acc +41
|
||||
acc +30
|
||||
jmp +232
|
||||
acc +28
|
||||
nop +495
|
||||
acc +15
|
||||
acc +48
|
||||
jmp +157
|
||||
nop +483
|
||||
jmp -59
|
||||
acc +5
|
||||
acc +30
|
||||
acc +30
|
||||
acc +2
|
||||
jmp +349
|
||||
acc +11
|
||||
acc +27
|
||||
acc +1
|
||||
jmp +367
|
||||
acc +8
|
||||
acc +45
|
||||
acc +11
|
||||
jmp +171
|
||||
jmp -113
|
||||
acc +48
|
||||
jmp -38
|
||||
acc +12
|
||||
jmp +145
|
||||
acc +8
|
||||
nop +29
|
||||
nop +319
|
||||
jmp +154
|
||||
nop +166
|
||||
jmp +395
|
||||
nop +15
|
||||
jmp +237
|
||||
acc +22
|
||||
acc +3
|
||||
acc +42
|
||||
acc +1
|
||||
jmp +288
|
||||
jmp -63
|
||||
nop +489
|
||||
acc +33
|
||||
jmp +247
|
||||
jmp +1
|
||||
acc -8
|
||||
acc +9
|
||||
jmp +413
|
||||
acc -17
|
||||
acc +3
|
||||
acc +3
|
||||
jmp +432
|
||||
nop -17
|
||||
acc +36
|
||||
nop +198
|
||||
acc +45
|
||||
jmp +109
|
||||
nop +242
|
||||
acc +40
|
||||
acc +11
|
||||
jmp +448
|
||||
jmp +437
|
||||
acc +3
|
||||
acc +49
|
||||
acc +27
|
||||
jmp +221
|
||||
nop +158
|
||||
jmp +143
|
||||
acc +50
|
||||
jmp -70
|
||||
acc +46
|
||||
acc +8
|
||||
acc +35
|
||||
acc -3
|
||||
jmp +104
|
||||
acc +11
|
||||
acc +0
|
||||
jmp +34
|
||||
nop +132
|
||||
jmp +425
|
||||
jmp +219
|
||||
acc -12
|
||||
acc +48
|
||||
jmp +21
|
||||
jmp +434
|
||||
acc +30
|
||||
acc +1
|
||||
acc +40
|
||||
jmp +435
|
||||
jmp +132
|
||||
acc +40
|
||||
jmp +236
|
||||
jmp +179
|
||||
jmp -149
|
||||
acc +25
|
||||
acc +40
|
||||
acc -9
|
||||
acc +49
|
||||
jmp +445
|
||||
nop +399
|
||||
acc -14
|
||||
nop +374
|
||||
acc +0
|
||||
jmp +152
|
||||
acc +39
|
||||
nop +322
|
||||
acc +49
|
||||
nop +117
|
||||
jmp -19
|
||||
acc +24
|
||||
jmp +385
|
||||
acc +17
|
||||
acc +39
|
||||
acc +44
|
||||
acc -8
|
||||
jmp -58
|
||||
acc -18
|
||||
nop -76
|
||||
jmp +66
|
||||
acc +14
|
||||
jmp +427
|
||||
acc +11
|
||||
acc +47
|
||||
acc +9
|
||||
jmp +1
|
||||
acc +42
|
||||
jmp -7
|
||||
acc -16
|
||||
acc -13
|
||||
jmp +409
|
||||
acc +1
|
||||
acc +35
|
||||
acc +34
|
||||
jmp +371
|
||||
acc +24
|
||||
acc +46
|
||||
acc -4
|
||||
jmp +367
|
||||
acc +19
|
||||
acc +27
|
||||
acc -8
|
||||
acc +41
|
||||
jmp -184
|
||||
nop -185
|
||||
acc +23
|
||||
acc -8
|
||||
acc +35
|
||||
jmp -9
|
||||
acc -7
|
||||
nop -101
|
||||
nop +121
|
||||
acc +37
|
||||
jmp -72
|
||||
acc +24
|
||||
jmp +1
|
||||
nop -124
|
||||
jmp +163
|
||||
acc +37
|
||||
acc -12
|
||||
jmp +331
|
||||
acc -12
|
||||
acc +1
|
||||
jmp +232
|
||||
jmp -233
|
||||
jmp -72
|
||||
acc +28
|
||||
jmp +169
|
||||
acc +43
|
||||
acc +18
|
||||
nop +108
|
||||
jmp -184
|
||||
acc -4
|
||||
acc -10
|
||||
nop +317
|
||||
acc +48
|
||||
jmp +173
|
||||
nop +45
|
||||
jmp -73
|
||||
acc +35
|
||||
jmp +198
|
||||
acc -15
|
||||
acc +46
|
||||
acc +31
|
||||
jmp +41
|
||||
nop +169
|
||||
jmp +1
|
||||
nop -92
|
||||
nop -271
|
||||
jmp -113
|
||||
jmp +1
|
||||
nop -42
|
||||
jmp +42
|
||||
nop -283
|
||||
acc +22
|
||||
nop +200
|
||||
jmp -17
|
||||
jmp +1
|
||||
acc +49
|
||||
nop +35
|
||||
nop -185
|
||||
jmp +298
|
||||
acc +1
|
||||
jmp +1
|
||||
nop +301
|
||||
acc +19
|
||||
jmp -34
|
||||
jmp +163
|
||||
jmp +1
|
||||
acc +49
|
||||
jmp -115
|
||||
jmp -62
|
||||
acc +8
|
||||
acc +5
|
||||
acc -6
|
||||
jmp -146
|
||||
acc -4
|
||||
nop -202
|
||||
acc +47
|
||||
jmp -114
|
||||
acc +8
|
||||
jmp +57
|
||||
acc +37
|
||||
jmp +61
|
||||
jmp +267
|
||||
acc +2
|
||||
acc +28
|
||||
nop -20
|
||||
jmp -186
|
||||
acc +24
|
||||
nop +269
|
||||
acc +48
|
||||
acc +45
|
||||
jmp -22
|
||||
acc +11
|
||||
acc +36
|
||||
jmp -267
|
||||
acc +7
|
||||
nop -45
|
||||
nop -231
|
||||
jmp +32
|
||||
nop +220
|
||||
acc +19
|
||||
jmp -250
|
||||
acc +33
|
||||
jmp -169
|
||||
acc +45
|
||||
acc -13
|
||||
acc +0
|
||||
acc +44
|
||||
jmp +6
|
||||
acc +42
|
||||
jmp +84
|
||||
acc +48
|
||||
jmp -332
|
||||
jmp +213
|
||||
acc -16
|
||||
acc +31
|
||||
acc +17
|
||||
acc +3
|
||||
jmp -75
|
||||
jmp +1
|
||||
acc +11
|
||||
acc +4
|
||||
jmp -271
|
||||
acc -12
|
||||
nop +97
|
||||
nop +11
|
||||
jmp -43
|
||||
acc +30
|
||||
jmp +1
|
||||
jmp +49
|
||||
jmp -379
|
||||
nop -51
|
||||
acc +0
|
||||
acc -8
|
||||
nop -191
|
||||
jmp -346
|
||||
jmp -255
|
||||
acc +2
|
||||
acc +21
|
||||
acc -16
|
||||
nop +217
|
||||
jmp -30
|
||||
acc +31
|
||||
jmp -270
|
||||
jmp -324
|
||||
jmp +130
|
||||
acc +49
|
||||
nop +179
|
||||
jmp -37
|
||||
acc +11
|
||||
acc +15
|
||||
acc +29
|
||||
acc +17
|
||||
jmp -237
|
||||
acc +47
|
||||
acc -13
|
||||
acc +6
|
||||
jmp +169
|
||||
nop +54
|
||||
acc -12
|
||||
jmp -233
|
||||
nop +33
|
||||
acc +17
|
||||
acc +14
|
||||
acc +21
|
||||
jmp -275
|
||||
acc -8
|
||||
acc +1
|
||||
nop +229
|
||||
jmp +1
|
||||
jmp +119
|
||||
jmp -193
|
||||
nop +217
|
||||
jmp +95
|
||||
acc -2
|
||||
acc +1
|
||||
acc +41
|
||||
jmp -332
|
||||
acc +44
|
||||
nop -343
|
||||
acc +23
|
||||
jmp -165
|
||||
acc +7
|
||||
acc -12
|
||||
nop -339
|
||||
jmp +9
|
||||
nop -390
|
||||
acc -17
|
||||
acc +43
|
||||
jmp -138
|
||||
nop -247
|
||||
acc +42
|
||||
acc +0
|
||||
jmp +170
|
||||
acc +48
|
||||
jmp -139
|
||||
acc +6
|
||||
acc +13
|
||||
acc +35
|
||||
jmp -85
|
||||
nop -117
|
||||
jmp -307
|
||||
acc +25
|
||||
acc -10
|
||||
acc -14
|
||||
acc +0
|
||||
jmp -355
|
||||
jmp +102
|
||||
acc -8
|
||||
acc +47
|
||||
acc +36
|
||||
jmp +42
|
||||
acc +33
|
||||
acc +17
|
||||
acc +46
|
||||
jmp -331
|
||||
jmp +1
|
||||
acc -11
|
||||
jmp +1
|
||||
acc +27
|
||||
jmp +147
|
||||
acc -14
|
||||
nop -28
|
||||
acc +32
|
||||
jmp -482
|
||||
acc +11
|
||||
nop -390
|
||||
jmp -485
|
||||
acc -12
|
||||
acc +37
|
||||
acc +33
|
||||
acc +28
|
||||
jmp -32
|
||||
acc +42
|
||||
acc -11
|
||||
jmp -460
|
||||
acc +36
|
||||
acc +6
|
||||
acc +39
|
||||
jmp +80
|
||||
nop +123
|
||||
acc -13
|
||||
jmp -97
|
||||
acc +25
|
||||
acc +46
|
||||
acc +13
|
||||
nop -450
|
||||
jmp +84
|
||||
acc +3
|
||||
nop -260
|
||||
jmp +1
|
||||
acc +22
|
||||
jmp -510
|
||||
acc -4
|
||||
acc +17
|
||||
acc -19
|
||||
jmp -420
|
||||
acc -14
|
||||
acc +26
|
||||
acc +29
|
||||
acc +17
|
||||
jmp -458
|
||||
acc -10
|
||||
acc +23
|
||||
nop -2
|
||||
jmp -196
|
||||
acc -5
|
||||
jmp -416
|
||||
acc +49
|
||||
jmp -165
|
||||
acc +4
|
||||
acc +7
|
||||
acc +20
|
||||
nop -217
|
||||
jmp +103
|
||||
jmp +5
|
||||
acc -1
|
||||
acc +2
|
||||
jmp +1
|
||||
jmp +84
|
||||
acc -14
|
||||
jmp -518
|
||||
jmp +1
|
||||
acc +30
|
||||
acc +21
|
||||
jmp -202
|
||||
nop -18
|
||||
jmp -344
|
||||
jmp -88
|
||||
nop -472
|
||||
acc -5
|
||||
acc +13
|
||||
jmp -295
|
||||
nop -315
|
||||
acc +41
|
||||
nop -317
|
||||
jmp -299
|
||||
nop +105
|
||||
jmp -86
|
||||
acc +7
|
||||
jmp -226
|
||||
nop -277
|
||||
acc +21
|
||||
acc +13
|
||||
acc +47
|
||||
jmp -283
|
||||
acc -11
|
||||
acc -1
|
||||
jmp -408
|
||||
acc +47
|
||||
nop -553
|
||||
acc +37
|
||||
acc -11
|
||||
jmp -468
|
||||
acc +43
|
||||
nop -299
|
||||
acc +40
|
||||
acc +2
|
||||
jmp -275
|
||||
acc +24
|
||||
acc -14
|
||||
acc +13
|
||||
acc +36
|
||||
jmp -249
|
||||
acc +35
|
||||
jmp -45
|
||||
acc +47
|
||||
acc +31
|
||||
acc -19
|
||||
jmp -151
|
||||
jmp -33
|
||||
acc +6
|
||||
jmp -160
|
||||
jmp -553
|
||||
acc +25
|
||||
jmp +1
|
||||
nop -267
|
||||
jmp -430
|
||||
acc +23
|
||||
nop +63
|
||||
acc +37
|
||||
jmp -434
|
||||
nop -579
|
||||
jmp +11
|
||||
acc +25
|
||||
acc -17
|
||||
acc +22
|
||||
acc +27
|
||||
jmp +15
|
||||
jmp -546
|
||||
acc -4
|
||||
acc +41
|
||||
acc +0
|
||||
jmp -261
|
||||
acc +20
|
||||
jmp -404
|
||||
jmp -408
|
||||
acc +26
|
||||
jmp -464
|
||||
acc +34
|
||||
nop -80
|
||||
acc -12
|
||||
jmp -43
|
||||
jmp -410
|
||||
acc -13
|
||||
acc -3
|
||||
jmp -310
|
||||
nop -433
|
||||
acc -7
|
||||
acc -11
|
||||
acc +9
|
||||
jmp -29
|
||||
nop -564
|
||||
acc -5
|
||||
acc -16
|
||||
acc +36
|
||||
jmp -587
|
||||
jmp -115
|
||||
acc +24
|
||||
acc +35
|
||||
nop -638
|
||||
jmp -573
|
||||
acc +31
|
||||
acc +14
|
||||
jmp -609
|
||||
acc +25
|
||||
acc -10
|
||||
acc +18
|
||||
jmp -308
|
||||
acc +25
|
||||
acc +33
|
||||
acc +21
|
||||
acc -12
|
||||
jmp -172
|
||||
nop -37
|
||||
acc +12
|
||||
jmp -316
|
||||
acc +41
|
||||
acc +14
|
||||
jmp -415
|
||||
acc +40
|
||||
jmp -112
|
||||
jmp -613
|
||||
acc +26
|
||||
nop -151
|
||||
jmp -471
|
||||
acc +50
|
||||
acc +16
|
||||
nop -119
|
||||
acc +46
|
||||
jmp +1
|
62
2020/d08/ex2/ex2.py
Executable file
62
2020/d08/ex2/ex2.py
Executable file
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from typing import List, Tuple
|
||||
|
||||
|
||||
def run(code: List[Tuple[str, int]]) -> Tuple[int, bool]:
|
||||
accumulator = 0
|
||||
rip = 0
|
||||
|
||||
def acc(val: int) -> None:
|
||||
nonlocal accumulator
|
||||
nonlocal rip
|
||||
accumulator += val
|
||||
rip += 1
|
||||
|
||||
def nop(val: int) -> None:
|
||||
nonlocal rip
|
||||
rip += 1
|
||||
|
||||
def jmp(val: int) -> None:
|
||||
nonlocal rip
|
||||
rip += val
|
||||
|
||||
instrs = {
|
||||
"acc": acc,
|
||||
"jmp": jmp,
|
||||
"nop": nop,
|
||||
}
|
||||
seen = set()
|
||||
|
||||
while rip not in seen and rip < len(code):
|
||||
seen |= {rip}
|
||||
func = instrs[code[rip][0]]
|
||||
func(code[rip][1])
|
||||
|
||||
return accumulator, rip == len(code)
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
code = [(line[:3], int(line[3:])) for line in raw]
|
||||
lut = {"jmp": "nop", "nop": "jmp"}
|
||||
for i in range(len(code)):
|
||||
if code[i][0] not in lut:
|
||||
continue
|
||||
new_code = deepcopy(code)
|
||||
new_code[i] = lut[new_code[i][0]], new_code[i][1]
|
||||
val, halted = run(new_code)
|
||||
if halted:
|
||||
return val
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
675
2020/d08/ex2/input
Normal file
675
2020/d08/ex2/input
Normal file
|
@ -0,0 +1,675 @@
|
|||
acc -8
|
||||
jmp +5
|
||||
acc +0
|
||||
acc +44
|
||||
acc +42
|
||||
jmp +324
|
||||
acc -17
|
||||
jmp +1
|
||||
acc -17
|
||||
jmp +51
|
||||
acc -13
|
||||
acc +4
|
||||
jmp +1
|
||||
nop +608
|
||||
jmp +274
|
||||
acc -17
|
||||
jmp +169
|
||||
acc +28
|
||||
nop +508
|
||||
jmp +1
|
||||
jmp +570
|
||||
acc +22
|
||||
acc -14
|
||||
jmp +377
|
||||
acc -13
|
||||
acc +27
|
||||
jmp +474
|
||||
acc -5
|
||||
jmp +1
|
||||
acc +12
|
||||
jmp +37
|
||||
jmp +184
|
||||
acc +36
|
||||
acc +32
|
||||
acc -8
|
||||
jmp +465
|
||||
acc -13
|
||||
acc +18
|
||||
jmp +169
|
||||
acc +20
|
||||
acc +26
|
||||
acc +23
|
||||
jmp +333
|
||||
jmp +584
|
||||
acc +9
|
||||
acc +28
|
||||
acc +28
|
||||
nop +571
|
||||
jmp +143
|
||||
acc +39
|
||||
acc +39
|
||||
acc -16
|
||||
jmp +361
|
||||
acc +48
|
||||
acc +3
|
||||
acc +15
|
||||
nop +4
|
||||
jmp +504
|
||||
acc +6
|
||||
jmp +285
|
||||
acc +26
|
||||
acc +33
|
||||
jmp +1
|
||||
acc +36
|
||||
jmp +577
|
||||
acc +36
|
||||
jmp +6
|
||||
nop +498
|
||||
acc +42
|
||||
jmp +496
|
||||
acc +10
|
||||
jmp +74
|
||||
acc +17
|
||||
acc +16
|
||||
acc +30
|
||||
jmp +254
|
||||
acc -3
|
||||
acc +16
|
||||
acc -2
|
||||
nop +106
|
||||
jmp +541
|
||||
acc -15
|
||||
jmp +579
|
||||
jmp +165
|
||||
acc +22
|
||||
acc -6
|
||||
acc +29
|
||||
acc -19
|
||||
jmp +342
|
||||
acc -19
|
||||
jmp +340
|
||||
acc +13
|
||||
acc +25
|
||||
acc +29
|
||||
jmp +269
|
||||
acc -14
|
||||
acc +27
|
||||
acc +41
|
||||
acc +49
|
||||
jmp +181
|
||||
nop +350
|
||||
jmp +1
|
||||
nop +437
|
||||
acc +34
|
||||
jmp +494
|
||||
acc +19
|
||||
acc +2
|
||||
acc +44
|
||||
jmp +558
|
||||
acc +10
|
||||
jmp +44
|
||||
nop +4
|
||||
nop -80
|
||||
nop +540
|
||||
jmp +16
|
||||
acc +28
|
||||
jmp +14
|
||||
acc +13
|
||||
nop +399
|
||||
acc +29
|
||||
nop -60
|
||||
jmp -6
|
||||
acc +41
|
||||
acc +30
|
||||
jmp +232
|
||||
acc +28
|
||||
nop +495
|
||||
acc +15
|
||||
acc +48
|
||||
jmp +157
|
||||
nop +483
|
||||
jmp -59
|
||||
acc +5
|
||||
acc +30
|
||||
acc +30
|
||||
acc +2
|
||||
jmp +349
|
||||
acc +11
|
||||
acc +27
|
||||
acc +1
|
||||
jmp +367
|
||||
acc +8
|
||||
acc +45
|
||||
acc +11
|
||||
jmp +171
|
||||
jmp -113
|
||||
acc +48
|
||||
jmp -38
|
||||
acc +12
|
||||
jmp +145
|
||||
acc +8
|
||||
nop +29
|
||||
nop +319
|
||||
jmp +154
|
||||
nop +166
|
||||
jmp +395
|
||||
nop +15
|
||||
jmp +237
|
||||
acc +22
|
||||
acc +3
|
||||
acc +42
|
||||
acc +1
|
||||
jmp +288
|
||||
jmp -63
|
||||
nop +489
|
||||
acc +33
|
||||
jmp +247
|
||||
jmp +1
|
||||
acc -8
|
||||
acc +9
|
||||
jmp +413
|
||||
acc -17
|
||||
acc +3
|
||||
acc +3
|
||||
jmp +432
|
||||
nop -17
|
||||
acc +36
|
||||
nop +198
|
||||
acc +45
|
||||
jmp +109
|
||||
nop +242
|
||||
acc +40
|
||||
acc +11
|
||||
jmp +448
|
||||
jmp +437
|
||||
acc +3
|
||||
acc +49
|
||||
acc +27
|
||||
jmp +221
|
||||
nop +158
|
||||
jmp +143
|
||||
acc +50
|
||||
jmp -70
|
||||
acc +46
|
||||
acc +8
|
||||
acc +35
|
||||
acc -3
|
||||
jmp +104
|
||||
acc +11
|
||||
acc +0
|
||||
jmp +34
|
||||
nop +132
|
||||
jmp +425
|
||||
jmp +219
|
||||
acc -12
|
||||
acc +48
|
||||
jmp +21
|
||||
jmp +434
|
||||
acc +30
|
||||
acc +1
|
||||
acc +40
|
||||
jmp +435
|
||||
jmp +132
|
||||
acc +40
|
||||
jmp +236
|
||||
jmp +179
|
||||
jmp -149
|
||||
acc +25
|
||||
acc +40
|
||||
acc -9
|
||||
acc +49
|
||||
jmp +445
|
||||
nop +399
|
||||
acc -14
|
||||
nop +374
|
||||
acc +0
|
||||
jmp +152
|
||||
acc +39
|
||||
nop +322
|
||||
acc +49
|
||||
nop +117
|
||||
jmp -19
|
||||
acc +24
|
||||
jmp +385
|
||||
acc +17
|
||||
acc +39
|
||||
acc +44
|
||||
acc -8
|
||||
jmp -58
|
||||
acc -18
|
||||
nop -76
|
||||
jmp +66
|
||||
acc +14
|
||||
jmp +427
|
||||
acc +11
|
||||
acc +47
|
||||
acc +9
|
||||
jmp +1
|
||||
acc +42
|
||||
jmp -7
|
||||
acc -16
|
||||
acc -13
|
||||
jmp +409
|
||||
acc +1
|
||||
acc +35
|
||||
acc +34
|
||||
jmp +371
|
||||
acc +24
|
||||
acc +46
|
||||
acc -4
|
||||
jmp +367
|
||||
acc +19
|
||||
acc +27
|
||||
acc -8
|
||||
acc +41
|
||||
jmp -184
|
||||
nop -185
|
||||
acc +23
|
||||
acc -8
|
||||
acc +35
|
||||
jmp -9
|
||||
acc -7
|
||||
nop -101
|
||||
nop +121
|
||||
acc +37
|
||||
jmp -72
|
||||
acc +24
|
||||
jmp +1
|
||||
nop -124
|
||||
jmp +163
|
||||
acc +37
|
||||
acc -12
|
||||
jmp +331
|
||||
acc -12
|
||||
acc +1
|
||||
jmp +232
|
||||
jmp -233
|
||||
jmp -72
|
||||
acc +28
|
||||
jmp +169
|
||||
acc +43
|
||||
acc +18
|
||||
nop +108
|
||||
jmp -184
|
||||
acc -4
|
||||
acc -10
|
||||
nop +317
|
||||
acc +48
|
||||
jmp +173
|
||||
nop +45
|
||||
jmp -73
|
||||
acc +35
|
||||
jmp +198
|
||||
acc -15
|
||||
acc +46
|
||||
acc +31
|
||||
jmp +41
|
||||
nop +169
|
||||
jmp +1
|
||||
nop -92
|
||||
nop -271
|
||||
jmp -113
|
||||
jmp +1
|
||||
nop -42
|
||||
jmp +42
|
||||
nop -283
|
||||
acc +22
|
||||
nop +200
|
||||
jmp -17
|
||||
jmp +1
|
||||
acc +49
|
||||
nop +35
|
||||
nop -185
|
||||
jmp +298
|
||||
acc +1
|
||||
jmp +1
|
||||
nop +301
|
||||
acc +19
|
||||
jmp -34
|
||||
jmp +163
|
||||
jmp +1
|
||||
acc +49
|
||||
jmp -115
|
||||
jmp -62
|
||||
acc +8
|
||||
acc +5
|
||||
acc -6
|
||||
jmp -146
|
||||
acc -4
|
||||
nop -202
|
||||
acc +47
|
||||
jmp -114
|
||||
acc +8
|
||||
jmp +57
|
||||
acc +37
|
||||
jmp +61
|
||||
jmp +267
|
||||
acc +2
|
||||
acc +28
|
||||
nop -20
|
||||
jmp -186
|
||||
acc +24
|
||||
nop +269
|
||||
acc +48
|
||||
acc +45
|
||||
jmp -22
|
||||
acc +11
|
||||
acc +36
|
||||
jmp -267
|
||||
acc +7
|
||||
nop -45
|
||||
nop -231
|
||||
jmp +32
|
||||
nop +220
|
||||
acc +19
|
||||
jmp -250
|
||||
acc +33
|
||||
jmp -169
|
||||
acc +45
|
||||
acc -13
|
||||
acc +0
|
||||
acc +44
|
||||
jmp +6
|
||||
acc +42
|
||||
jmp +84
|
||||
acc +48
|
||||
jmp -332
|
||||
jmp +213
|
||||
acc -16
|
||||
acc +31
|
||||
acc +17
|
||||
acc +3
|
||||
jmp -75
|
||||
jmp +1
|
||||
acc +11
|
||||
acc +4
|
||||
jmp -271
|
||||
acc -12
|
||||
nop +97
|
||||
nop +11
|
||||
jmp -43
|
||||
acc +30
|
||||
jmp +1
|
||||
jmp +49
|
||||
jmp -379
|
||||
nop -51
|
||||
acc +0
|
||||
acc -8
|
||||
nop -191
|
||||
jmp -346
|
||||
jmp -255
|
||||
acc +2
|
||||
acc +21
|
||||
acc -16
|
||||
nop +217
|
||||
jmp -30
|
||||
acc +31
|
||||
jmp -270
|
||||
jmp -324
|
||||
jmp +130
|
||||
acc +49
|
||||
nop +179
|
||||
jmp -37
|
||||
acc +11
|
||||
acc +15
|
||||
acc +29
|
||||
acc +17
|
||||
jmp -237
|
||||
acc +47
|
||||
acc -13
|
||||
acc +6
|
||||
jmp +169
|
||||
nop +54
|
||||
acc -12
|
||||
jmp -233
|
||||
nop +33
|
||||
acc +17
|
||||
acc +14
|
||||
acc +21
|
||||
jmp -275
|
||||
acc -8
|
||||
acc +1
|
||||
nop +229
|
||||
jmp +1
|
||||
jmp +119
|
||||
jmp -193
|
||||
nop +217
|
||||
jmp +95
|
||||
acc -2
|
||||
acc +1
|
||||
acc +41
|
||||
jmp -332
|
||||
acc +44
|
||||
nop -343
|
||||
acc +23
|
||||
jmp -165
|
||||
acc +7
|
||||
acc -12
|
||||
nop -339
|
||||
jmp +9
|
||||
nop -390
|
||||
acc -17
|
||||
acc +43
|
||||
jmp -138
|
||||
nop -247
|
||||
acc +42
|
||||
acc +0
|
||||
jmp +170
|
||||
acc +48
|
||||
jmp -139
|
||||
acc +6
|
||||
acc +13
|
||||
acc +35
|
||||
jmp -85
|
||||
nop -117
|
||||
jmp -307
|
||||
acc +25
|
||||
acc -10
|
||||
acc -14
|
||||
acc +0
|
||||
jmp -355
|
||||
jmp +102
|
||||
acc -8
|
||||
acc +47
|
||||
acc +36
|
||||
jmp +42
|
||||
acc +33
|
||||
acc +17
|
||||
acc +46
|
||||
jmp -331
|
||||
jmp +1
|
||||
acc -11
|
||||
jmp +1
|
||||
acc +27
|
||||
jmp +147
|
||||
acc -14
|
||||
nop -28
|
||||
acc +32
|
||||
jmp -482
|
||||
acc +11
|
||||
nop -390
|
||||
jmp -485
|
||||
acc -12
|
||||
acc +37
|
||||
acc +33
|
||||
acc +28
|
||||
jmp -32
|
||||
acc +42
|
||||
acc -11
|
||||
jmp -460
|
||||
acc +36
|
||||
acc +6
|
||||
acc +39
|
||||
jmp +80
|
||||
nop +123
|
||||
acc -13
|
||||
jmp -97
|
||||
acc +25
|
||||
acc +46
|
||||
acc +13
|
||||
nop -450
|
||||
jmp +84
|
||||
acc +3
|
||||
nop -260
|
||||
jmp +1
|
||||
acc +22
|
||||
jmp -510
|
||||
acc -4
|
||||
acc +17
|
||||
acc -19
|
||||
jmp -420
|
||||
acc -14
|
||||
acc +26
|
||||
acc +29
|
||||
acc +17
|
||||
jmp -458
|
||||
acc -10
|
||||
acc +23
|
||||
nop -2
|
||||
jmp -196
|
||||
acc -5
|
||||
jmp -416
|
||||
acc +49
|
||||
jmp -165
|
||||
acc +4
|
||||
acc +7
|
||||
acc +20
|
||||
nop -217
|
||||
jmp +103
|
||||
jmp +5
|
||||
acc -1
|
||||
acc +2
|
||||
jmp +1
|
||||
jmp +84
|
||||
acc -14
|
||||
jmp -518
|
||||
jmp +1
|
||||
acc +30
|
||||
acc +21
|
||||
jmp -202
|
||||
nop -18
|
||||
jmp -344
|
||||
jmp -88
|
||||
nop -472
|
||||
acc -5
|
||||
acc +13
|
||||
jmp -295
|
||||
nop -315
|
||||
acc +41
|
||||
nop -317
|
||||
jmp -299
|
||||
nop +105
|
||||
jmp -86
|
||||
acc +7
|
||||
jmp -226
|
||||
nop -277
|
||||
acc +21
|
||||
acc +13
|
||||
acc +47
|
||||
jmp -283
|
||||
acc -11
|
||||
acc -1
|
||||
jmp -408
|
||||
acc +47
|
||||
nop -553
|
||||
acc +37
|
||||
acc -11
|
||||
jmp -468
|
||||
acc +43
|
||||
nop -299
|
||||
acc +40
|
||||
acc +2
|
||||
jmp -275
|
||||
acc +24
|
||||
acc -14
|
||||
acc +13
|
||||
acc +36
|
||||
jmp -249
|
||||
acc +35
|
||||
jmp -45
|
||||
acc +47
|
||||
acc +31
|
||||
acc -19
|
||||
jmp -151
|
||||
jmp -33
|
||||
acc +6
|
||||
jmp -160
|
||||
jmp -553
|
||||
acc +25
|
||||
jmp +1
|
||||
nop -267
|
||||
jmp -430
|
||||
acc +23
|
||||
nop +63
|
||||
acc +37
|
||||
jmp -434
|
||||
nop -579
|
||||
jmp +11
|
||||
acc +25
|
||||
acc -17
|
||||
acc +22
|
||||
acc +27
|
||||
jmp +15
|
||||
jmp -546
|
||||
acc -4
|
||||
acc +41
|
||||
acc +0
|
||||
jmp -261
|
||||
acc +20
|
||||
jmp -404
|
||||
jmp -408
|
||||
acc +26
|
||||
jmp -464
|
||||
acc +34
|
||||
nop -80
|
||||
acc -12
|
||||
jmp -43
|
||||
jmp -410
|
||||
acc -13
|
||||
acc -3
|
||||
jmp -310
|
||||
nop -433
|
||||
acc -7
|
||||
acc -11
|
||||
acc +9
|
||||
jmp -29
|
||||
nop -564
|
||||
acc -5
|
||||
acc -16
|
||||
acc +36
|
||||
jmp -587
|
||||
jmp -115
|
||||
acc +24
|
||||
acc +35
|
||||
nop -638
|
||||
jmp -573
|
||||
acc +31
|
||||
acc +14
|
||||
jmp -609
|
||||
acc +25
|
||||
acc -10
|
||||
acc +18
|
||||
jmp -308
|
||||
acc +25
|
||||
acc +33
|
||||
acc +21
|
||||
acc -12
|
||||
jmp -172
|
||||
nop -37
|
||||
acc +12
|
||||
jmp -316
|
||||
acc +41
|
||||
acc +14
|
||||
jmp -415
|
||||
acc +40
|
||||
jmp -112
|
||||
jmp -613
|
||||
acc +26
|
||||
nop -151
|
||||
jmp -471
|
||||
acc +50
|
||||
acc +16
|
||||
nop -119
|
||||
acc +46
|
||||
jmp +1
|
32
2020/d09/ex1/ex1.py
Executable file
32
2020/d09/ex1/ex1.py
Executable file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import itertools
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def find_invalid(nums: List[int]) -> int:
|
||||
for i in range(25, len(nums)):
|
||||
num = nums[i]
|
||||
found = False
|
||||
for lhs, rhs in itertools.combinations(nums[i - 25 : i], 2):
|
||||
if lhs + rhs == num:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
return num
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
return find_invalid([int(line) for line in raw])
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
1000
2020/d09/ex1/input
Normal file
1000
2020/d09/ex1/input
Normal file
File diff suppressed because it is too large
Load diff
42
2020/d09/ex2/ex2.py
Executable file
42
2020/d09/ex2/ex2.py
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import itertools
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
|
||||
def find_invalid(nums: List[int]) -> int:
|
||||
for i in range(25, len(nums)):
|
||||
num = nums[i]
|
||||
found = False
|
||||
for lhs, rhs in itertools.combinations(nums[i - 25 : i], 2):
|
||||
if lhs + rhs == num:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
return num
|
||||
assert False # Sanity check
|
||||
|
||||
|
||||
def find_weakness(nums: List[int], invalid: int) -> int:
|
||||
for i in range(len(nums) - 2):
|
||||
for j in range(i + 2, len(nums)):
|
||||
if sum(nums[i:j]) == invalid:
|
||||
return min(nums[i:j]) + max(nums[i:j])
|
||||
assert False # Sanity check((
|
||||
|
||||
|
||||
def solve(raw: List[str]) -> int:
|
||||
nums = [int(line) for line in raw]
|
||||
invalid = find_invalid(nums)
|
||||
return find_weakness(nums, invalid)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
input = [line.strip() for line in sys.stdin.readlines()]
|
||||
print(solve(input))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue