Compare commits
477 commits
43650ade44
...
67ef6227dc
Author | SHA1 | Date | |
---|---|---|---|
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 |
7
.envrc
Normal file
7
.envrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
use_flake() {
|
||||
watch_file flake.nix
|
||||
watch_file flake.lock
|
||||
eval "$(nix print-dev-env)"
|
||||
}
|
||||
|
||||
use flake
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Generated by Nix
|
||||
/.pre-commit-config.yaml
|
2
.isort.cfg
Normal file
2
.isort.cfg
Normal file
|
@ -0,0 +1,2 @@
|
|||
[settings]
|
||||
profile=black
|
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
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue