Compare commits
480 commits
d62a8befcd
...
eb9c25af5a
Author | SHA1 | Date | |
---|---|---|---|
Bruno BELANYI | eb9c25af5a | ||
Bruno BELANYI | 120a42f1b0 | ||
Bruno BELANYI | 8618c81b2f | ||
Bruno BELANYI | 67ef6227dc | ||
Bruno BELANYI | c1ef85e59b | ||
Bruno BELANYI | b80a75858d | ||
Bruno BELANYI | 061af7c1d1 | ||
Bruno BELANYI | b004a8fae7 | ||
Bruno BELANYI | 0c23bd9eee | ||
Bruno BELANYI | 03d3cf2210 | ||
Bruno BELANYI | eca3f7bd59 | ||
Bruno BELANYI | 4047f428e1 | ||
Bruno BELANYI | a42da85f1f | ||
Bruno BELANYI | 1204116d6f | ||
Bruno BELANYI | 7017b91d91 | ||
Bruno BELANYI | 8b58cedff2 | ||
Bruno BELANYI | a734b0d292 | ||
Bruno BELANYI | a69212b0ee | ||
Bruno BELANYI | 6fbc38b565 | ||
Bruno BELANYI | 0f949820e1 | ||
Bruno BELANYI | 5e8eb3d7f2 | ||
Bruno BELANYI | 4c11e798bd | ||
Bruno BELANYI | 3837f06467 | ||
Bruno BELANYI | 1a0a231bd7 | ||
Bruno BELANYI | 781e51b3a0 | ||
Bruno BELANYI | c8e0e82c12 | ||
Bruno BELANYI | 70cbe0d6f2 | ||
Bruno BELANYI | 06f3c8f169 | ||
Bruno BELANYI | a18f882c1a | ||
Bruno BELANYI | e795c9cee8 | ||
Bruno BELANYI | 8f8e37b42d | ||
Bruno BELANYI | 57f28d6411 | ||
Bruno BELANYI | 7e2489f5f9 | ||
Bruno BELANYI | f9c1e152c3 | ||
Bruno BELANYI | bb2bee9c6e | ||
Bruno BELANYI | 122b81ed15 | ||
Bruno BELANYI | d5694f2bd3 | ||
Bruno BELANYI | 5215e97077 | ||
Bruno BELANYI | 1be0b68503 | ||
Bruno BELANYI | 8f6fc416fb | ||
Bruno BELANYI | 61e32bde3d | ||
Bruno BELANYI | 97b4a3c7b3 | ||
Bruno BELANYI | f62c625850 | ||
Bruno BELANYI | d15f807bd1 | ||
Bruno BELANYI | 90ebcbebd8 | ||
Bruno BELANYI | 38dc59b16d | ||
Bruno BELANYI | 1e7d41b861 | ||
Bruno BELANYI | 572d03ae1d | ||
Bruno BELANYI | f8b27ddff8 | ||
Bruno BELANYI | 3f2c16d8a8 | ||
Bruno BELANYI | 307381a434 | ||
Bruno BELANYI | d8f472ec43 | ||
Bruno BELANYI | 21986b1148 | ||
Bruno BELANYI | 9f7c2a6448 | ||
Bruno BELANYI | bd396f32d7 | ||
Bruno BELANYI | d2e2d79d71 | ||
Bruno BELANYI | 15b8b5aaeb | ||
Bruno BELANYI | 70fdb4e606 | ||
Bruno BELANYI | f8c387c5a6 | ||
Bruno BELANYI | f31434d9c6 | ||
Bruno BELANYI | abf3b5e66c | ||
Bruno BELANYI | c46be2b190 | ||
Bruno BELANYI | 933fc2da0b | ||
Bruno BELANYI | 9bbb769a9b | ||
Bruno BELANYI | 7cf50212b4 | ||
Bruno BELANYI | 8692f6c401 | ||
Bruno BELANYI | a4e14d1245 | ||
Bruno BELANYI | 8e5433a642 | ||
Bruno BELANYI | f4e3d977c2 | ||
Bruno BELANYI | d5842f92be | ||
Bruno BELANYI | 6f31630af7 | ||
Bruno BELANYI | a310f24d8e | ||
Bruno BELANYI | 348ce5b369 | ||
Bruno BELANYI | 34e16218b8 | ||
Bruno BELANYI | dcce8c1eec | ||
Bruno BELANYI | ad9ddd69e5 | ||
Bruno BELANYI | 4f5138adb8 | ||
Bruno BELANYI | 73ee756062 | ||
Bruno BELANYI | 245a07bbdd | ||
Bruno BELANYI | 13437c7bd6 | ||
Bruno BELANYI | dda2adcb6e | ||
Bruno BELANYI | c329b034a6 | ||
Bruno BELANYI | bacc167481 | ||
Bruno BELANYI | 3afecbf47e | ||
Bruno BELANYI | 0a65ff5789 | ||
Bruno BELANYI | 7a7ba0b454 | ||
Bruno BELANYI | d45398d1e9 | ||
Bruno BELANYI | 10faba0e78 | ||
Bruno BELANYI | 3e34da7b31 | ||
Bruno BELANYI | 831b3606b4 | ||
Bruno BELANYI | f659487d80 | ||
Bruno BELANYI | bdd585fec7 | ||
Bruno BELANYI | 3d6780146b | ||
Bruno BELANYI | d52a3a1e59 | ||
Bruno BELANYI | 2923fd5dcc | ||
Bruno BELANYI | 1193810e57 | ||
Bruno BELANYI | 8ab447e917 | ||
Bruno BELANYI | 65c087a68b | ||
Bruno BELANYI | 078dfd94e7 | ||
Bruno BELANYI | 52ecb598bc | ||
Bruno BELANYI | 8df335ba05 | ||
Bruno BELANYI | 447467ef6e | ||
Bruno BELANYI | 1039b4c0ac | ||
Bruno BELANYI | a53f99d841 | ||
Bruno BELANYI | 37d878da27 | ||
Bruno BELANYI | 53c344b223 | ||
Bruno BELANYI | 5bbf42ef1b | ||
Bruno BELANYI | 92cabbda8f | ||
Bruno BELANYI | addda451ef | ||
Bruno BELANYI | d1194e8c5f | ||
Bruno BELANYI | 7759412af3 | ||
Bruno BELANYI | 4211451deb | ||
Bruno BELANYI | 1562f97efc | ||
Bruno BELANYI | 1c57181989 | ||
Bruno BELANYI | e8cbc17839 | ||
Bruno BELANYI | 2ce03834e4 | ||
Bruno BELANYI | f3af387265 | ||
Bruno BELANYI | 43b78a23c5 | ||
Bruno BELANYI | a4d483e01c | ||
Bruno BELANYI | eeaf6956e5 | ||
Bruno BELANYI | b819e62da4 | ||
Bruno BELANYI | 992cbd34f4 | ||
Bruno BELANYI | c7bb07d13a | ||
Bruno BELANYI | 810101024f | ||
Bruno BELANYI | e1dc373b69 | ||
Bruno BELANYI | 3e5502e3d8 | ||
Bruno BELANYI | 5d6ef372de | ||
Bruno BELANYI | 8881d00b55 | ||
Bruno BELANYI | 31fbfaaead | ||
Bruno BELANYI | 1392358ada | ||
Bruno BELANYI | 076126ec41 | ||
Bruno BELANYI | 64ae3b2a59 | ||
Bruno BELANYI | 69055425f0 | ||
Bruno BELANYI | 8e8e26f2d6 | ||
Bruno BELANYI | 1743b72d82 | ||
Bruno BELANYI | a57da6fcfe | ||
Bruno BELANYI | ef8b11d2d3 | ||
Bruno BELANYI | e18d783d39 | ||
Bruno BELANYI | e509e6fd4b | ||
Bruno BELANYI | ce88300254 | ||
Bruno BELANYI | fa883c71c0 | ||
Bruno BELANYI | 1cee160cad | ||
Bruno BELANYI | 7009315b66 | ||
Bruno BELANYI | 6355c9c84d | ||
Bruno BELANYI | 0587294ccf | ||
Bruno BELANYI | 14e8b539c6 | ||
Bruno BELANYI | 0f91c37d6d | ||
Bruno BELANYI | 1ce063154e | ||
Bruno BELANYI | da042bea7d | ||
Bruno BELANYI | a9c325ce14 | ||
Bruno BELANYI | e457aaed44 | ||
Bruno BELANYI | 2c486e5984 | ||
Bruno BELANYI | 7eb906cd17 | ||
Bruno BELANYI | e5f1d74b08 | ||
Bruno BELANYI | 73c97eb7ce | ||
Bruno BELANYI | 3d45fe8501 | ||
Bruno BELANYI | 98f58280fa | ||
Bruno BELANYI | 977dbcbd93 | ||
Bruno BELANYI | 644f29a79d | ||
Bruno BELANYI | 5f55835edf | ||
Bruno BELANYI | 300502a05f | ||
Bruno BELANYI | 93cac379e0 | ||
Bruno BELANYI | efb846e460 | ||
Bruno BELANYI | a03da090dc | ||
Bruno BELANYI | 19d6374476 | ||
Bruno BELANYI | 44dafef243 | ||
Bruno BELANYI | 5731ff8e82 | ||
Bruno BELANYI | 426deae1ce | ||
Bruno BELANYI | 63bbd74790 | ||
Bruno BELANYI | 20779b5e2e | ||
Bruno BELANYI | 912e8e6edb | ||
Bruno BELANYI | a505c9de49 | ||
Bruno BELANYI | 71280e082d | ||
Bruno BELANYI | f6fbf6d6e6 | ||
Bruno BELANYI | 8b63d66750 | ||
Bruno BELANYI | 637b7e64c2 | ||
Bruno BELANYI | a45e00083c | ||
Bruno BELANYI | a6f1d09f91 | ||
Bruno BELANYI | 02a0c87f74 | ||
Bruno BELANYI | 5270736a28 | ||
Bruno BELANYI | 761a37e8fe | ||
Bruno BELANYI | 0c2712d7db | ||
Bruno BELANYI | 20fcfe32b2 | ||
Bruno BELANYI | 6c4ead5e1b | ||
Bruno BELANYI | 65cb34a16a | ||
Bruno BELANYI | 5ad92f1585 | ||
Bruno BELANYI | fd66f79400 | ||
Bruno BELANYI | e2d1a5f74d | ||
Bruno BELANYI | cea94a22fb | ||
Bruno BELANYI | c2cfef5e30 | ||
Bruno BELANYI | 9b01dc5723 | ||
Bruno BELANYI | d43d8c0cf1 | ||
Bruno BELANYI | 32ccf155df | ||
Bruno BELANYI | 3030162e09 | ||
Bruno BELANYI | 035b00e5cf | ||
Bruno BELANYI | 96b6c799e7 | ||
Bruno BELANYI | 4c8667879d | ||
Bruno BELANYI | 787381537b | ||
Bruno BELANYI | ca0ff2f0b9 | ||
Bruno BELANYI | a710ad0217 | ||
Bruno BELANYI | a06d490eef | ||
Bruno BELANYI | 6f0ffd34db | ||
Bruno BELANYI | a064fe7199 | ||
Bruno BELANYI | 24610576bb | ||
Bruno BELANYI | 8c13d5954e | ||
Bruno BELANYI | 31c0f09981 | ||
Bruno BELANYI | 46864fc490 | ||
Bruno BELANYI | fcb74b375f | ||
Bruno BELANYI | 6a6552f6fc | ||
Bruno BELANYI | a6560adc6a | ||
Bruno BELANYI | 709ad10ae2 | ||
Bruno BELANYI | 5266bd7cd7 | ||
Bruno BELANYI | 068ce3366a | ||
Bruno BELANYI | a8b2046162 | ||
Bruno BELANYI | 84ee4c57f0 | ||
Bruno BELANYI | bf830af1ae | ||
Bruno BELANYI | d35e1d43d6 | ||
Bruno BELANYI | 289b1ce455 | ||
Bruno BELANYI | ac9f1f2d6d | ||
Bruno BELANYI | 04589c89b8 | ||
Bruno BELANYI | 05fdbcc303 | ||
Bruno BELANYI | 130e417c62 | ||
Bruno BELANYI | 61936793e3 | ||
Bruno BELANYI | f8d2551280 | ||
Bruno BELANYI | 9ab9b3bd08 | ||
Bruno BELANYI | 3152b281e2 | ||
Bruno BELANYI | d85baf2a6d | ||
Bruno BELANYI | 16e9f6eb9c | ||
Bruno BELANYI | ee48bb409a | ||
Bruno BELANYI | a791595c4e | ||
Bruno BELANYI | 65328ff90d | ||
Bruno BELANYI | 74e53e919c | ||
Bruno BELANYI | 820d358803 | ||
Bruno BELANYI | 98deed16ed | ||
Bruno BELANYI | 05a02c63fd | ||
Bruno BELANYI | f561c94209 | ||
Bruno BELANYI | 549a806bd6 | ||
Bruno BELANYI | 030f680090 | ||
Bruno BELANYI | 8bf78654a5 | ||
Bruno BELANYI | c0bf6fe213 | ||
Bruno BELANYI | 2be3cf4327 | ||
Bruno BELANYI | 38902d9a64 | ||
Bruno BELANYI | 87dd721d47 | ||
Bruno BELANYI | bbb6b33406 | ||
Bruno BELANYI | b8e0bc7db7 | ||
Bruno BELANYI | b41103b3a8 | ||
Bruno BELANYI | 44d90b4153 | ||
Bruno BELANYI | b42fd7e459 | ||
Bruno BELANYI | ae66ae03d6 | ||
Bruno BELANYI | bf5053d865 | ||
Bruno BELANYI | 643286ca25 | ||
Bruno BELANYI | cb03ef9b2b | ||
Bruno BELANYI | ee4c12e081 | ||
Bruno BELANYI | 68219cf710 | ||
Bruno BELANYI | 03565ed812 | ||
Bruno BELANYI | 420d4a8f7a | ||
Bruno BELANYI | a1520e437e | ||
Bruno BELANYI | 235f8cd29b | ||
Bruno BELANYI | b1f325432c | ||
Bruno BELANYI | 5f332cc4fa | ||
Bruno BELANYI | df66079060 | ||
Bruno BELANYI | 8794333d64 | ||
Bruno BELANYI | 4b19161d71 | ||
Bruno BELANYI | 6dbdba8a46 | ||
Bruno BELANYI | 64651f1be9 | ||
Bruno BELANYI | b2c5e732f5 | ||
Bruno BELANYI | 3feee209e3 | ||
Bruno BELANYI | 85fd510ec9 | ||
Bruno BELANYI | 6434bbca1b | ||
Bruno BELANYI | c7f1e0c57c | ||
Bruno BELANYI | 9c1b1bc4a5 | ||
Bruno BELANYI | 3fb206b0e5 | ||
Bruno BELANYI | cef3c2fa8d | ||
Bruno BELANYI | 5e1b3b095c | ||
Bruno BELANYI | 97ce6eb8b5 | ||
Bruno BELANYI | 00df99ac05 | ||
Bruno BELANYI | 531bbda3d5 | ||
Bruno BELANYI | fc8af0d5ce | ||
Bruno BELANYI | 3b0f1c8882 | ||
Bruno BELANYI | 4a99cd11bd | ||
Bruno BELANYI | f535c7c129 | ||
Bruno BELANYI | 2ab20607e1 | ||
Bruno BELANYI | ab86a2dce7 | ||
Bruno BELANYI | e05173e73b | ||
Bruno BELANYI | 6d778ff545 | ||
Bruno BELANYI | c341ad6eee | ||
Bruno BELANYI | b8d6bc9b4f | ||
Bruno BELANYI | 7793f65af4 | ||
Bruno BELANYI | 4794a6269a | ||
Bruno BELANYI | 7f9758eb0c | ||
Bruno BELANYI | 10abc46e11 | ||
Bruno BELANYI | 330a8d64d0 | ||
Bruno BELANYI | d474708fc8 | ||
Bruno BELANYI | 55e08af4b1 | ||
Bruno BELANYI | ce04fb589b | ||
Bruno BELANYI | 039e7f5214 | ||
Bruno BELANYI | ea66011fef | ||
Bruno BELANYI | daa87d923d | ||
Bruno BELANYI | 2177287e01 | ||
Bruno BELANYI | 484a9722ad | ||
Bruno BELANYI | 614d3447c5 | ||
Bruno BELANYI | 8acf8aadaf | ||
Bruno BELANYI | b15c1a0d57 | ||
Bruno BELANYI | cba9dd02f8 | ||
Bruno BELANYI | 7956b96baa | ||
Bruno BELANYI | 4b03030ed6 | ||
Bruno BELANYI | a21310895c | ||
Bruno BELANYI | 05a6845e83 | ||
Bruno BELANYI | 357c18a5fa | ||
Bruno BELANYI | 175706ca68 | ||
Bruno BELANYI | b1bec40137 | ||
Bruno BELANYI | 2f661fa8a8 | ||
Bruno BELANYI | 0c925ae943 | ||
Bruno BELANYI | 50b46506ee | ||
Bruno BELANYI | 01750a9c39 | ||
Bruno BELANYI | 1337f92ef3 | ||
Bruno BELANYI | e2acd44936 | ||
Bruno BELANYI | 5dfe49a98d | ||
Bruno BELANYI | 6183509703 | ||
Bruno BELANYI | 7ce292eb33 | ||
Bruno BELANYI | 56b37a3e4f | ||
Bruno BELANYI | 3270cf77aa | ||
Bruno BELANYI | 0e09148689 | ||
Bruno BELANYI | aab1b0d7e8 | ||
Bruno BELANYI | fe4d2f5c1f | ||
Bruno BELANYI | 6158f55f42 | ||
Bruno BELANYI | cd827923c3 | ||
Bruno BELANYI | 3e7dc177ff | ||
Bruno BELANYI | 8c30df4da9 | ||
Bruno BELANYI | bd8b216cf2 | ||
Bruno BELANYI | 810aee2aed | ||
Bruno BELANYI | 987cdd56c5 | ||
Bruno BELANYI | c8b9636957 | ||
Bruno BELANYI | 5cb2e01a2f | ||
Bruno BELANYI | b2e5775014 | ||
Bruno BELANYI | 9171fe1ae2 | ||
Bruno BELANYI | 16e0da1a2c | ||
Bruno BELANYI | 37bc234a8a | ||
Bruno BELANYI | 8a2bbc38b6 | ||
Bruno BELANYI | 9baeadebee | ||
Bruno BELANYI | f0658a7c81 | ||
Bruno BELANYI | 1480e095c5 | ||
Bruno BELANYI | 9b09b7f5f3 | ||
Bruno BELANYI | f7bf6d1058 | ||
Bruno BELANYI | b2b051837f | ||
Bruno BELANYI | 9d2ad5dce4 | ||
Bruno BELANYI | e802aea353 | ||
Bruno BELANYI | 711cb4724b | ||
Bruno BELANYI | ee985f7151 | ||
Bruno BELANYI | 886e96349a | ||
Bruno BELANYI | 57cd081712 | ||
Bruno BELANYI | 1ce8bd45b3 | ||
Bruno BELANYI | a2d966926b | ||
Bruno BELANYI | e9b6af3754 | ||
Bruno BELANYI | 54b5f45c5a | ||
Bruno BELANYI | 2c134402dc | ||
Bruno BELANYI | d3f00411f4 | ||
Bruno BELANYI | 717d495d89 | ||
Bruno BELANYI | d3da5495c9 | ||
Bruno BELANYI | 1c4bec86ef | ||
Bruno BELANYI | 258e8a568b | ||
Bruno BELANYI | 8544842253 | ||
Bruno BELANYI | b5042767c6 | ||
Bruno BELANYI | 5d6ea97234 | ||
Bruno BELANYI | f071afb02b | ||
Bruno BELANYI | b26314c942 | ||
Bruno BELANYI | f157debb7b | ||
Bruno BELANYI | 3afd466d83 | ||
Bruno BELANYI | 72cd094e0c | ||
Bruno BELANYI | ff956922aa | ||
Bruno BELANYI | a6110aaa7f | ||
Bruno BELANYI | 07198e85d3 | ||
Bruno BELANYI | 687b0a848d | ||
Bruno BELANYI | e171f3953b | ||
Bruno BELANYI | 0eefd66d10 | ||
Bruno BELANYI | 9202d31fa8 | ||
Bruno BELANYI | d2abd31795 | ||
Bruno BELANYI | d6c0be03f0 | ||
Bruno BELANYI | 49feb648c1 | ||
Bruno BELANYI | bd842fd6f8 | ||
Bruno BELANYI | 7a599b5139 | ||
Bruno BELANYI | 93b884fef3 | ||
Bruno BELANYI | aeddad4f38 | ||
Bruno BELANYI | e843016596 | ||
Bruno BELANYI | 13a1532871 | ||
Bruno BELANYI | 2a281d1857 | ||
Bruno BELANYI | 632a4b004f | ||
Bruno BELANYI | be6b51f20f | ||
Bruno BELANYI | d3d35e2001 | ||
Bruno BELANYI | e28d9faeef | ||
Bruno BELANYI | ac365651d3 | ||
Bruno BELANYI | f3647021be | ||
Bruno BELANYI | f31334b438 | ||
Bruno BELANYI | 57b1172146 | ||
Bruno BELANYI | 84b83d27a0 | ||
Bruno BELANYI | a8de8b9a3f | ||
Bruno BELANYI | 5012cbfcb1 | ||
Bruno BELANYI | c2c3ad7c32 | ||
Bruno BELANYI | a8ffb5bf66 | ||
Bruno BELANYI | 359dfe5d54 | ||
Bruno BELANYI | 91dabb5b6a | ||
Bruno BELANYI | 2b84e1c6f1 | ||
Bruno BELANYI | 4f2385a8ba | ||
Bruno BELANYI | fdac3b73af | ||
Bruno BELANYI | a67fd01204 | ||
Bruno BELANYI | 1108caab20 | ||
Bruno BELANYI | c13206f5aa | ||
Bruno BELANYI | b9199f86f5 | ||
Bruno BELANYI | 3c766f31dd | ||
Bruno BELANYI | 121678cd81 | ||
Bruno BELANYI | d7e663cd0c | ||
Bruno BELANYI | 2375649653 | ||
Bruno BELANYI | 5297e0bafe | ||
Bruno BELANYI | b8dfe0d149 | ||
Bruno BELANYI | 5178c58a5a | ||
Bruno BELANYI | 5f9288aa5f | ||
Bruno BELANYI | 0d175c824f | ||
Bruno BELANYI | 776577c118 | ||
Bruno BELANYI | a304a38046 | ||
Bruno BELANYI | 17a4286307 | ||
Bruno BELANYI | 6d30ed5992 | ||
Bruno BELANYI | 30a7a7da33 | ||
Bruno BELANYI | 82f57ddea5 | ||
Bruno BELANYI | dad9912dd2 | ||
Bruno BELANYI | 07223f9d30 | ||
Bruno BELANYI | 254093a24d | ||
Bruno BELANYI | ffe7fa42d5 | ||
Bruno BELANYI | 035b8b5a0f | ||
Bruno BELANYI | 704cf451cb | ||
Bruno BELANYI | c1c5abc0a4 | ||
Bruno BELANYI | 78954b23e5 | ||
Bruno BELANYI | e4699300b0 | ||
Bruno BELANYI | 3fc73336a4 | ||
Bruno BELANYI | ac39fe2abb | ||
Bruno BELANYI | 1b8f5bc5e0 | ||
Bruno BELANYI | ed9ba2c14a | ||
Bruno BELANYI | d3445b2ef1 | ||
Bruno BELANYI | 2b15ae7552 | ||
Bruno BELANYI | 213575d822 | ||
Bruno BELANYI | 030f45af6c | ||
Bruno BELANYI | 3a19846717 | ||
Bruno BELANYI | 94dffe573c | ||
Bruno BELANYI | 20d47b0048 | ||
Bruno BELANYI | aee22cd938 | ||
Bruno BELANYI | 9b842e321c | ||
Bruno BELANYI | ce998da2e2 | ||
Bruno BELANYI | 968562f2c9 | ||
Bruno BELANYI | 2866dc88c9 | ||
Bruno BELANYI | 3ffe51992d | ||
Bruno BELANYI | 31090e26d3 | ||
Bruno BELANYI | 53ce8a1258 | ||
Bruno BELANYI | 97f8ebd006 | ||
Bruno BELANYI | 405fb690a7 | ||
Bruno BELANYI | b7754cbafb | ||
Bruno BELANYI | 20546f5e81 | ||
Bruno BELANYI | b42bf6c526 | ||
Bruno BELANYI | c8ae320cc3 | ||
Bruno BELANYI | 87ba3e1726 | ||
Bruno BELANYI | d39f649c64 | ||
Bruno BELANYI | 0f964aaeab | ||
Bruno BELANYI | 524e3711ae | ||
Bruno BELANYI | f2a968616f | ||
Bruno BELANYI | cac131629d | ||
Bruno BELANYI | 76deb52857 | ||
Bruno BELANYI | 3978e39554 | ||
Bruno BELANYI | 3d9b48a237 | ||
Bruno BELANYI | 91621b3394 | ||
Bruno BELANYI | f8127cba7a | ||
Bruno BELANYI | a4ac7ea2aa | ||
Bruno BELANYI | 402e014d4d | ||
Bruno BELANYI | 160d779f3e | ||
Bruno BELANYI | 026ec029b3 | ||
Bruno BELANYI | 625590f31a | ||
Bruno BELANYI | e91fc23ca1 | ||
Bruno BELANYI | be24ef1771 | ||
Bruno BELANYI | 9b1d63fd54 | ||
Bruno BELANYI | 1a96ae91b1 | ||
Bruno BELANYI | c7203e4a59 | ||
Bruno BELANYI | a71bb20141 | ||
Bruno BELANYI | bd040e8594 |
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 Dict, 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()
|
103
2019/d05/ex1/ex1.py
Executable file
103
2019/d05/ex1/ex1.py
Executable file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from copy import deepcopy
|
||||||
|
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 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),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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
211
2019/d09/ex1/ex1.py
Executable file
211
2019/d09/ex1/ex1.py
Executable file
|
@ -0,0 +1,211 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
import sys
|
||||||
|
from copy import deepcopy
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
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
|
||||||
|
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
|
211
2019/d09/ex2/ex2.py
Executable file
211
2019/d09/ex2/ex2.py
Executable file
|
@ -0,0 +1,211 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
import sys
|
||||||
|
from copy import deepcopy
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
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
|
||||||
|
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 @@
|
||||||
|
#...##.####.#.......#.##..##.#.
|
||||||
|
#.##.#..#..#...##..##.##.#.....
|
||||||
|
#..#####.#......#..#....#.###.#
|
||||||
|
...#.#.#...#..#.....#..#..#.#..
|
||||||
|
.#.....##..#...#..#.#...##.....
|
||||||
|
##.....#..........##..#......##
|
||||||
|
.##..##.#.#....##..##.......#..
|
||||||
|
#.##.##....###..#...##...##....
|
||||||
|
##.#.#............##..#...##..#
|
||||||
|
###..##.###.....#.##...####....
|
||||||
|
...##..#...##...##..#.#..#...#.
|
||||||
|
..#.#.##.#.#.#####.#....####.#.
|
||||||
|
#......###.##....#...#...#...##
|
||||||
|
.....#...#.#.#.#....#...#......
|
||||||
|
#..#.#.#..#....#..#...#..#..##.
|
||||||
|
#.....#..##.....#...###..#..#.#
|
||||||
|
.....####.#..#...##..#..#..#..#
|
||||||
|
..#.....#.#........#.#.##..####
|
||||||
|
.#.....##..#.##.....#...###....
|
||||||
|
###.###....#..#..#.....#####...
|
||||||
|
#..##.##..##.#.#....#.#......#.
|
||||||
|
.#....#.##..#.#.#.......##.....
|
||||||
|
##.##...#...#....###.#....#....
|
||||||
|
.....#.######.#.#..#..#.#.....#
|
||||||
|
.#..#.##.#....#.##..#.#...##..#
|
||||||
|
.##.###..#..#..#.###...#####.#.
|
||||||
|
#...#...........#.....#.......#
|
||||||
|
#....##.#.#..##...#..####...#..
|
||||||
|
#.####......#####.....#.##..#..
|
||||||
|
.#...#....#...##..##.#.#......#
|
||||||
|
#..###.....##.#.......#.##...##
|
87
2019/d10/ex2/ex2.py
Executable file
87
2019/d10/ex2/ex2.py
Executable file
|
@ -0,0 +1,87 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from cmath import phase
|
||||||
|
from itertools import groupby
|
||||||
|
from math import gcd, pi
|
||||||
|
from pprint import pprint
|
||||||
|
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 Dict, 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 Dict, 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
|
29
2019/d16/ex2/ex2.py
Executable file
29
2019/d16/ex2/ex2.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 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 Iterator, List, NamedTuple, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
66
2020/d07/ex2/ex2.py
Executable file
66
2020/d07/ex2/ex2.py
Executable file
|
@ -0,0 +1,66 @@
|
||||||
|
#!/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 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