Compare commits

...

99 Commits

Author SHA1 Message Date
afff8dd79f Final 2021 changes. 2022-11-30 18:56:34 -08:00
6cab94ba0b Day 22 part 2 stubbed out 2021-12-23 20:46:56 -08:00
987760422a Day 22 part 1 2021-12-23 20:34:13 -08:00
2400d34336 Day 21 some clippy cleanup 2021-12-23 19:44:52 -08:00
e4e00517f7 Disable broken day 21 part 2. 2021-12-23 19:43:32 -08:00
d56885bd14 Day 21 part 1 and non-functioning part 2. 2021-12-23 19:25:22 -08:00
b67eea9efe Day 20 part 2 2021-12-22 15:07:49 -08:00
fca64c2988 Day 20 part 1 w/ hack 2021-12-22 13:31:18 -08:00
6fbc06d4e1 advent: add helper image class (not currently used). 2021-12-22 12:46:30 -08:00
1b837b8965 Day 18 WIP, soo close. 2021-12-22 11:33:39 -08:00
a31a47b4b5 Day 18 add merge (aka +) capability. 2021-12-21 14:07:45 -08:00
247e4a89a5 Day 18 basic parse/Display implementations. 2021-12-21 14:07:17 -08:00
7a3a9c096a Address cargo clippy 2021-12-17 20:41:20 -08:00
b83d6f081d Day 17 part 2 2021-12-17 20:37:05 -08:00
2848a9ae1f Day 17 part 1 2021-12-17 19:40:54 -08:00
232b2687ca Create advent prelude and cleanup lint by using it. 2021-12-16 20:10:01 -08:00
1fb9a8416d Day 16 part 2 2021-12-16 20:00:41 -08:00
6ba8f3900c Day 16 part 1 rewrite into structured data 2021-12-16 19:28:08 -08:00
8739e5cc91 Day 16 part 1 2021-12-15 23:32:42 -08:00
c7a180dee3 Day 15 part 2 2021-12-15 11:24:42 -08:00
c16e3ad864 Day 15 part 1 2021-12-15 10:37:15 -08:00
2fdcf171b0 Day 13 part 2 2021-12-14 22:08:36 -08:00
1a427b7a1f Day 13 part 1 2021-12-14 22:07:40 -08:00
39cf326001 Day 14 fix part 1 and comment out part 2 2021-12-14 19:56:38 -08:00
0a2c2d13ce Day 14 part 2 that compiles forever 2021-12-14 19:47:05 -08:00
dbd597ad41 Day 14 part 1 2021-12-13 21:52:05 -08:00
9cdb935254 Some template changes to match common patterns. 2021-12-13 21:51:46 -08:00
e93f6d01ca Day 12 clippy lint. 2021-12-11 22:21:27 -08:00
b542304187 Day 12 part 2 2021-12-11 22:19:43 -08:00
b6dacf5b47 Day 12 part 1 solution. 2021-12-11 21:50:19 -08:00
b88d1d2a37 Day 11 clippy lint 2021-12-10 22:37:12 -08:00
197fc4dc2c Day 11 part 1 and 2 2021-12-10 22:35:59 -08:00
69a9bb276d Day 10 part 1 and 2 2021-12-09 22:22:17 -08:00
9cd8f5e4c8 Day 10 part 1 solution. 2021-12-09 22:21:29 -08:00
4e647d1bff Day 9 part 2, now works on final input data. 2021-12-09 18:01:08 -08:00
5000517fd0 Day 9 part 2, works for test data but stack overflows on real data. 2021-12-08 23:07:28 -08:00
35ef072d7f Day 9 part 1 solution 2021-12-08 21:55:55 -08:00
df51dcdaa8 Day 8 part 1 add a bunch of variations 2021-12-08 18:49:38 -08:00
b15a06e07c Day 8 part 2 perf improvements with s/HashSet/Vec/ and others 2021-12-08 18:16:15 -08:00
19ca505fde Day 8 part 2 perf improvements with Segment 2021-12-08 17:58:25 -08:00
19d9d47d4f Day 8 part 2 2021-12-07 22:46:43 -08:00
45ba7b3cb5 Day 8 part 1 2021-12-07 21:36:56 -08:00
b030505425 day[47]: lint cleanup. 2021-12-07 20:11:31 -08:00
0483ba1c77 Day 7 part 2 2021-12-07 13:56:01 -08:00
091f53b1fe Day 7 part 1 2021-12-07 11:30:25 -08:00
186fc8e581 Day 4 don't print out winning table. 2021-12-06 21:08:26 -08:00
1e34e0abea Day 4 try using bit comparisons to find bingo.
This is actually slower for some reason.
2021-12-06 20:42:24 -08:00
10fe6a570e Day 4 perf improvments v1 2021-12-06 20:01:48 -08:00
343707c63c Day 6 part 2 slightly faster over pre-rotate_left version. 2021-12-06 19:13:46 -08:00
60b77d5d3d day 6 part 2 Use rotate_left 2021-12-06 18:06:13 -08:00
6acaaf8b7a Day 6 part 2, put data on stack 2021-12-06 15:50:10 -08:00
44c0c16255 Day 6 part 2 2021-12-06 15:26:45 -08:00
e0bfb8b09d Day 6 part 1 2021-12-06 14:42:41 -08:00
5f6aded243 Update template. 2021-12-05 18:57:03 -08:00
45f780c1ca Address cargo clippy output. 2021-12-05 14:51:58 -08:00
5b65e8ec71 Day 5 part 2 2021-12-05 14:43:03 -08:00
ae10705a38 Day 5 part 1 2021-12-05 13:57:02 -08:00
9491fe5d9f Day 4 part 2 2021-12-04 22:00:55 -08:00
65eac56f1c Day 4 part 1 2021-12-04 21:47:57 -08:00
d5a07374fe Cleanup unused use statement. 2021-12-04 21:47:34 -08:00
4e37406c53 Put tests in sub module for template. 2021-12-04 21:46:49 -08:00
02ebdf3613 Add rustfmt.toml. 2021-12-04 10:49:08 -08:00
d2b1742d72 Day 3 part 2 2021-12-04 08:40:21 -08:00
53136289d5 Day 3 part 1 2021-12-03 14:59:04 -08:00
11744d1fe9 Use anyhow to make try operator feasible in parse and part#. 2021-12-01 21:34:51 -08:00
11c5dcaaaf Use anyhow to make ? availble 2021-12-01 21:24:46 -08:00
eca0b7d3a1 Day 2 part 2. 2021-12-01 21:18:11 -08:00
d4e5f1aea9 Day 2 part 1. 2021-12-01 21:13:45 -08:00
e5815a6784 Fix missing dependency in template. 2021-12-01 21:13:30 -08:00
ccc258bcb2 Stub implementation template. 2021-12-01 19:38:13 -08:00
76da21b3cc day1 part2 2021-11-30 22:00:25 -08:00
6de9b72fae day1 part1 2021-11-30 21:56:27 -08:00
6a4ec39446 Stub out initial 2021 runner. 2021-11-30 21:21:32 -08:00
586ab1680c Cleanup verbose debug output in release mode for day 21 2020-12-26 17:24:52 -08:00
2f36a0b5e8 Cleanup lint and make sure all tests run as appropriate with debug_assertions enable 2020-12-26 17:20:13 -08:00
992fcb01be Day 18 part 1 (fixed) 2020-12-26 15:19:23 -08:00
4e9e90c096 Day 18 part 2 solution (and broke part 1) 2020-12-26 15:15:03 -08:00
d935de1fb0 Day 20 part 2 solution. 2020-12-26 12:34:44 -08:00
5535aaf810 Day 25 part 2 text. 2020-12-26 08:28:24 -08:00
1c5032a5e5 Day 25 part 1 solution. 2020-12-26 08:25:30 -08:00
e3d9c13731 Day 23 hint for improving runtime. 2020-12-26 08:25:06 -08:00
e04081ac4a Day 22 lint cleanup. 2020-12-26 08:24:49 -08:00
68b7037d20 Day 24 part 2 solution. 2020-12-25 16:27:10 -08:00
5e92b3a7e0 Day 24 part 1 solution.
Broken day 23 part 2.
Moved debug_println into lib.rs.
2020-12-25 14:18:12 -08:00
25855b47a6 Day 23 part 1 solution 2020-12-23 20:47:52 -08:00
5900b4d3c6 Day 18 part 2 BROKEN. 2020-12-23 19:03:07 -08:00
5b10da61a4 Day 18 part 1 solution and comprehensive tests 2020-12-22 19:57:51 -08:00
48a55571c2 Day 22 part 2 solution. 2020-12-22 19:35:38 -08:00
67ee67ea42 Updating README.md 2020-12-22 16:32:29 -08:00
038e67d444 Day 22 part 2 doc comment 2020-12-22 15:36:32 -08:00
b7ff05ac27 Day 22 part 1 solution 2020-12-22 15:28:13 -08:00
b160a511b3 Day 21 cleanup debugging. 2020-12-22 14:57:48 -08:00
97d32e2588 Day 21 part 2 working. 2020-12-21 22:04:22 -08:00
9ef8a73b15 Day 21 part 1 & part 2, unit tests pass, but website rejects part 2 2020-12-21 22:00:54 -08:00
abac9fbfda Day 21 part 1 solution 2020-12-21 20:40:34 -08:00
1144eb6afc Day 20 part 2 BROKEN. 2020-12-21 17:21:43 -08:00
e8007abb76 Day 20 part 1 solution. 2020-12-20 10:12:02 -08:00
7bfe984659 Day 18 use large numeric type to prevent overflow. 2020-12-20 10:11:30 -08:00
37fdc75db4 Shitty day 19 part 2 answer 2020-12-19 15:17:44 -08:00
76 changed files with 21947 additions and 334 deletions

13
.gitignore vendored
View File

@@ -1 +1,14 @@
**/target/ **/target/
# Added by cargo
/target
# Added by cargo
#
# already existing elements were commented out
#/target
Cargo.lock

69
2020/Cargo.lock generated
View File

@@ -7,6 +7,7 @@ dependencies = [
"anyhow", "anyhow",
"aoc-runner", "aoc-runner",
"aoc-runner-derive", "aoc-runner-derive",
"pretty_assertions",
"regex", "regex",
] ]
@@ -19,6 +20,15 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.34" version = "1.0.34"
@@ -54,6 +64,22 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "ctor"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.6" version = "0.4.6"
@@ -72,6 +98,27 @@ version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "output_vt100"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
dependencies = [
"winapi",
]
[[package]]
name = "pretty_assertions"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
dependencies = [
"ansi_term",
"ctor",
"difference",
"output_vt100",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.24" version = "1.0.24"
@@ -167,3 +214,25 @@ name = "unicode-xid"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -11,3 +11,8 @@ anyhow = "1.0.34"
aoc-runner = "0.3.0" aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0" aoc-runner-derive = "0.3.0"
regex = "1.4.2" regex = "1.4.2"
[dev-dependencies]
pretty_assertions = "0.6"
[profile.release]
debug = true

View File

@@ -1,155 +1,236 @@
``` ```
Advent of code 2020 Advent of code 2020
Day 1 - Part 1 - binary: 1006875 Day 1 - Part 1 - binary: 1006875
generator: 21.838µs, generator: 21.403µs,
runner: 1.773µs runner: 581ns
Day 1 - Part 1 - linear: 1006875 Day 1 - Part 1 - linear: 1006875
generator: 5.339µs, generator: 8.431µs,
runner: 8.329µs runner: 11.164µs
Day 1 - Part 1 - set: 1006875 Day 1 - Part 1 - set: 1006875
generator: 18.303µs, generator: 22.51µs,
runner: 1.392µs runner: 1.04µs
Day 1 - Part 2: 165026160 Day 1 - Part 2: 165026160
generator: 4.735µs, generator: 6.176µs,
runner: 1.465477ms runner: 1.320463ms
Day 2 - Part 1: 640 Day 2 - Part 1: 640
generator: 1.713032ms, generator: 1.572384ms,
runner: 123.609µs runner: 99.594µs
Day 2 - Part 1 - handrolled: 640 Day 2 - Part 1 - handrolled: 640
generator: 173.912µs, generator: 202.476µs,
runner: 109.58µs runner: 106.704µs
Day 2 - Part 2: 472 Day 2 - Part 2: 472
generator: 1.475144ms, generator: 1.341148ms,
runner: 10.985µs runner: 10.37µs
Day 3 - Part 1: 148 Day 3 - Part 1: 148
generator: 38.406µs, generator: 35.027µs,
runner: 2.797µs runner: 1.018µs
Day 3 - Part 2: 727923200 Day 3 - Part 2: 727923200
generator: 37.063µs, generator: 33.64µs,
runner: 12.181µs runner: 4.379µs
Day 4 - Part 1: 239 Day 4 - Part 1: 239
generator: 372.532µs, generator: 351.073µs,
runner: 1.922µs runner: 1.736µs
Day 4 - Part 2: 188 Day 4 - Part 2: 188
generator: 363.202µs, generator: 332.453µs,
runner: 43.784µs runner: 42.199µs
Day 5 - Part 1 - glenng: 989 Day 5 - Part 1 - glenng: 989
generator: 171ns, generator: 181ns,
runner: 81.501µs runner: 77.639µs
Day 5 - Part 1 - wathiede: 989 Day 5 - Part 1 - wathiede: 989
generator: 85.614µs, generator: 83.219µs,
runner: 459ns runner: 632ns
Day 5 - Part 2 - wathiede: 548 Day 5 - Part 2 - wathiede: 548
generator: 86.417µs, generator: 76.923µs,
runner: 29.328µs runner: 28.274µs
Day 6 - Part 1: 6930 Day 6 - Part 1: 6930
generator: 118ns, generator: 122ns,
runner: 630.141µs runner: 548.722µs
Day 6 - Part 2: 3585 Day 6 - Part 2: 3585
generator: 127ns, generator: 109ns,
runner: 2.007135ms runner: 1.786837ms
Day 6 - Part 2 - faster: 3585 Day 6 - Part 2 - faster: 3585
generator: 129ns, generator: 119ns,
runner: 1.095441ms runner: 911.866µs
Day 7 - Part 1: 222 Day 7 - Part 1: 222
generator: 1.109401ms, generator: 936.409µs,
runner: 202.592µs runner: 181.642µs
Day 7 - Part 2: 13264 Day 7 - Part 2: 13264
generator: 1.092186ms, generator: 898.057µs,
runner: 5.447µs runner: 4.034µs
Day 8 - Part 1: 1744 Day 8 - Part 1: 1744
generator: 143ns, generator: 183ns,
runner: 47.289µs runner: 38.058µs
Day 8 - Part 2: 1174 Day 8 - Part 2: 1174
generator: 111ns, generator: 119ns,
runner: 150.1µs runner: 144.217µs
Day 9 - Part 1: 1309761972 Day 9 - Part 1: 1309761972
generator: 27.284µs, generator: 29.337µs,
runner: 37.991µs runner: 40.825µs
Day 9 - Part 1 - sorted: 1309761972 Day 9 - Part 1 - sorted: 1309761972
generator: 26.598µs, generator: 26.371µs,
runner: 230.765µs runner: 222.038µs
Day 9 - Part 2: 177989832 Day 9 - Part 2: 177989832
generator: 28.558µs, generator: 29.874µs,
runner: 124.417µs runner: 119.825µs
Day 10 - Part 1: 1625 Day 10 - Part 1: 1625
generator: 6.835µs, generator: 6.602µs,
runner: 421ns runner: 528ns
Day 10 - Part 2: 3100448333024 Day 10 - Part 2: 3100448333024
generator: 4.802µs, generator: 4.893µs,
runner: 1.176µs runner: 1.448µs
Day 11 - Part 1: 2338 Day 11 - Part 1: 2338
generator: 75.55µs, generator: 67.172µs,
runner: 11.383128ms runner: 12.483103ms
Day 11 - Part 2: 2134 Day 11 - Part 2: 2134
generator: 58.641µs, generator: 117.56µs,
runner: 49.994105ms runner: 47.514021ms
Day 12 - Part 1: 1838 Day 12 - Part 1: 1838
generator: 38.302µs, generator: 81.477µs,
runner: 8.936µs runner: 9.093µs
Day 12 - Part 2: 89936 Day 12 - Part 2: 89936
generator: 33.951µs, generator: 55.605µs,
runner: 8.316µs runner: 8.085µs
Day 13 - Part 1: 153 Day 13 - Part 1: 153
generator: 2.04µs, generator: 2.293µs,
runner: 205ns runner: 384ns
Day 13 - Part 2: 471793476184394 Day 13 - Part 2: 471793476184394
generator: 2.258µs, generator: 2.142µs,
runner: 3.68µs runner: 2.576µs
Day 14 - Part 1: 10717676595607 Day 14 - Part 1: 10717676595607
generator: 93ns, generator: 86ns,
runner: 89.201µs runner: 117.882µs
Day 14 - Part 2: 3974538275659 Day 14 - Part 2: 3974538275659
generator: 92ns, generator: 155ns,
runner: 5.803116ms runner: 5.737865ms
Day 15 - Part 1: 929 Day 15 - Part 1: 929
generator: 177ns, generator: 145ns,
runner: 253.908µs runner: 257.345µs
Day 15 - Part 2: 16671510 Day 15 - Part 2: 16671510
generator: 114ns, generator: 106ns,
runner: 2.423626128s runner: 2.520441045s
Day 16 - Part 1: 23115 Day 16 - Part 1: 23115
generator: 246.028µs, generator: 268.255µs,
runner: 24.917µs runner: 23.009µs
Day 16 - Part 2: 239727793813 Day 16 - Part 2: 239727793813
generator: 246.67µs, generator: 214.632µs,
runner: 429.366µs runner: 392.169µs
Day 17 - Part 1: 315
generator: 3.741µs,
runner: 2.863143ms
Day 17 - Part 2: 1520
generator: 2.332µs,
runner: 29.722289ms
Day 19 - Part 1: 178
generator: 1.706494ms,
runner: 228.465µs
Day 19 - Part 2: 346
generator: 50.489244ms,
runner: 9.837093ms
Day 21 - Part 1: 2595
generator: 314.271µs,
runner: 613.046µs
["sesame", "nuts"]: thvm ckqq qrsczjv zmb zrgzf jmdg hlmvqh *pnglkx *nfnzx *tjsdp *jkbqk *rpmqq *gzgvdh *rgdx *szsbj *xjdhk *zfml *ddbmq *mvnqdh *gsgmdn *dtlhh *rqqfnlc *bxv *nthhxn *hnmjfl *fkh *hkxcb *rpcdfph *flhfddq *qspfqb *rpmmv *jfqqgtl *xxfgvz *kltcm *xjrpr *vnfmc *xhmmt *zkzdrn *xgbvk *ngqh *djpsmd *bnzq *rbvdt *tfmgl *pjln
["sesame"]: thvm mrfxh ckqq hlmvqh zmb qrsczjv zrgzf *qchnn *dnpgcd *zfml *gsgmdn *frld *nfnzx *nqfc *xbpb *kltcm *ljmvpp *zntrfp *gzgvdh *rrbndl *pptgt *rknm *qsgb *mstc *zzldmh *nggcjr *bkd *zfsks *cxzkmr *tzjnvp *npbnj *lh *pfqxsxd *clqk *rpmmv *szsbj *mnvq *cnghsg *jdtzr *kfsfn *jxjqp *knqzf *lvjpp *qdpbx *xxfgvz *ngqh *jvvmcq *zmcj *dsmc *xhmmt
["eggs"]: hlmvqh qrsczjv thvm zrgzf ckqq jmdg mrfxh *klmjmz *clqk *pjln *lvjpp *tbm *rqqfnlc *gzgvdh *klx *sfk *bnzq *mhrm *vht *pjqdmpm *tfmgl *cxzkmr *ghr *rxrgtvs *rfh *rhrc *vnfmc *ljhn *fbcds *rkzhxmh *htllnq *xhmmt *rcr *dgrrm *xlzqfb *xlnn *vpgvm *zntrfp *pgqxp *xjrpr *vnmfg *vqrjn *thcs *mnvq *rczbvg *bkd *zqsc *ngqh *rpmqq *zmcj *cbbkfx *rpcdfph *jfqqgtl *mszc *tzjnvp *sdccxkt *rcvd *pcf *xzcdnr *jgtrnm *zfcvnj *dsmc *gjqfj *gtgrcf *nthhxn *jngghk *hnmjfl *qspfqb *bxv
["dairy", "peanuts", "eggs"]: mrfxh zrgzf zmb jmdg thvm ckqq hlmvqh *nthhxn *htllnq *pbn *qsgb *dvcfx *mstc *jngghk *xddkbd *dpfphd *zhghprj *rfh *ljmvpp *vtljml *pmtfmv *xxfgvz *crnfzr *xbpb *tshn *nqfc *kmsh *rknm *hkqp *pjqdmpm *pjln *ddbmq *bjvcg *zntrfp *vnfmc *qszmzsh *fhtsl *tjsdp *kfsfn *jkbqk *mnvq *dnpgcd *xzcdnr *xjrpr *rbvdt *vht *jxjqp *zzldmh *cnghsg *pzxj *jfqqgtl *kqzcj *lxr *glrc *dgrrm *cxzkmr *clqk *xjdhk *vpvj *lbfgp *klmjmz
["dairy"]: zrgzf thvm mrfxh zmb hlmvqh jmdg ckqq *rqqfnlc *vgp *tbm *tjsdp *tshn *zzldmh *vgjbgj *pptgt *xnfhq *pbn *rpmmv *dnpgcd *qszmzsh *rbvdt *nzlks *xddkbd *npbnj *lxr *szsbj *dtlhh *ljmvpp *xjzc *pjqdmpm *rknm *rrbndl *xhmmt *pjln *pfqxsxd *jdtzr *jnr *jkbqk *vht *vhcnpg *ddgdhg *pzxj *ljhn *xgbvk *qfkjsq *zhghprj *gzgvdh *xzcdnr *ddbmq *rcvd *lbfgp *mvnqdh *rfh *nggcjr *gjqfj *hrfmdk
["soy", "shellfish"]: jmdg ckqq qrsczjv thvm mrfxh hlmvqh zrgzf *cmnb *cnghsg *cxzkmr *vfkpj *pgb *xddkbd *qfvfzg *gzgvdh *bxv *zfml *clqk *pbn *nthhxn *rvchbn *xbpb *sfk *dtlhh *rqqfnlc *rhrc *djpsmd *qrftr *gjqfj *bjvcg *zntrfp *zlgztsbd *lbfgp *vnmfg *jkbqk *lvjpp *pfqxsxd *ljmvpp *mnvq *ljhn *fkh *ddrd *qmmt *rcr *vht *xgbvk *ddbmq *tbm *vhcnpg *srgnx *ngqh *mhrm *pptgt *glrc *rpmmv *kx *htllnq
["nuts", "dairy", "sesame"]: ckqq jmdg zmb thvm mrfxh zrgzf qrsczjv *fdf *tshn *zhghprj *xjzc *xxfgvz *nggcjr *hkqp *vgjbgj *hnmjfl *mstc *dmxhhd *rpmmv *jdtzr *klx *ngqh *gtgrcf *bjvcg *vgp *jgtrnm *ttxx *bcvmz *pgqxp *nfnzx *sjgx *zfcvnj *tzjnvp *qmmt *qdpbx *rhrc *gmc *zfsks *ljmvpp *gjqfj *fjgxv *zttx *lbskg *vnfmc *vfkpj *lxr *hkxcb *dln *xbpb *sfk *vpgvm *ljhn *rknm *rfh *mgxzl *thcs *jfqqgtl *bkd *sdccxkt *zzldmh *rcvd *qchnn *xhmmt *rkzhxmh *xgbvk *csfmx *gzgvdh *ncqdr *rxr *vtljml *lbfgp *pzxj *djpsmd *dpfphd *rczbvg *knnmm *xmjlsn
["nuts", "sesame"]: qrsczjv jmdg hlmvqh mrfxh ckqq thvm zmb *klx *hkqp *lqmfgp *mstc *mgxzl *cxfzhj *xxfgvz *jxjqp *ljhn *pcf *mrxg *bjvcg *vht *lbskg *tphtz *nldzpc *tjsdp *mszc *sfk *dln *ghr *mppf *lbfgp *zkzdrn *qdpbx *bnzq *qsgb *rrbndl *nggcjr *zttx *qjsbk *llgsg *srgnx *dbx *stcsp *rcr *zfml *jvvmcq *pptgt *gmc *fkh *xjdhk *pzxj *zntrfp *flhfddq *knqzf *ddrd *jmgt *fdf *thcs *lh *xmjlsn *kglr *pjqdmpm *kx *dpfphd *vqrjn *vhcnpg *rxrgtvs *pfqxsxd *nqfc *cbbkfx *dtlhh *qmmt *xlzqfb *rpmmv *jfqqgtl *gsgmdn *bcvmz *mnvq *fbcds *xjzc *gtgrcf
["soy"]: hlmvqh zmb qrsczjv zrgzf thvm ckqq jmdg *gzgvdh *vbqbkt *fjgxv *nggcjr *jvvmcq *pptgt *fmvvb *zqsc *rbvdt *llgsg *xddkbd *rfh *pjln *tzjnvp *glrc *rqqfnlc *zttx *rrbndl *qfkjsq *mppf *rxrgtvs *lvjpp *dtlhh *zfml *stcsp *zkzdrn *vtljml *qdpbx *fstgc *xlnn *sdccxkt *hkxcb *kltcm *xlzqfb *jfqqgtl *npbnj *bcvmz *rknm *ngqh *xbpb *rcr *kglr *dbx *xxfgvz *bjvcg *rpmmv *srgnx *gjqfj *tshn *gmc *vgp *dgrrm *ljhn *knnmm *qkgqv *mstc *pnglkx *flhfddq *tjsdp *zntrfp *vgjbgj *bkd
["wheat", "dairy"]: ckqq jmdg zmb thvm hlmvqh zrgzf mrfxh *qjsbk *fkh *xddkbd *fjgxv *lbfgp *rxr *tphtz *vhcnpg *klmjmz *pmtfmv *hrfmdk *dbx *fbcds *jnr *xxfgvz *pfqxsxd *qfvfzg *bxv *flhfddq *rknm *rpmqq *pjln *sdccxkt *pgb *klx *jdtzr *lxr *nthhxn *vnmfg *jgtrnm *nfnzx *zzldmh *ddbmq *nldzpc *tvqbhv *dznd *dnpgcd *cmnb *vpvj *sjgx *xjzc *hkxcb *szsbj *dcbk *pmvl *pjqdmpm *mhrm *rgdx *jfqqgtl *zttx *vtljml *cbbkfx *knqzf *mszc *jkbqk *xbpb *vgjbgj *pptgt *vfkpj *vqrjn *zhghprj *xnfhq *tshn *rcvd *xjdhk *djpsmd *rfh *glrc *rkzhxmh
["peanuts", "soy"]: ckqq jmdg qrsczjv hlmvqh thvm zrgzf zmb *mvnqdh *nqfc *bjvcg *zfcvnj *ljhn *hkqp *srgnx *zfsks *bxv *xbpb *rkzhxmh *cxfzhj *rpmqq *zdntns *dnpgcd *thcs *lvjpp *klx *jngghk *flhfddq *gmc *pjln *dcbk *cbbkfx *vbqbkt *qchnn *tshn *fhtsl *qmthj *jvvmcq *ncqdr *jmgt *csfmx *tzjnvp *rczbvg *rcr *rbvdt *gtgrcf *cnghsg *rxrgtvs
["shellfish", "eggs", "dairy"]: ckqq zrgzf qrsczjv thvm jmdg mrfxh hlmvqh *frld *mvnqdh *tphtz *bjvcg *xzcdnr *djpsmd *ttxx *dcbk *qdpbx *tshn *rczbvg *vpvj *qmmt *ddrd *dln *bxv *jxjqp *lh *mgxzl *ltvr *pbn *nggcjr *dsmc *llgsg *knnmm *pzxj *cnghsg *vnmfg *mhrm *xlnn *gjqfj *pptgt *jkbqk *htllnq *xnfhq *klx *jmgt *rxr *hnmjfl *lqmfgp *qrftr *mppf *sjgx *rvchbn *lvjpp *mstc *zqsc *gmc *kmsh *rpmmv *crnfzr *hrfmdk *kglr *cxzkmr *dvcfx
["nuts", "shellfish"]: jmdg mrfxh thvm qrsczjv zmb ckqq zrgzf *xjrpr *mjpt *cbbkfx *rpmqq *ljhn *vht *sdccxkt *ngqh *bnzq *jgtrnm *fmvvb *xxfgvz *jfqqgtl *tfmgl *bcvmz *pgqxp *crnfzr *xddkbd *zfsks *pzxj *tshn *fbcds *lbfgp *thcs *hkqp *gsgmdn *dvcfx *cnghsg *csfmx *vhqfz *rxr *bxv *xjdhk *zhghprj *dtlhh *qmthj *jxjqp *rczbvg *gmc *sfk *ttxx *ltvr *pnglkx *dnpgcd *qsgb *clqk *klmjmz *lh *rvchbn *pjln *knqzf *vnfmc *qspfqb *nthhxn *zqsc *mhrm *gzgvdh *ncqdr *ddrd *vqrjn
["dairy"]: zrgzf qrsczjv ckqq thvm mrfxh hlmvqh jmdg *rvchbn *vhcnpg *mstc *hkqp *bnzq *xbpb *fhtsl *fjgxv *ddgdhg *jfqqgtl *rpmqq *dpfphd *pcf *qrftr *ngqh *vht *dvcfx *dfrg *tphtz *mnvq *qjsbk *mvnqdh *zntrfp *xjzc *jmgt *xzcdnr *vnfmc *xddkbd *fkh *kmsh *xmjlsn *zfsks *bcvmz *ljhn *gmc *rrbndl *fmvvb *cxzkmr *lh *zdntns *pgb *xxfgvz *hrfmdk *dln *tvqbhv *cnghsg *vpgvm *mjpt *jdtzr *dgrrm *kglr *pgqxp *kqzcj *hkxcb *xgbvk *djpsmd *tshn *klmjmz *rfh *xlnn *bjvcg *qfkjsq *rkzhxmh *glrc *clqk *gjqfj *knqzf *ljmvpp *csfmx *rbvdt *zfcvnj *dsmc *fstgc
["sesame", "shellfish"]: mrfxh zmb hlmvqh qrsczjv thvm zrgzf ckqq *nthhxn *vnfmc *dsmc *vpvj *rhrc *zfcvnj *zdntns *qmthj *knnmm *rpmmv *dtlhh *qdpbx *zhghprj *xddkbd *rqqfnlc *dpfphd *xhmmt *dgrrm *pgqxp *gmc *flhfddq *zkzdrn *vhcnpg *mjpt *fbcds *ncqdr *pjln *zttx *hrfmdk *xlnn *dvcfx *fkh *mszc *klx *cmnb *zfml *mnvq *rcr *bjvcg *csfmx *xlzqfb
["eggs"]: hlmvqh jmdg ckqq zrgzf mrfxh thvm qrsczjv *xnfhq *lh *qdpbx *rpcdfph *qsgb *rpmqq *tjsdp *ljhn *gsgmdn *vfkpj *xlzqfb *qmmt *jmgt *dvcfx *bkd *pmvl *ngqh *sjgx *dpfphd *kfsfn *bjvcg *jkbqk *qrftr *mjpt *vnmfg *nldzpc *ncqdr *jvvmcq *pptgt *pjqdmpm *pjln *ddrd *csfmx *kglr *xgbvk *tzjnvp *bxv *htllnq *fstgc *zfcvnj *jxjqp *pbn *dsmc *kbtx *vqrjn *rqqfnlc *rxrgtvs *hnmjfl
["shellfish", "dairy"]: zrgzf hlmvqh mrfxh thvm jmdg qrsczjv ckqq *mvnqdh *klx *rbvdt *kx *qmthj *hrfmdk *bcvmz *fhtsl *xxfgvz *pmvl *csfmx *hkxcb *rpmqq *vpvj *jmgt *vbqbkt *lxr *zhghprj *kglr *dpfphd *xzcdnr *mszc *vgp *dvcfx *gzgvdh *ncqdr *mppf *nldzpc *djpsmd *pnglkx *lqmfgp *sjgx *jfqqgtl *dln *vhcnpg *npbnj *cmnb *hnmjfl *kfsfn *vtljml *qspfqb *xlzqfb *dcbk *jngghk *lh *jxjqp *rxr *jdtzr *qrftr *fbcds *mrxg *zzldmh *qfvfzg *dtlhh *hkqp *dsmc *qdpbx *cxzkmr *tfmgl *xjrpr *pjqdmpm *rczbvg *rcvd *lbfgp *qszmzsh *glrc *qkgqv *tvqbhv *fkh *rknm *zntrfp *cbbkfx
["nuts"]: zmb thvm qrsczjv zrgzf ckqq jmdg hlmvqh *zqsc *sfk *lvjpp *ddgdhg *qspfqb *dmxhhd *zzldmh *xzcdnr *xjdhk *dznd *qfvfzg *ljhn *ghr *bcvmz *frld *pnglkx *fhtsl *srgnx *jfqqgtl *fdf *vhqfz *qsgb *jkbqk *xxfgvz *pjqdmpm *rpmqq *fkh *crnfzr *mjpt *cnghsg *qrftr *xddkbd *rkzhxmh *pfqxsxd *mhrm *gtgrcf *fmvvb *tvqbhv *dgrrm *xbpb *qmthj *gjqfj *kqzcj *tshn *qkgqv *vfkpj *kmsh *pgqxp *ddrd *glrc *xgbvk *hrfmdk *rgdx *bnzq *knnmm *qchnn *vnmfg *ncqdr *qfkjsq *pmtfmv *xnfhq *sjgx *cbbkfx *stcsp *rbvdt *mstc *gzgvdh *kglr *dsmc *rrbndl *xjzc *rpcdfph
["dairy", "wheat", "eggs"]: jmdg zmb hlmvqh qrsczjv thvm ckqq zrgzf *rbvdt *zkzdrn *hnmjfl *gmc *pgqxp *lqmfgp *knqzf *xbpb *fmvvb *bkd *dgrrm *vgjbgj *dcbk *ttxx *dtlhh *vpgvm *xlnn *jgtrnm *dpfphd *xzcdnr *jngghk *qmmt *flhfddq *gzgvdh *crnfzr *qszmzsh *xlzqfb *dfrg *qspfqb *qmthj *rpcdfph *frld *zqsc *xjdhk *dmxhhd *ljhn *qchnn *bnzq *kltcm *gtgrcf *mszc *zhghprj *rhrc *csfmx *mrxg *klmjmz *lbskg *pzxj *nggcjr *nthhxn *nldzpc *rpmqq *dbx *mhrm *xjzc
["sesame"]: jmdg zmb thvm qrsczjv mrfxh hlmvqh ckqq *lh *sfk *jvvmcq *szsbj *fmvvb *xxfgvz *sjgx *jnr *vqrjn *gmc *cnghsg *qsgb *mppf *jfqqgtl *fjgxv *vbqbkt *zqsc *xgbvk *pgqxp *nqfc *jmgt *rfh *xlnn *rhrc *nfnzx *rpcdfph *qszmzsh *kglr *xnfhq *tbm *zzldmh *rcvd *pmvl *kqzcj *hnmjfl *nggcjr *qchnn *zmcj *rvchbn *fdf *xmjlsn *mnvq *mgxzl *rkzhxmh *bxv *ngqh *xlzqfb *gjqfj *sdccxkt *clqk *cmnb *rbvdt *jkbqk *dpfphd *kltcm *jngghk *mszc
["dairy"]: thvm mrfxh zmb ckqq zrgzf hlmvqh qrsczjv *zfcvnj *mvnqdh *gjqfj *htllnq *nggcjr *vtljml *qrftr *fstgc *xjrpr *dvcfx *klmjmz *qjsbk *rcvd *hrfmdk *rczbvg *mjpt *ncqdr *kbtx *nqfc *xxfgvz *xlzqfb *jkbqk *jmgt *rxrgtvs *qspfqb *rhrc *qmthj *mszc *ghr *fmvvb *cxfzhj *lqmfgp *vfkpj *tzjnvp *mhrm *vpvj *pgqxp *ngqh *xlnn *xnfhq *tbm *zqsc *jvvmcq *rvchbn *lxr *vgp *cmnb *pjqdmpm
["wheat"]: mrfxh zrgzf jmdg thvm hlmvqh qrsczjv zmb *qfvfzg *ngqh *rhrc *nthhxn *mvnqdh *rcr *knnmm *zmcj *nfnzx *stcsp *nzlks *qdpbx *kfsfn *nldzpc *cxzkmr *fkh *vpvj *llgsg *pgb *cmnb *ncqdr *qchnn *rknm *xjzc *zntrfp *mstc *clqk *gsgmdn *jnr *ljhn *mppf *hkqp *xlnn *xgbvk *csfmx *rpmmv *fmvvb *mjpt *zlgztsbd *dtlhh *dln *bnzq *klmjmz *tfmgl *vgp *qmmt *kglr *dbx *gzgvdh *rcvd *kmsh *rgdx *kqzcj *ttxx *tzjnvp *qmthj *zfsks *lh *vhcnpg *pgqxp *zhghprj *vht *rxr *vbqbkt *pcf *gtgrcf *zzldmh *dvcfx
["dairy", "wheat", "peanuts"]: zrgzf mrfxh hlmvqh zmb ckqq thvm qrsczjv *vfkpj *kbtx *qkgqv *bkd *srgnx *rcr *zdntns *tjsdp *kfsfn *rhrc *mstc *vtljml *zlgztsbd *rbvdt *glrc *qfvfzg *rkzhxmh *ddbmq *pbn *flhfddq *dfrg *kglr *clqk *rxrgtvs *cxzkmr *ddgdhg *cmnb *rpmmv *dln *zttx *pjln *pjqdmpm *jmgt *qdpbx *rcvd *rrbndl *vbqbkt *xmjlsn *lh *xhmmt *qmthj *nzlks *pgb *xzcdnr *mrxg *xgbvk *fkh *vgp *rqqfnlc *gjqfj *gsgmdn *tbm *szsbj *bxv *lxr *cnghsg *jfqqgtl *dbx *pmtfmv *lvjpp *xjzc *xlnn *dtlhh *dsmc *vnfmc *zkzdrn *ghr *fhtsl
["dairy", "sesame"]: zmb jmdg hlmvqh thvm ckqq qrsczjv mrfxh *nldzpc *pbn *rxr *vgp *pgqxp *zfsks *vfkpj *tvqbhv *qmmt *pjln *qfkjsq *hnmjfl *mrxg *dln *nqfc *lbfgp *rcr *kfsfn *vtljml *rxrgtvs *tbm *dsmc *hkqp *lh *jngghk *vbqbkt *fbcds *clqk *pjqdmpm *mppf *tzjnvp *xhmmt *csfmx *rpcdfph *sdccxkt *kbtx *knqzf *rkzhxmh *mszc *ttxx *klx *mnvq
["wheat", "peanuts"]: ckqq hlmvqh zmb zrgzf mrfxh jmdg qrsczjv *rgdx *tfmgl *gmc *fstgc *ltvr *pnglkx *kglr *hkqp *ddgdhg *qfkjsq *xzcdnr *jnr *xxfgvz *zhghprj *ghr *pfqxsxd *ljmvpp *cmnb *nldzpc *dznd *xlnn *lh *zfcvnj *dcbk *kmsh *xjrpr *qjsbk *nzlks *gtgrcf *kfsfn *dpfphd *rqqfnlc *mppf *zzldmh *thcs *cbbkfx *jmgt *rcr *pjln *jxjqp *fmvvb *pmvl *mgxzl *knqzf *rbvdt *gzgvdh *nqfc *vnmfg *qszmzsh *tjsdp *ljhn *qrftr *ddbmq *bkd *fbcds
["peanuts"]: mrfxh zrgzf hlmvqh thvm zmb qrsczjv jmdg *clqk *rpmmv *rkzhxmh *pbn *pmvl *hkxcb *mvnqdh *kbtx *tzjnvp *ncqdr *kmsh *dcbk *qchnn *bkd *kqzcj *cmnb *mjpt *knnmm *pzxj *frld *gsgmdn *pfqxsxd *ltvr *lqmfgp *fkh *rbvdt *vgjbgj *nldzpc *jgtrnm *dbx *qrftr *zdntns *lbskg *rpcdfph *djpsmd *vbqbkt *dsmc *jdtzr *qmthj *hnmjfl *sfk *mppf *fmvvb *rcr *xmjlsn *csfmx *dln *vqrjn *xbpb *stcsp *fdf *rxrgtvs *mstc *ljhn *npbnj *thcs *ddbmq *knqzf *dgrrm *rqqfnlc *mszc *jnr *lbfgp *qsgb *dtlhh *pgb *bcvmz *qszmzsh *rfh *gjqfj *xlzqfb *rxr
["soy", "wheat", "eggs"]: thvm zrgzf jmdg zmb ckqq hlmvqh mrfxh *clqk *csfmx *lvjpp *kqzcj *zntrfp *dcbk *ghr *vtljml *pfqxsxd *pjqdmpm *jgtrnm *flhfddq *zzldmh *llgsg *nthhxn *mjpt *pjln *dznd *mnvq *bjvcg *nfnzx *tzjnvp *vgp *dtlhh *qmmt *rpmmv *zfcvnj *xzcdnr *tbm *dbx *bxv *cxzkmr *tfmgl *mszc *ttxx *qkgqv *qjsbk *pgqxp *zfml *mhrm *vpvj *jdtzr *mgxzl *tvqbhv *qfvfzg *vhcnpg *lbskg *lqmfgp *cnghsg *rcvd *hnmjfl *zhghprj *xjrpr *xxfgvz *dln *gtgrcf *sdccxkt *kx *qspfqb *jfqqgtl *pptgt *dmxhhd *rpcdfph *fstgc *rcr *fmvvb *ljmvpp *mrxg *gmc *pgb *kmsh *cmnb
["peanuts", "eggs", "nuts"]: hlmvqh qrsczjv ckqq zrgzf zmb jmdg mrfxh *klx *nggcjr *xjrpr *zdntns *kltcm *vhcnpg *xlnn *kqzcj *dnpgcd *vht *rpmmv *bnzq *hnmjfl *lbskg *fdf *bkd *dgrrm *rvchbn *mgxzl *pgb *jdtzr *dcbk *qszmzsh *rpmqq *hrfmdk *qrftr *dpfphd *lxr *ngqh *xddkbd *tbm *vqrjn *qchnn *vpvj *mstc *pbn *jxjqp *jgtrnm *tfmgl *rqqfnlc *xmjlsn *rxr *pmtfmv *zmcj *zfsks *zqsc *crnfzr *fbcds *xgbvk *hkxcb *gmc *nldzpc *nfnzx *xnfhq
["dairy", "sesame", "eggs"]: thvm zmb jmdg mrfxh zrgzf ckqq hlmvqh *csfmx *zzldmh *dcbk *fdf *rhrc *fjgxv *qchnn *cxzkmr *qmthj *crnfzr *nqfc *zmcj *mhrm *ltvr *sdccxkt *flhfddq *cbbkfx *cmnb *qdpbx *xmjlsn *fhtsl *knqzf *bxv *nggcjr *vnmfg *cxfzhj *jdtzr *pnglkx *lxr *kmsh *vgjbgj *dln *mppf *gzgvdh *rpmmv *zntrfp *pgqxp *zfml *vnfmc *vht *pmvl *xlzqfb *rxrgtvs *kltcm *pzxj *dsmc *dtlhh *hrfmdk *qmmt *dnpgcd *bjvcg *gsgmdn *cnghsg *xhmmt *gmc *ttxx *qjsbk *fkh *vhqfz *xxfgvz
["peanuts"]: ckqq jmdg mrfxh zmb hlmvqh thvm zrgzf *jmgt *mppf *ttxx *dsmc *xnfhq *bxv *kglr *bcvmz *dfrg *jnr *mnvq *ngqh *sfk *fdf *xhmmt *fjgxv *zfcvnj *rczbvg *cmnb *xjrpr *szsbj *dvcfx *gtgrcf *knqzf *pjln *lbfgp *vnmfg *jdtzr *mhrm *fstgc *tbm *djpsmd *pnglkx *qkgqv *vfkpj *hkxcb *qfkjsq *pgqxp *xzcdnr *nfnzx *npbnj *rbvdt *jfqqgtl *qfvfzg *jvvmcq *hnmjfl *rgdx *gjqfj *zhghprj *kqzcj *rcr *tvqbhv *tshn
["dairy", "sesame"]: qrsczjv zrgzf thvm ckqq hlmvqh mrfxh zmb *rknm *lvjpp *cnghsg *sdccxkt *rcvd *rxrgtvs *stcsp *fstgc *ttxx *pmvl *rpcdfph *dznd *pptgt *mstc *rpmmv *fdf *knnmm *jnr *bjvcg *mnvq *qdpbx *zfml *rqqfnlc *zqsc *zhghprj *mgxzl *qmmt *fkh *rxr *dsmc *lbskg *sfk *xhmmt *kqzcj *vfkpj *mhrm *pcf *jmgt *ljmvpp *jfqqgtl *szsbj *xjrpr *vnfmc *qszmzsh *dbx *mszc *xlnn *qrftr *qchnn *mjpt *zttx *ddgdhg *gmc *djpsmd *zfcvnj *dln *qkgqv *rcr *dnpgcd *tzjnvp *hkxcb *zmcj *lxr *bcvmz *fhtsl *vnmfg *vpgvm
["sesame", "dairy", "shellfish"]: jmdg thvm mrfxh zmb ckqq qrsczjv zrgzf *rgdx *cmnb *fstgc *pfqxsxd *ncqdr *dmxhhd *glrc *xjrpr *rkzhxmh *fhtsl *hkxcb *pmtfmv *zfsks *knnmm *pgb *vnmfg *thcs *dfrg *ddbmq *clqk *zntrfp *nthhxn *xjzc *dgrrm *lvjpp *rpmmv *vht *lh *jfqqgtl *vgp *mszc *rczbvg *jnr *jngghk *xhmmt *vhqfz *bcvmz *tjsdp *bkd *xlzqfb *xddkbd *pmvl *ddgdhg *djpsmd *ttxx *zfcvnj *mjpt *nldzpc *qrftr *kx *xnfhq *fjgxv *jmgt *ljhn *mrxg *pbn *sdccxkt *rxrgtvs *dln *dpfphd *tbm *rfh *tvqbhv
["eggs"]: zmb thvm jmdg hlmvqh mrfxh zrgzf ckqq *rczbvg *cxfzhj *lxr *mgxzl *hkxcb *kbtx *jvvmcq *pmtfmv *jfqqgtl *jxjqp *mszc *rknm *vfkpj *qmmt *ltvr *cnghsg *pjln *gzgvdh *szsbj *pgb *dcbk *lvjpp *qchnn *bcvmz *sdccxkt *llgsg *xgbvk *mrxg *ghr *zhghprj *hkqp *thcs *zzldmh *frld *gtgrcf *pnglkx *clqk *kglr *xhmmt *hnmjfl *qjsbk *qfvfzg *dnpgcd *dbx *djpsmd *qrftr *rgdx *tvqbhv *ncqdr
["shellfish"]: zmb zrgzf jmdg hlmvqh qrsczjv mrfxh ckqq *pmvl *rxrgtvs *mvnqdh *dznd *srgnx *qmmt *pgb *dgrrm *xjdhk *klx *rcvd *cnghsg *ttxx *hrfmdk *qspfqb *pfqxsxd *fmvvb *pzxj *sfk *rbvdt *nggcjr *zqsc *npbnj *kglr *xddkbd *lbskg *lqmfgp *mrxg *zfml *rkzhxmh *jfqqgtl *vgjbgj *rpmmv *tphtz *mszc *dln *zfcvnj *vpgvm *tzjnvp *rhrc *nldzpc *rknm *tshn *jgtrnm *mppf *fjgxv *ddgdhg *vpvj *fbcds
["nuts", "sesame"]: jmdg thvm mrfxh zmb ckqq zrgzf qrsczjv *xlzqfb *nthhxn *dln *rczbvg *vgp *cbbkfx *gsgmdn *jvvmcq *glrc *klmjmz *stcsp *bcvmz *dbx *vpvj *cmnb *sjgx *rfh *rrbndl *mgxzl *jnr *rhrc *xlnn *mhrm *bxv *qrftr *lvjpp *fjgxv *kglr *cxfzhj *pptgt *ghr *kbtx *pnglkx *qjsbk *jfqqgtl *fstgc *dznd *qszmzsh *jgtrnm *tjsdp *klx *pjln *vgjbgj *vbqbkt *zkzdrn *sfk *vhqfz *hrfmdk *kltcm *vnfmc *zqsc *xhmmt *knnmm *qfvfzg *xjrpr *nqfc *jkbqk
["shellfish", "peanuts"]: ckqq zmb thvm mrfxh hlmvqh zrgzf qrsczjv *jgtrnm *bxv *fbcds *dznd *bkd *ttxx *rpmqq *pmvl *dtlhh *xjdhk *zdntns *knnmm *vqrjn *dsmc *lqmfgp *ltvr *jfqqgtl *mszc *xhmmt *szsbj *crnfzr *fkh *rbvdt *pjqdmpm *nggcjr *qrftr *bcvmz *qmmt *srgnx *xddkbd *rvchbn *cmnb *pptgt *xjzc *llgsg *rxr *bnzq *gsgmdn *zzldmh *rcvd *dgrrm *zfsks *qsgb *tvqbhv *zkzdrn *nzlks *lh *klmjmz *rxrgtvs *kqzcj *mnvq *ngqh *rczbvg *tshn *tjsdp *pcf *fdf *rfh *pnglkx *hkqp *jkbqk *sdccxkt *fstgc *vpvj *ddbmq *zttx *xlzqfb *qfvfzg *frld *zlgztsbd *xnfhq *pfqxsxd *cxfzhj *cxzkmr *tphtz *clqk
["nuts"]: zrgzf thvm hlmvqh qrsczjv mrfxh ckqq jmdg *hrfmdk *nthhxn *lh *rbvdt *qdpbx *mhrm *vhqfz *lqmfgp *qjsbk *vgp *qfvfzg *szsbj *nldzpc *vpgvm *sdccxkt *dgrrm *tfmgl *zdntns *ddgdhg *zfsks *zmcj *pnglkx *ncqdr *sfk *rqqfnlc *vht *mstc *pmvl *cmnb *gmc *thcs *bjvcg *nzlks *klx *jfqqgtl *fkh *ghr *ddbmq *htllnq *xlnn *kglr
["eggs", "nuts", "dairy"]: mrfxh qrsczjv hlmvqh jmdg thvm zrgzf zmb *fkh *knqzf *tvqbhv *hkqp *nqfc *mvnqdh *xxfgvz *gzgvdh *vnfmc *qrftr *ngqh *cxzkmr *mjpt *dvcfx *zmcj *xddkbd *clqk *rvchbn *dsmc *xjzc *pfqxsxd *dfrg *qmmt *mhrm *flhfddq *rrbndl *xnfhq *dznd *frld *jnr *djpsmd *qjsbk *ddbmq *qchnn *pnglkx *dtlhh *zhghprj *fhtsl *vtljml *nzlks *qszmzsh *lqmfgp *pbn *cmnb *rpcdfph *kx *qkgqv *tshn *zlgztsbd *xlnn
["eggs"]: mrfxh zrgzf thvm qrsczjv jmdg zmb hlmvqh *gsgmdn *zqsc *cxzkmr *xlnn *htllnq *vbqbkt *pgb *pnglkx *tphtz *jmgt *qkgqv *pjqdmpm *glrc *sdccxkt *rbvdt *vht *pzxj *fstgc *bcvmz *mjpt *dvcfx *vpvj *ljmvpp *pfqxsxd *tshn *zmcj *qmmt *pcf *dpfphd *xxfgvz *jxjqp *rczbvg *mgxzl *fjgxv *hnmjfl *rkzhxmh *cnghsg *zfml *gjqfj *tbm *lh *mppf *dcbk *zntrfp *dbx *jvvmcq *szsbj *pjln *xhmmt *rcr *nthhxn *kx *fmvvb *xzcdnr *klx *rpcdfph *djpsmd *jdtzr *mnvq *bjvcg *mrxg
["peanuts", "eggs", "soy"]: thvm mrfxh zmb hlmvqh jmdg ckqq qrsczjv *vqrjn *rhrc *pzxj *pjqdmpm *tshn *pjln *nggcjr *ljhn *fkh *qchnn *kfsfn *vgjbgj *jmgt *qkgqv *stcsp *knnmm *dznd *pgb *csfmx *fmvvb *ltvr *rknm *rpcdfph *qfvfzg *zfcvnj *clqk *kx *ghr *rpmmv *vbqbkt *tfmgl *dfrg *lxr *hrfmdk *vpgvm *zlgztsbd *rczbvg *tvqbhv *jnr *qjsbk *qfkjsq *xxfgvz *klx *dnpgcd *kbtx *flhfddq *jfqqgtl *ddrd *xgbvk *rqqfnlc *bnzq *mnvq *ncqdr *dln *qdpbx *kltcm *mppf *zttx *dbx *pmtfmv *klmjmz *vnmfg *pgqxp *nthhxn *crnfzr *dmxhhd *xhmmt *rgdx *mvnqdh *gsgmdn *nzlks *xzcdnr *fbcds *djpsmd *zfsks *dpfphd *lh *ddbmq *vfkpj *vgp
["shellfish", "dairy", "nuts"]: hlmvqh zmb thvm ckqq qrsczjv mrfxh jmdg *dsmc *rqqfnlc *dgrrm *lbskg *xxfgvz *klmjmz *jmgt *jnr *dznd *npbnj *rrbndl *fkh *vfkpj *dvcfx *hnmjfl *qrftr *pmtfmv *kltcm *xzcdnr *gtgrcf *lbfgp *bcvmz *xddkbd *vgjbgj *gjqfj *kglr *qchnn *zlgztsbd *rcvd *xmjlsn *bnzq *kbtx *vnfmc *srgnx *pptgt *llgsg *cbbkfx *cnghsg *xjzc *rbvdt *mnvq *mppf *rknm *tzjnvp *rfh *vgp *vpvj *nfnzx *hkxcb *zqsc *lqmfgp *kmsh *dnpgcd *sjgx *sfk *gmc *jfqqgtl *ltvr *vpgvm *pmvl *qmthj *klx *tbm *rvchbn *pfqxsxd *xjdhk *glrc *rczbvg *knqzf
["peanuts", "shellfish"]: qrsczjv mrfxh ckqq zrgzf thvm zmb hlmvqh *ngqh *lxr *qrftr *nldzpc *cbbkfx *zdntns *xxfgvz *srgnx *qspfqb *zfsks *tzjnvp *tphtz *lbfgp *gjqfj *xjrpr *qfkjsq *rfh *xgbvk *dtlhh *xjdhk *qkgqv *hkqp *dsmc *rczbvg *klmjmz *xlzqfb *ddgdhg *kltcm *vhqfz *kglr *jxjqp *xddkbd *htllnq *gtgrcf *lbskg *gmc *szsbj *zfcvnj *pjqdmpm
["peanuts", "eggs", "dairy"]: jmdg ckqq qrsczjv zmb hlmvqh thvm zrgzf *xlzqfb *vpgvm *flhfddq *kbtx *zmcj *vhqfz *tphtz *vqrjn *stcsp *rgdx *nfnzx *nggcjr *xmjlsn *pgb *ngqh *pjqdmpm *qsgb *nldzpc *hkxcb *klmjmz *rpmmv *xjrpr *zlgztsbd *ncqdr *rpcdfph *qjsbk *gzgvdh *xnfhq *cbbkfx *knnmm *qfkjsq *xddkbd *vgp *pmtfmv *qdpbx *cnghsg *hrfmdk *fjgxv *xlnn *xjzc *mszc *ljmvpp *zntrfp *fdf *pcf *mnvq *bkd *fbcds *dbx *fstgc *dln *pfqxsxd *mhrm *pbn *zttx *zhghprj
["sesame"]: jmdg zmb qrsczjv hlmvqh zrgzf thvm mrfxh *nldzpc *gmc *mjpt *knqzf *rbvdt *zntrfp *nthhxn *rxr *xzcdnr *kx *ljmvpp *kltcm *jmgt *gjqfj *pgqxp *xjrpr *dbx *dmxhhd *pnglkx *gsgmdn *vhcnpg *xjzc *pjqdmpm *rpcdfph *lbfgp *xgbvk *jvvmcq *qdpbx *nqfc *dvcfx *rknm *kbtx *npbnj *mrxg *klmjmz *rrbndl *xbpb *ncqdr *fdf *vpvj *kglr *pptgt
["shellfish", "nuts"]: ckqq jmdg mrfxh zrgzf thvm zmb qrsczjv *tshn *dmxhhd *qmthj *kqzcj *rqqfnlc *pcf *dgrrm *hkqp *flhfddq *qmmt *thcs *vqrjn *vht *tbm *lqmfgp *bcvmz *fbcds *rbvdt *xzcdnr *xlzqfb *vfkpj *sdccxkt *fstgc *fhtsl *qfvfzg *kmsh *dznd *bxv *glrc *pmtfmv *rkzhxmh *zqsc *xjzc *fmvvb *ddbmq *qspfqb *tjsdp *rcvd *xgbvk *gzgvdh *cmnb *pptgt *ngqh *xlnn *sjgx *mrxg *qdpbx *rknm *hnmjfl *szsbj *zntrfp *gtgrcf *fdf *kltcm *vhcnpg *pjln *mppf *dnpgcd *ttxx *srgnx *qszmzsh
removing ("dairy", "thvm")
removing ("sesame", "zmb")
removing ("peanuts", "hlmvqh")
removing ("wheat", "zrgzf")
removing ("eggs", "jmdg")
removing ("soy", "ckqq")
removing ("nuts", "qrsczjv")
removing ("shellfish", "mrfxh")
Day 21 - Part 2: thvm,jmdg,qrsczjv,hlmvqh,zmb,mrfxh,ckqq,zrgzf
generator: 358.788µs,
runner: 1.783195ms
Day 22 - Part 1: 32033
generator: 120ns,
runner: 7.289µs
``` ```

561
2020/input/2020/day19.txt Normal file
View File

@@ -0,0 +1,561 @@
102: 100 47 | 76 84
23: 60 47 | 73 84
132: 17 47 | 81 84
108: 55 100
18: 116 47 | 26 84
103: 84 115 | 47 81
65: 84 113 | 47 50
128: 107 47 | 125 84
14: 84 100 | 47 107
118: 47 17 | 84 57
2: 47 100 | 84 40
28: 63 84 | 74 47
22: 102 84 | 123 47
123: 84 74
19: 3 47 | 13 84
24: 74 47 | 81 84
115: 55 55
90: 92 47 | 44 84
48: 84 94 | 47 96
109: 17 84 | 100 47
92: 84 75 | 47 108
66: 38 47 | 125 84
83: 66 47 | 108 84
31: 121 84 | 77 47
29: 47 61 | 84 111
45: 47 47 | 47 84
59: 47 49 | 84 43
37: 47 30 | 84 95
36: 107 84 | 125 47
82: 74 84 | 38 47
61: 84 10 | 47 110
79: 47 28 | 84 109
33: 101 47 | 133 84
12: 45 47 | 63 84
91: 122 84 | 93 47
122: 65 47 | 52 84
21: 57 84 | 115 47
8: 42
67: 102 47 | 64 84
39: 113 84 | 81 47
41: 84 124 | 47 10
50: 47 47 | 84 84
17: 47 84 | 84 84
120: 98 84 | 78 47
113: 55 47 | 47 84
20: 84 128 | 47 104
7: 84 1 | 47 20
51: 84 113 | 47 81
56: 84 83 | 47 69
131: 84 127 | 47 97
0: 8 11
5: 47 63 | 84 125
94: 15 84 | 127 47
121: 99 47 | 27 84
119: 47 115 | 84 57
129: 47 80 | 84 131
15: 47 100 | 84 45
35: 84 50 | 47 76
95: 47 115 | 84 107
68: 127 84 | 51 47
124: 84 107
75: 50 55
57: 47 84 | 84 55
13: 47 33 | 84 129
53: 106 47 | 59 84
106: 16 84 | 118 47
89: 84 125 | 47 45
104: 45 84 | 76 47
99: 47 56 | 84 7
78: 84 74 | 47 81
64: 17 47 | 115 84
32: 50 84 | 40 47
1: 47 24 | 84 72
47: "a"
80: 114 47 | 109 84
88: 47 119 | 84 132
105: 47 125 | 84 100
6: 68 84 | 67 47
110: 76 84 | 63 47
38: 84 84 | 84 47
49: 47 63 | 84 76
26: 55 107
81: 47 84
74: 84 47
96: 84 89 | 47 117
77: 47 86 | 84 71
135: 32 84 | 2 47
133: 47 15 | 84 128
42: 19 84 | 62 47
30: 47 100 | 84 74
27: 6 47 | 91 84
63: 84 55 | 47 47
62: 84 87 | 47 23
76: 84 84
4: 84 135 | 47 54
60: 41 47 | 37 84
100: 47 47 | 84 47
85: 47 112 | 84 18
116: 125 84 | 63 47
134: 57 47 | 115 84
34: 52 47 | 25 84
40: 47 47
111: 58 84 | 126 47
3: 29 47 | 130 84
114: 17 84 | 107 47
52: 47 45 | 84 74
10: 47 100 | 84 81
98: 47 76 | 84 100
112: 84 82 | 47 103
72: 40 47 | 45 84
126: 50 84 | 113 47
107: 84 47 | 47 84
11: 42 31
55: 84 | 47
54: 12 84 | 5 47
130: 34 47 | 70 84
84: "b"
127: 81 47 | 17 84
87: 84 53 | 47 9
101: 105 84 | 14 47
9: 88 84 | 120 47
73: 47 79 | 84 22
97: 74 84 | 50 47
117: 74 47
70: 47 134 | 84 46
58: 47 50 | 84 115
125: 47 47 | 55 84
46: 47 81 | 84 17
86: 84 90 | 47 85
25: 38 84 | 63 47
69: 39 47 | 78 84
43: 47 100 | 84 125
93: 84 66 | 47 35
44: 47 21 | 84 36
16: 57 47 | 107 84
71: 48 84 | 4 47
babaaabbbababababbbbabbaabbaabaa
babaaaabaaaaababbbbaaaaa
abbabaabbaaabababaabbbbabbbbbaabbbbabababaaaabbbbababbbb
bbbabababbabbbabbbabbbbb
babaabbbababbbabaabaaaaa
abbabaabbaababbabababbbababbbabbabbabbbabbaabbbb
aaaaabaabbbbbaabbbbbbbbbbaaabbaaabbaabab
baababbabbbabbaaaaaababbaabbababbbabbbbb
aaabaaaabbabbbabbabaabbbabaabbbbaaaaabaaaabaabaaababaabbabbaaaabbbbaabbabbabaaaaaaaabaab
ababaaabababbbababaaabab
bbbbabbbbbaabaaaaaabbbbbbabbbabaabbaaababbbaaaaababaabaabaabababbabbbabbabaaabbaaabbaaaa
babaabaaababaaabaaaababa
aabaaabbaabbbabbabaabaab
bbbaabaaaabaaabbbaaabbbabbbaaabb
aaaaaaabaaababbbbbbbbbbbbaaabaabbaaabbab
bbabbabbaaaaabababaababa
babbababbbabbaababaababbaaaaabaaabbbabba
bbbbbbbababbaaaaabaaabbaabbaaaab
bbbbbaaabbbbbaaaaaabaaaabbbaaabb
babbababaababbbbbbbaaabb
abaabbaabbababaabbababba
abaaabbaaabaabbbabababba
babaaaabaaaababbabbbbaaa
bbbbbbbabaababbaaaaababbabbaabbabbbaabaababaabbbbbbaabab
aaabbabbbaabababbaabaaba
bbbababbabaabbabbbabaaaa
baabbabababaaaabbbbbbaab
bbabbbbabaababbabbbaabab
abaabbabbbabbabbabbbabba
bbbbbbbaaababaaabbaabbbabbaaabbbbabababb
aabbaaabbabbabaaaabbabaababbbaababaabababaaabbaa
aaabaababbbabbbbaaababbbbaaabbbb
aaaaaaaaaaabaaaababbabbb
bbbabbbbaabaababaabbabab
baaabaabbaaaabbbbaaaaaaa
bbbbbbbaabbabbaabaabaaaa
aaaaabaabbabbaaaaaaaaabb
aabaaabbaabbabaaabbabaabbaababaaabbbaaaaababbaabaaabbaaabbaaabaa
bababbbaaabaababbbababaabbaabaabbaaaabbabbaabababbbabbbababbabbb
abbbaababbaabaaaaababbbaaaabbbaa
aababbbaaaabaabbbbabaaaa
aaaaabbaaabaaabbbababaaa
bbbababaaabaaaabbabbabaabbababababababbbabbaaaaabbababbabbbbabbbabbbaabb
bbbabababbbabababababbbb
bbaaababbbabbbbaabbbbbaa
bbababaabaaaabbaabbbbaaa
bbbbabbababbbbaabbaaaababbababbaabaaabababbabbabbbbbbaababbbbabbbbaaaaabbbaabbba
abbabbabbbbbbaabaaaaabababaaaaabaaabbaaaabababba
bbbabaabaababaaabaabbaaa
bbababbbbaaababaaaabbabbaaabbbaa
aabbbbababaabbaabababbaa
aaabbabbbaabbbabbbbbbbbabaaaabbaaabababaabaaabab
aaaaaaababbabbabbabaaaaa
aababaaaaaababbbabbabbabaaababbbbbabbababababaaaabbabbbb
babaabbbbaaabaaabbbabbab
bbbbabbbbaabbbabbbaabbbaabbbbbaabbbbaaabbbbaabbbbaababbaaaabaaaabbabbabbabbaabbb
aaabbbabbaaabaabbaaaaabaabababab
abbababbabbbbbabbaabbbabaaababbbbbbbabaababbbbbabababbbb
bbaabbbaaaaababaaabaaaabbbbbbaabbaaaabbaabaaabaabaaaabbabbabbbaabbaaaaaa
abbabbaaaabaaaabbbbbbaabbabaababbbbabbba
bbaaaabaabbababbbbaabbaa
aabbaabaabbaaabbaaabaaaaaaababbabababbaa
baaaabbaaaaaabbbbabbababbaabbbbabbabbabbaabbaabb
babbaaaabbaabaaabbbbaaaabbbabbaaaaaaaabb
aaaaababaaabbabbababbabb
abbabaaaaaabaababbabaaab
aaabaababbaabbbaababbabb
babbabaabaababbabbabaabb
abbabbaabbabbbabababaaaa
bbabbbaaaababaaaaaabbbaa
bbbbbbbaaaaaabbabbbaabaaaaabbaaa
bbbaabaababaaabbaababbabaababaabbbababba
bbaaabbaabaabbbbbbbaababbbaabaabaaabaababaaaaabbbaaabaababaaaaabaabbbbaabaabbbaa
baabbababbaaaaababaabbabaabbbaabaabbaabbabbbaaababbaaaab
bbabaaaaaaaabababaabbababbaabbbbabbbaaababbaababaabaaaaaaaabaabb
baaaaaabbaababbaababaaaa
bbbabbbbbbaabaabbaaabbab
babbbabababaaaabaabbaaabbbabaabababbbaaabaababbbbbaababbbabbbabb
aabaaababababababaabbbababbababbbabbaabb
bbaabaaabbaabababbaababaabbabbba
bbbabaaaababaabbaabbabbbbabbaabaabbabaabbaabaabaabbaabbabaaabaaa
abbaaabbbbbbbbbbaaabbaab
baabbbbbaabbaabbaabbababbaabaaba
baaaabaaabbbbaabaabbabbbbaababbb
abbbbbbaabbbbbbbbbbbbaaaaaaabaaa
abbbbbbbbbabbbaabbbaaabaaabababa
aababbbaabbabaabbabaaaba
bbabbaabbabbabaaababbbba
aaabbbabbaabaabbbbbabbbbaaaaabbbbabbbabababbbaaa
aaabaabbaabaababaabababb
bbababaaabbbaabaabbababa
baabbbaaaaababababaabbaababbabbb
babbbaabbaaaabbaababbabb
bbababbbababbbaabbabbbabaabababaaabaaaaa
babbbbbbbbabbbababbbbaab
abaabbbbbabbbbbbaaabbaba
bbabbbaabbbbbaaabbbaaaaa
abbbbbbbbaabbbaaabbbbbbabaaaabaaaaaabbbb
aabaaabababbbbbbaaabbaab
bbbabababbbbbbabbbbbaabaabababbaaabbbbbb
aababbbaaaaaaaaaabbaaaaa
ababaababaababbbabbbbabaaabbabaaabbabbaabbaaaaaababaabba
aabbaaabaabbbaabaabaabbbaaabaaab
aabbaaabaaaaabaaaaabbbabaaabaaaababaaaaaabbbbbaaaababbaa
babbbaabaabaaabababbabaababbbaabbabaabbaabababbababaaaaa
aabbbbabababbbaaaaabaabbbaabbabaaaabababaabaaaabaaaababaabbbabbaabaaabbb
bbbbbbababbbabaababbabaabababababaababbabbbbbbbabbaaabbb
bbabababaaababbabbababba
abbbbbbabbbbbbaaabbbaabbbbabaabaaaaaaabb
aaaaabbbbaaaabbabbbabbab
aabbaaabbbbaaaabbabababbbabbaabbbbababbbbaaabbbababaabbbaabaaaaababbbaaa
ababbbabbbabbbaaababbbbbaabbabbaababbaaa
abbabbababbababbbbbbabbb
aabbaabaabbabbabbaabbaab
baabbbaaabbababbabbaaaba
baaabbbaaabbbabbbaaaaaaa
bbaaababaaaaabaabaaaabba
aabaaabbbbabbaabaaababaabbbbaabb
bbbbabbaaaabbabbaabbabab
aabaaaabbaaaaabababbabba
bababbbabaabaabbaaaabaab
ababaaabbbaabaabbbaabaaababaabbbabaabbaaaabbbaaabbbaabab
aababaaabbbbaaaaaaabbbbb
abaabbaabbbbbaaaaaaabaaa
babbbabababbaaaabaaaabab
abbbbbabbabbaaaababbaabb
bbaaaaabbbbababaaaaabaab
bbaababaaaabaabbabaabaab
bbababbaabbbbabbbaaaaabbabababba
bbabbaabbbbbabbaabababbbaabbbbbabaabbaaabbbabbbabaabbaab
abbabbaabbaaaaabbbabbbaabbbabaaabbaaabbbaaabaaab
aaababbababbabaabaabbbababbabbabbbaababaabbbabbaabaababa
baabbaabbbabbababbaaaaaabaaabbab
aabbabaabbbbbbbbbaabaaababaaaaaa
abbaabbabaaaaabaabbbabaabaaabaabaabaabbbaabaabaaaabaaaaa
baaaabbabaababbababbbababababbbb
bbabbaabbaaabbbabaaabaababbbbbbabbaaabaa
baabbbbaabbbbbbabaabbaab
baaaabbaabbababbaababbababaaaabbbbbbbabababaaaba
baabbbbbaabaabbbbbabbaaaabbaabbaabbbbbabbbbbbaba
babaabbbbbaabaaaabaababbabbbbabbbbbaaaaa
baabbababbaababaabbbaaab
bbaaaabbbaaaaaabbbabababbaabbabbbaaabbaaababaabb
abbbbbbaaababaaababbaaba
baabbabababababaaaaaababbababbbabaabbbaaabaaabab
aaaaababaabaabababbbbbbbabbbaaba
bababaaabbbaabbabaaaaabb
aabbaababbabbbbabbbaaaab
bbbbbbbbaabbbabbbabbbbba
aabaababbaabaabbbbaaaaababaaaaabbaaaaaaa
aaaaaaaaaaaaabababbbbbbabbbaabab
bbbaabaaababbbaaaabaaababbababbbabaaabbaabaaaaaa
ababbabbbbbbaabbaaabbaaabbaaabbaaaabbbba
baabababbbbbabaaababbbaabbaaababbbbaaaababbabbbb
bbaabbbaabaaabaaababaabb
bbabbbaaabbaabbbaaaabbaa
bbbabaabaaaaabaaaababaaaabaaabaaaaaaabbaabbaabbabbbbbaba
baaaabbaabbbaabaabbabbaabbbaaabaaabbbbbaaaaabaab
bbabbabbbbbbbaabbbababbbbbaabaaaaaabbaaa
abbbbbbbabaaabbbabbaaaabaaabababaabaabababbbaaaaabaaaababbababbabbbbabbb
baabbabaababbbaabbababba
bbaabbbaaaabbbbaaabaabaa
baabbabaabbbbbabaaaaabaababbbbaaabaaaaaa
baaabaaabbbababbababaaabaababbaa
aaababbabbaaaaabbaabababbbabaaba
aabbbaabaabbaaababbbaabb
bbbbbbbbbaabababaabaabaa
ababbaaaaabbbbbaaaabbaabbaaabaaabaabbaabbabbbababbbbabbabaaaaaababaaaaba
baaaaabaaaaaababaabbaaaa
aaaaaaaabbabababaaaabbaa
aababaaaababbbaabbbaaaaa
aaaaaaabbbaaabababbbaaab
aaababaaaabbbbababbaaaab
aaababaabaaaabbaabbaabab
bbaabaaaaaabaabbbabaaabbababaaba
ababaaabbaaaabbabbaabaaaabbababbaababaaababaabbbbabbabbb
aaaaaaabaaababbbbbaaaabbbbabaaaabaaabbabbaabbbab
abbabaaaabaaabbabbabbaaaababbbbbbbbaaaaa
abaaaaababbbbbababbbbaba
abaabaaaaabbbbaaaaaabaab
babababaaababaaaabaababa
bbbaaaaabbbbbbaaaabbaabb
aababaaaaaaaabaaabbbbaab
ababaaabababbbaaaaaabbab
baabbbabbbaabbbaabbbaabb
baabbbbaabbbaababbababba
bbbbabaaaaaababbbaababaa
aaaaabbabbbaabbaabaabbbaaabababababbbbba
baabaaabbbaabaabababaabb
aaabaaaaabbabbaabaabaaaa
aaabaabaabbabbabbabaabab
babaabbbbaabbbbbabaaabbabbaabaaabbababbababbbaaaababaabb
baaabaaababbabababbaaabbbaabaaabbaabaaaa
baaabaabbbababbbabbbbbabbabbaaab
abbabaaaaabbbbbababbaaaaaaaaababbabaababaabbbbbb
abbbbbbaabbbbaaababaabaaabbbbabbabbbbababbababbababaaaabbbaaaaba
aaabaabbabbbabaaabbaaaaa
bbbbaaabbbbabaaabaaabbbb
babbbaabbaabbbbbaaaabaaa
aaaaabaabaabaaabaabbaababbaababb
baababbbababbabbbbbbbaabaaaaabbababbbbbabaaaababbbbbbbbbbbaaaaabbabaaaabbababbab
baabaabababaababaaabbaaa
aababbabababaaababbabaaabbababbaabaababa
bbabbbabbabbbaababababba
abbaabbbaababaaaabbbabab
aaababbbabaabbbbbbbbabbb
aabbbbabbaaabaaaabbbaabb
abbbbbaabbbaabababaabaabababbaba
aaababaabbbbaaaababaaabbbaabbabbaaaabbaaababbaaa
bbaaaabaabbabaaaaabbaaabbbbabbab
aaabbababbbbababbbbbaaaababaaaaaababbaababaababbaababbbaaabbaaba
abbaabbbbabaabbbababbaab
baabbbbbbbaaabbbbababbbbbbaaaaaaabbbbbaaabaababa
aabbbbabbbbababbbabaaabbbabbbbbbbaaaabab
baabbbaabbabbbbababbbbaa
babbbbbbabbbbbbbaaabaabbbbbbbbbabbaaabaa
bbbabaaabbbbbaaaaaabbaab
abbbbbababaaabbaaababbbabbaaaaabaaaaabaabaaaaabb
bbabababaabbbaabaaabbbbabaaabbab
aaabbbbabbbbaaabbbbabbbbbbbbabbbaabababb
baaaabbaabbababbbabaaaaa
baababaabbaaaaabbababaabbbababbbababbbbabbabbaabbaaaabbabbaaabbbbbabbabbabbbabab
aaaaaaaaaabbbbababbbbabb
abbaaabbbaaaaaabbababaab
abaabbbbbaabbabaaaabababaabbababaaabbaab
aaaaabaabaababbaabbbbaba
bbbbbaaabbabababbaabbabaabaaaabaaabababb
aaaaabbaabbabaaaabbabbbabbbaaabbbaabaaaabbaaaaaa
aaabaaaaaaaaabbaaabaaabbbaabbbabaaaaabbbbabaaaaa
abaababbaababbbbaaabaaaabbbbbbbaabbaabaa
abaaabaabbbbbbabaabbbabbababaaba
bbabbaaabbaaaaababaaabbaaabbbabbbbbbabbaaabbabba
aaaaaaabbaababababaabbaababbaaaabaaabbab
bbbbbaaaaaababbbbaabbaab
abbaabbbbbaaaabbbbbbaaaabaabbabbaabbbaabbbaabbab
aaaabbbababaababbbbaababaababbaabbbabaababbbaabbbbaabbbaababbbaa
abbabbaaabbbaababbabaaab
aaaaaaababbaaabbbbaababb
baaabbaabaaabbaaabbbabba
babbbaabbbabbaabaabbaabaaabababa
aaaababbabababbbababaaabbbabaababbaababaaaabaabaabbabaaabbbaabaa
aaaaaaabaabbabaaabbabbaaaababbbbabbabaaabaaabaabaaaabbbaaabbbaaa
abbbbbbbbbbbabbabbbbaabb
baaabbbaabaababbaaabbaba
bbbbbbabbabbbabbaabaababbbbaabab
aaaaababbbbbabbbababbaabbbbbbabbaabbbbbbbbaaaaaa
ababaabbbababbbbbbbaaaabaabbbaaa
aaaababbbbbbabbabbaabbaa
aaabaababbbababbbabbabbb
bbababaaabaaabbaaabbaaaa
aaaaababbbaabbaaaaaaaabaabbbababbbbaabab
aabbaabbbabaabaabaaaaaaaabaababbbabbbbbaababbabbababaabaaabbbabbaabaabbaaabbbbba
bbbbaaaabbabababbbaaaaaa
abaaaaabaaaaaaabaabbaaabaaababaaaabaaaaa
babbbaabababaaabababbaab
baaaaaababababbbbaabababbbbbbaabbabaaaabaaaaaabaaababbaa
aabaaabbaababbabbabaabbbaababbabaabbbbaa
ababbbbbabbbaabababbaaba
bbababababbbaaaaabaabbabaaabbabb
bbaabaabaabbbaabbaaaaaabaabbabbbabbbbaab
baabaabbaababbbabbbbbaba
aaaaabababaaaaababababba
abababababbbabbbbababaaa
ababbbaabbabbbbabbbbbbaaabbbbabaabbabbba
babaaaaaaaabbaaabbbaabab
abaaababaaaabaaabaaaaaaabbabbbaaaababababaaaababaaaababbbbabaabbaabbbbba
aaababbbbaaaabbbaaaaaaabbbbabbbaaabbbbaa
babababaaaaababbabaabaab
bbaabbbababbabababaabaababbbbabaabbaaaaababbbbab
abababbbaabbbbababbbaaaaaaabaaab
aabaabaaaaaababaabbaaaabaabaaaaaaaababaa
aabbbaabbbbbabaababbabba
abbbaabaaaaaaaaababbbabbbbaaaababbbbbababbbaaaaa
aaabbbabbbbababbbbaabaabbaaaabab
aabbaababbabbbabbbbbbaba
abbaabbabbbbaaaaabaaaabbbaaababb
aaabababbbbbaaaabbbababb
abbbbbbbaaabaababbababababaabbbaabaabaaa
bbbabababaabbababaabbbbabaababaa
bbbabbabaaaabaaaaabbaaababababababababaaaaaabbbbaaaaabaabbaababb
aabaaabaaaaaaaababbabbbb
aabbabaabaabbabbaaabbbbaaabaabaa
bbaaaabbbbbabaaabababbbaaabaaababababaab
bbbbbbbaaabbbbbaaaaabbab
babaabbbbaaabaaabbbababbbbbaabaaabbbbaba
bbaaaabbbbbbaaaaabababaaaaabbaaabbbaabba
bbabbbababaabbbbaabaaabaaaabbaaa
baabaabbabaababbbbaabaabbaabbabbabbbbababbaaabbb
babbbabaabbbaababababbab
aabaaabbabaaaaabbbaaaabbaaabbaba
aaaaabaaabaabbbbaabbbbbb
aaaabbbabbababaabaabbbaabbbbbababababababbbaaabbaaabbabaaababbba
abaaaabbabbbbbabbbabbbababbaababbbaaabba
abababbbbaabbbbbbabbbbbbabbbbbabaaaababbababaabb
abaaabbabbababbbabaababbbaabbbbababbbaabbbaabbaa
babbbbbbbaabababbbababaaabbabbaabaabbabbaabbbaaa
aaababbababaaaabbbbaaaaa
babaaabbaabbbbbaaaaababa
aaabaaaaaabbaababaabbabababbaaaabbaabbaa
abaabbabbbaababaabbbaabababbabaabbaaaababbababaaabbbabbb
bbbbababbbaabaabbabaaabbaababbaaabaaabbb
baabbbabaaaaaaabbaabbaab
bbbaaabaaaababbbababaabbbbbbbaabbbbababb
babbaaaababbabbaabababbbababbbabaaababaa
aaabababaabbabaabbbabaaababbbbab
bbbbababbbabbbababbababbbaababaababaabba
bbbababababbbbbbabbbaaaaabaabbba
aabaaabbabbbbbaaabaababaabaaabab
bbabbabaabaaaaaababbbbaa
abaabaabaaaaabaabbbbbabababbabbbaabaabaa
bbabbbaababbbabbaabbaaabbabbabaabaaabaaababaabaabbbabbababbbbabbbabbabbabbaabbbb
aaaaabaababbababababbbbbaababbabbbabababbbbbabbb
abaaabbabbabbbaaaabababb
abbbbbababaaaaabbabaaaaa
bbbabbabaaabbaabbaaaabaababbaaab
bbbbbbbbabaabbaaaabbbaaa
baaabbbaaababbbbabbbabbbabaabaabaababaab
aaaababbbbaabbbaaaaababbbabbabba
bbabbbaaababaaabbbbbbbbabbaabaababbabbba
aaabababbabbbabaaabbabaaaaabbaba
aabaabbbbaabbbabaaabbbbabbbbabbb
bbbbbbabababaaababaabbbbaabbaaaabababbbb
abaaaabbaaabaabbbbaaababaaabbaabaabbbbbb
baabbababbbaaabaababbbba
baaabbbabababbbaabbaabab
babababaaaabaaaabbbbabbb
babbababaaabbbbabbbaabaabaabbbbbaaabbbab
baabbaabbababbababbaaaaa
bbababbbaaaaaaaabaabbbbaaaaabaaa
abbbaabbbbbbbbaabbabbbabbbbbabaaababaaab
bbaabbbababaabbbbabaaaba
baaababababaabbbbbabbaba
abababbbaababbbbabbabaabbaabbbaaabbbaabaabbbbaaa
bbaaaaaaaaabababbaabababaababbbbbbbbabaaaaabbabbbbbbbbaabaaaaabbbababbaaaaababaa
baaaaabaaaaaaaaaabbabbba
baabbbbaabaabbabbaaabbbb
abbabbabaabbabaaaabbabab
abaabbbbbaaaaababbabaaba
bbbbbaaabbaabbbaabaaabbaabaaaaabbaabababaabbabbbbabbaabb
babbbabaabaaabbaabbbbbaa
bbabbaabbabbabaabbaaaabaaaabbaab
aaaababaaabaaaaabbabbabaababaabaaabbabbb
abbaaabbbbababaabaaaabaa
baabbbbabaabaabbbaabbaab
baababbabbbabaabaaabaabbbaaabaaabbbbbaba
bbbababbaabbbabbbbbbbbaa
bbbbbbabbbabbabbabbaabbbaaabaaab
bbbababbababaaababaaabbabaababbb
baabaabbaabbabaabbbaaaab
bbaaaababbabababaaabaaaaaaabaabaabbbbaba
bbabbaaabbbbbaaabbbaabab
ababaaababbabababbaababb
aabaaaababbabbabbabbbbaa
aaaabaaabbaabbabababaaaaabbbabbb
abbbabaabbabbbaaaabaaababbabbabbbbaabaababaaabbb
bbaaaabbaabbaaabaaaaaaabaaabbbbaaabbaabaaababaaabbaaabaa
babbbabbaaabababbbabaaab
abbabbabbaabbababbabbbbaaaaabbbabbababba
abbaababbbaabbababbbabbaaabbbbbaaaabababaabababbbbaabbbaabbabaabbbbbabbaabaaaaab
babbbabaababbbabbbbabbba
baaabaabaaaaaaabbabaabba
baabaabbbaabaaabbbabbaaabaaaaaabbbbbaabb
bbababbbabaaaabbbababaaa
baababbaaaabbbbaabbababbaabbaabaabaabbbabbabaaab
bbbbbbaaabbbababbaababbbbaaabbaabbaababb
bbabbaaabaabbbaababbaabb
ababbbababbbbbbbababbabb
babababababaaaaaaaaababababbaaabbabaabab
abaaabaaabbaabbbbabbaaba
aaaababbbabbbbbbbbbaabba
babbbabaaababaaabaaababb
ababbbabbbabbabbbbababaaaaabbbaa
aaaaabbbaabbaababbbbbbbbbaaaabbbaaaaabaabbbbaabaaababbaabababbabbabbabbb
abbabaabbbabbbaaaaabaaaabbbbbaaa
bbbbabbaaabaabbbaabababb
bbbabbaabbbaabaaabaaabaabaaaaaabaabbbbaa
bbbababbbabaaaabaaabbaba
abbababbabaababbbaabbabaaaabaabbaaaabaaabbabbbbbababababbbbaabba
aaabaaaaaababbbaabbaabab
abaabbaabaaabababaaabbbababbbbab
aaaaabbbbbababbbbabaaaaa
aabaaabaaababaaaabaabaaa
aabaabababbbaaaabaabbaaa
babaabaababaabbbbbababbbaaababbaabbabaabbabbbbabbaabaaba
aabaaabaaaabaaaabbaabbbb
bbbbaabaabaaabaaaababbbabaabbaab
bbabababbbabbbbaabbbbaab
baabababbaabbbbbbaaabbbabbbabbbbbabaabbababbaaabaabababa
abbbabbbabbabbabbaaaabaabbbbbaaaabaabababaababaaaaabababaababbba
baabbabbbaabbbbaabaabbabaababbaa
abaababbaaaaabbbaabbbaabaaababbbbbaaababaaaaababbabbaabb
bbbabbbbababababaaabaaabbaabbabaabbabbbbaababaaaabbbabbbbbbabbbbaaaaababbaaaaaaa
aababbabaabababaaababbabbaaaaaaabbbbbbaabbaaabbbbbbaabbb
ababbbabaaabaababbbaaabb
abbbbbbaabbbbbbbbbababba
bbabbbbabbabbbaaabbabaababbbaaaaaabbaaaa
bbaabaababbbbbbbabaabaab
aaaaabbabbbbabbabaabbbbbbabbabaaababbabbaabbaaaa
abbaabbabbbbbbbbabababba
abababbbabbababbabbabbaabbbbaabb
baaabaaaaaaaabbabaaababb
abaabbbbbabaaaabbaaaabaa
bbaabaaabbaabaaaabbbbbaa
baabaaabbbbbbbbabbababaaabbaaaab
bbaaabababbaaabbaabaaabbaabaabbabaaaabaa
aababbbbbbabbabbbbabbbbaaabababb
abbbabaabbaaaaabaaabbaaa
abbbaaaabaaabaaaaaaaaaaabbaabbab
aaabaaaabbbbbbbaabbababbbabbbabaabbabbaabbbbaaaabbbaabbb
aabbaaabbbabbabbbbbaabaaaaaaaabaabbbaabb
babbbbbbaabbabaabaaaabab
aaaaabbbaaaaabbaaababbbaabababab
baabaabbbbbbbbbabbaabaaababaabab
aababbbbaaaabbaababaaaaabaabbbabbbababaaaabaaabbaaaabaabababbbabbabaabbabaabaaaa
aababaaaabbbababbbaabaabbbbababbbbaaabababababba
bbbbbbabbabbababaaaaabaabaabbbaabbaaabababbaaaab
abbaabbbaabbbbabbbabbaba
bbaababaabaabbbbbabababb
aabaabbbbbbbbbbababbababbbbbababbabbaaab
bbabbaabaabbaabababaaaabbabbaaaaabaaabab
babbaaaabbabbabbabbaabab
bbbababbabbababbbabbaabb
aaababbabaaaaaababbbabba
babaabaabaaababaaabaaabaaaabbabb

1728
2020/input/2020/day20.txt Normal file

File diff suppressed because it is too large Load Diff

45
2020/input/2020/day21.txt Normal file
View File

@@ -0,0 +1,45 @@
pnglkx nfnzx tjsdp jkbqk rpmqq gzgvdh rgdx szsbj xjdhk zfml ddbmq thvm mvnqdh gsgmdn dtlhh rqqfnlc bxv nthhxn hnmjfl ckqq qrsczjv fkh hkxcb rpcdfph flhfddq qspfqb zmb rpmmv zrgzf jfqqgtl xxfgvz kltcm xjrpr vnfmc xhmmt zkzdrn jmdg xgbvk ngqh hlmvqh djpsmd bnzq rbvdt tfmgl pjln (contains sesame, nuts)
qchnn dnpgcd zfml thvm gsgmdn frld nfnzx nqfc xbpb kltcm ljmvpp mrfxh zntrfp gzgvdh rrbndl pptgt rknm qsgb mstc ckqq zzldmh nggcjr bkd zfsks hlmvqh cxzkmr zmb tzjnvp npbnj lh pfqxsxd clqk rpmmv szsbj mnvq cnghsg jdtzr kfsfn jxjqp knqzf lvjpp qdpbx qrsczjv xxfgvz ngqh zrgzf jvvmcq zmcj dsmc xhmmt (contains sesame)
hlmvqh klmjmz clqk qrsczjv pjln lvjpp tbm thvm rqqfnlc gzgvdh klx sfk bnzq mhrm vht pjqdmpm tfmgl cxzkmr ghr rxrgtvs rfh rhrc vnfmc ljhn fbcds rkzhxmh htllnq zrgzf xhmmt rcr dgrrm xlzqfb xlnn ckqq vpgvm zntrfp jmdg pgqxp xjrpr vnmfg vqrjn thcs mnvq rczbvg bkd zqsc ngqh rpmqq zmcj cbbkfx rpcdfph mrfxh jfqqgtl mszc tzjnvp sdccxkt rcvd pcf xzcdnr jgtrnm zfcvnj dsmc gjqfj gtgrcf nthhxn jngghk hnmjfl qspfqb bxv (contains eggs)
nthhxn htllnq pbn qsgb mrfxh zrgzf dvcfx mstc jngghk xddkbd dpfphd zhghprj rfh ljmvpp vtljml pmtfmv zmb xxfgvz crnfzr xbpb jmdg tshn nqfc kmsh rknm hkqp pjqdmpm pjln ddbmq bjvcg zntrfp vnfmc qszmzsh fhtsl tjsdp kfsfn jkbqk thvm mnvq dnpgcd xzcdnr xjrpr rbvdt vht jxjqp zzldmh cnghsg pzxj jfqqgtl ckqq kqzcj lxr glrc dgrrm cxzkmr clqk xjdhk hlmvqh vpvj lbfgp klmjmz (contains dairy, peanuts, eggs)
rqqfnlc vgp tbm tjsdp tshn zzldmh zrgzf vgjbgj pptgt xnfhq pbn rpmmv dnpgcd qszmzsh rbvdt nzlks xddkbd thvm npbnj lxr szsbj dtlhh mrfxh ljmvpp xjzc zmb pjqdmpm rknm rrbndl xhmmt hlmvqh jmdg pjln pfqxsxd jdtzr jnr jkbqk vht vhcnpg ckqq ddgdhg pzxj ljhn xgbvk qfkjsq zhghprj gzgvdh xzcdnr ddbmq rcvd lbfgp mvnqdh rfh nggcjr gjqfj hrfmdk (contains dairy)
cmnb cnghsg cxzkmr vfkpj pgb xddkbd qfvfzg gzgvdh bxv zfml clqk pbn nthhxn jmdg ckqq rvchbn xbpb sfk dtlhh rqqfnlc rhrc djpsmd qrftr gjqfj bjvcg zntrfp qrsczjv thvm zlgztsbd lbfgp vnmfg jkbqk lvjpp pfqxsxd ljmvpp mrfxh mnvq ljhn fkh ddrd hlmvqh qmmt rcr vht xgbvk ddbmq tbm vhcnpg srgnx zrgzf ngqh mhrm pptgt glrc rpmmv kx htllnq (contains soy, shellfish)
fdf tshn zhghprj xjzc xxfgvz nggcjr hkqp vgjbgj ckqq hnmjfl mstc dmxhhd rpmmv jdtzr klx ngqh gtgrcf bjvcg vgp jgtrnm ttxx bcvmz pgqxp nfnzx sjgx zfcvnj tzjnvp qmmt jmdg qdpbx zmb rhrc gmc zfsks ljmvpp gjqfj fjgxv zttx lbskg vnfmc vfkpj lxr hkxcb dln xbpb sfk vpgvm thvm ljhn rknm rfh mgxzl thcs jfqqgtl bkd sdccxkt zzldmh mrfxh rcvd qchnn xhmmt rkzhxmh xgbvk csfmx zrgzf qrsczjv gzgvdh ncqdr rxr vtljml lbfgp pzxj djpsmd dpfphd rczbvg knnmm xmjlsn (contains nuts, dairy, sesame)
klx hkqp lqmfgp mstc mgxzl cxfzhj xxfgvz qrsczjv jxjqp ljhn pcf mrxg jmdg bjvcg vht lbskg tphtz nldzpc tjsdp mszc hlmvqh sfk dln ghr mppf lbfgp zkzdrn qdpbx bnzq qsgb rrbndl nggcjr zttx qjsbk llgsg srgnx dbx stcsp rcr zfml jvvmcq pptgt gmc fkh xjdhk pzxj zntrfp flhfddq knqzf ddrd jmgt fdf thcs lh mrfxh xmjlsn kglr pjqdmpm kx dpfphd vqrjn vhcnpg rxrgtvs pfqxsxd nqfc ckqq cbbkfx dtlhh thvm zmb qmmt xlzqfb rpmmv jfqqgtl gsgmdn bcvmz mnvq fbcds xjzc gtgrcf (contains nuts, sesame)
gzgvdh vbqbkt fjgxv nggcjr jvvmcq pptgt fmvvb zqsc hlmvqh rbvdt llgsg xddkbd rfh pjln tzjnvp glrc zmb rqqfnlc zttx qrsczjv rrbndl qfkjsq mppf rxrgtvs lvjpp dtlhh zfml stcsp zkzdrn vtljml qdpbx zrgzf fstgc xlnn sdccxkt hkxcb kltcm xlzqfb jfqqgtl npbnj bcvmz rknm ngqh xbpb rcr thvm kglr dbx xxfgvz bjvcg rpmmv srgnx ckqq gjqfj tshn gmc vgp dgrrm ljhn knnmm qkgqv mstc pnglkx flhfddq tjsdp jmdg zntrfp vgjbgj bkd (contains soy)
qjsbk fkh xddkbd fjgxv lbfgp rxr ckqq tphtz vhcnpg klmjmz pmtfmv jmdg hrfmdk dbx fbcds jnr xxfgvz pfqxsxd qfvfzg bxv flhfddq rknm rpmqq pjln sdccxkt pgb klx jdtzr zmb thvm hlmvqh lxr zrgzf nthhxn vnmfg jgtrnm nfnzx zzldmh ddbmq nldzpc tvqbhv dznd dnpgcd cmnb vpvj sjgx xjzc hkxcb szsbj dcbk pmvl pjqdmpm mhrm rgdx jfqqgtl zttx vtljml mrfxh cbbkfx knqzf mszc jkbqk xbpb vgjbgj pptgt vfkpj vqrjn zhghprj xnfhq tshn rcvd xjdhk djpsmd rfh glrc rkzhxmh (contains wheat, dairy)
mvnqdh nqfc bjvcg ckqq zfcvnj jmdg ljhn hkqp srgnx zfsks bxv xbpb rkzhxmh cxfzhj rpmqq zdntns dnpgcd thcs lvjpp klx jngghk flhfddq gmc pjln dcbk cbbkfx vbqbkt qchnn tshn fhtsl qmthj jvvmcq ncqdr jmgt csfmx qrsczjv tzjnvp rczbvg rcr hlmvqh rbvdt gtgrcf thvm cnghsg zrgzf rxrgtvs zmb (contains peanuts, soy)
ckqq frld mvnqdh tphtz bjvcg xzcdnr djpsmd ttxx dcbk qdpbx tshn rczbvg vpvj qmmt ddrd dln bxv zrgzf jxjqp lh mgxzl qrsczjv ltvr pbn nggcjr dsmc llgsg knnmm pzxj cnghsg thvm vnmfg mhrm xlnn gjqfj pptgt jkbqk htllnq jmdg xnfhq klx jmgt mrfxh rxr hnmjfl lqmfgp qrftr mppf sjgx rvchbn lvjpp mstc zqsc gmc kmsh rpmmv crnfzr hrfmdk kglr hlmvqh cxzkmr dvcfx (contains shellfish, eggs, dairy)
xjrpr mjpt cbbkfx rpmqq ljhn jmdg vht sdccxkt ngqh bnzq jgtrnm fmvvb mrfxh xxfgvz jfqqgtl tfmgl bcvmz pgqxp thvm crnfzr xddkbd zfsks qrsczjv pzxj tshn fbcds lbfgp thcs hkqp gsgmdn dvcfx zmb cnghsg csfmx vhqfz rxr bxv xjdhk zhghprj dtlhh ckqq qmthj jxjqp rczbvg gmc sfk ttxx ltvr pnglkx dnpgcd qsgb clqk klmjmz lh rvchbn pjln knqzf vnfmc qspfqb nthhxn zqsc mhrm gzgvdh ncqdr zrgzf ddrd vqrjn (contains nuts, shellfish)
rvchbn vhcnpg mstc zrgzf hkqp bnzq xbpb qrsczjv fhtsl fjgxv ddgdhg jfqqgtl rpmqq dpfphd pcf qrftr ngqh vht dvcfx dfrg tphtz mnvq qjsbk mvnqdh zntrfp xjzc jmgt xzcdnr vnfmc xddkbd fkh kmsh xmjlsn ckqq zfsks bcvmz ljhn gmc rrbndl fmvvb cxzkmr lh zdntns pgb thvm xxfgvz hrfmdk dln mrfxh tvqbhv cnghsg vpgvm hlmvqh mjpt jdtzr dgrrm kglr pgqxp kqzcj hkxcb xgbvk djpsmd tshn klmjmz rfh xlnn bjvcg qfkjsq rkzhxmh glrc clqk gjqfj jmdg knqzf ljmvpp csfmx rbvdt zfcvnj dsmc fstgc (contains dairy)
nthhxn vnfmc dsmc vpvj rhrc zfcvnj zdntns qmthj knnmm rpmmv dtlhh qdpbx zhghprj xddkbd mrfxh rqqfnlc dpfphd xhmmt dgrrm pgqxp zmb gmc flhfddq zkzdrn hlmvqh qrsczjv vhcnpg mjpt fbcds thvm ncqdr pjln zttx hrfmdk xlnn dvcfx fkh mszc klx cmnb zfml zrgzf mnvq rcr bjvcg csfmx xlzqfb ckqq (contains sesame, shellfish)
xnfhq hlmvqh lh qdpbx rpcdfph qsgb rpmqq tjsdp ljhn gsgmdn vfkpj jmdg xlzqfb ckqq qmmt jmgt dvcfx zrgzf bkd pmvl ngqh sjgx dpfphd kfsfn mrfxh bjvcg jkbqk qrftr mjpt vnmfg nldzpc ncqdr jvvmcq pptgt pjqdmpm thvm pjln ddrd csfmx kglr xgbvk tzjnvp bxv htllnq fstgc zfcvnj jxjqp pbn dsmc kbtx vqrjn rqqfnlc rxrgtvs hnmjfl qrsczjv (contains eggs)
mvnqdh klx rbvdt kx qmthj hrfmdk bcvmz fhtsl zrgzf xxfgvz pmvl csfmx hkxcb rpmqq vpvj jmgt vbqbkt lxr hlmvqh zhghprj kglr dpfphd xzcdnr mszc vgp dvcfx gzgvdh ncqdr mppf nldzpc djpsmd pnglkx mrfxh lqmfgp sjgx jfqqgtl dln vhcnpg npbnj cmnb hnmjfl kfsfn vtljml qspfqb xlzqfb dcbk jngghk lh jxjqp rxr jdtzr qrftr fbcds thvm mrxg zzldmh qfvfzg dtlhh hkqp dsmc qdpbx cxzkmr tfmgl xjrpr pjqdmpm rczbvg rcvd lbfgp jmdg qszmzsh glrc qkgqv tvqbhv qrsczjv fkh rknm ckqq zntrfp cbbkfx (contains shellfish, dairy)
zqsc zmb sfk thvm lvjpp ddgdhg qrsczjv qspfqb dmxhhd zzldmh xzcdnr xjdhk dznd qfvfzg ljhn ghr zrgzf bcvmz frld pnglkx fhtsl srgnx jfqqgtl fdf vhqfz qsgb jkbqk ckqq xxfgvz pjqdmpm rpmqq jmdg fkh crnfzr mjpt cnghsg qrftr xddkbd rkzhxmh pfqxsxd mhrm gtgrcf hlmvqh fmvvb tvqbhv dgrrm xbpb qmthj gjqfj kqzcj tshn qkgqv vfkpj kmsh pgqxp ddrd glrc xgbvk hrfmdk rgdx bnzq knnmm qchnn vnmfg ncqdr qfkjsq pmtfmv xnfhq sjgx cbbkfx stcsp rbvdt mstc gzgvdh kglr dsmc rrbndl xjzc rpcdfph (contains nuts)
rbvdt jmdg zkzdrn zmb hnmjfl gmc pgqxp lqmfgp knqzf xbpb fmvvb bkd dgrrm vgjbgj dcbk ttxx dtlhh vpgvm xlnn hlmvqh jgtrnm dpfphd qrsczjv xzcdnr jngghk qmmt thvm flhfddq gzgvdh crnfzr qszmzsh xlzqfb dfrg qspfqb qmthj rpcdfph frld zqsc xjdhk dmxhhd ljhn qchnn bnzq kltcm gtgrcf mszc zhghprj rhrc csfmx mrxg klmjmz lbskg ckqq pzxj nggcjr nthhxn nldzpc rpmqq dbx mhrm zrgzf xjzc (contains dairy, wheat, eggs)
lh sfk jvvmcq szsbj fmvvb xxfgvz sjgx jnr vqrjn gmc cnghsg qsgb jmdg mppf jfqqgtl fjgxv vbqbkt zqsc xgbvk pgqxp nqfc jmgt rfh xlnn rhrc nfnzx rpcdfph qszmzsh kglr zmb xnfhq thvm tbm zzldmh rcvd pmvl kqzcj hnmjfl nggcjr qrsczjv qchnn zmcj rvchbn fdf xmjlsn mnvq mgxzl rkzhxmh bxv ngqh xlzqfb gjqfj sdccxkt clqk cmnb rbvdt jkbqk dpfphd mrfxh hlmvqh kltcm ckqq jngghk mszc (contains sesame)
zfcvnj mvnqdh gjqfj htllnq nggcjr vtljml qrftr fstgc xjrpr dvcfx klmjmz thvm qjsbk rcvd hrfmdk rczbvg mjpt ncqdr kbtx nqfc xxfgvz xlzqfb mrfxh zmb jkbqk jmgt rxrgtvs qspfqb rhrc qmthj mszc ghr fmvvb cxfzhj lqmfgp ckqq zrgzf vfkpj tzjnvp mhrm vpvj pgqxp ngqh xlnn hlmvqh xnfhq tbm zqsc jvvmcq rvchbn lxr qrsczjv vgp cmnb pjqdmpm (contains dairy)
qfvfzg ngqh rhrc nthhxn mvnqdh rcr knnmm zmcj nfnzx stcsp nzlks qdpbx kfsfn nldzpc mrfxh cxzkmr fkh vpvj llgsg pgb cmnb ncqdr qchnn zrgzf rknm xjzc zntrfp mstc clqk gsgmdn jnr ljhn mppf hkqp jmdg xlnn xgbvk csfmx rpmmv fmvvb mjpt thvm zlgztsbd dtlhh dln bnzq klmjmz tfmgl vgp qmmt kglr dbx gzgvdh rcvd kmsh rgdx kqzcj ttxx tzjnvp qmthj hlmvqh zfsks qrsczjv lh vhcnpg pgqxp zmb zhghprj vht rxr vbqbkt pcf gtgrcf zzldmh dvcfx (contains wheat)
vfkpj kbtx qkgqv bkd srgnx rcr zdntns tjsdp kfsfn rhrc mstc vtljml zlgztsbd rbvdt zrgzf glrc qfvfzg rkzhxmh ddbmq pbn flhfddq dfrg kglr clqk rxrgtvs cxzkmr mrfxh ddgdhg cmnb hlmvqh rpmmv dln zttx pjln zmb pjqdmpm jmgt ckqq qdpbx rcvd thvm rrbndl vbqbkt xmjlsn lh xhmmt qmthj nzlks pgb xzcdnr mrxg xgbvk fkh vgp rqqfnlc gjqfj gsgmdn tbm szsbj bxv lxr cnghsg jfqqgtl dbx pmtfmv lvjpp xjzc xlnn dtlhh dsmc vnfmc qrsczjv zkzdrn ghr fhtsl (contains dairy, wheat, peanuts)
nldzpc pbn rxr vgp zmb pgqxp zfsks vfkpj tvqbhv qmmt pjln jmdg qfkjsq hnmjfl mrxg hlmvqh dln nqfc lbfgp rcr kfsfn vtljml rxrgtvs tbm dsmc hkqp lh jngghk vbqbkt thvm fbcds clqk pjqdmpm ckqq mppf tzjnvp xhmmt csfmx rpcdfph sdccxkt kbtx knqzf rkzhxmh qrsczjv mszc ttxx klx mrfxh mnvq (contains dairy, sesame)
rgdx tfmgl gmc fstgc ltvr ckqq pnglkx kglr hkqp ddgdhg qfkjsq xzcdnr jnr xxfgvz hlmvqh zhghprj ghr pfqxsxd ljmvpp zmb cmnb nldzpc dznd xlnn zrgzf lh zfcvnj dcbk kmsh xjrpr qjsbk nzlks gtgrcf kfsfn dpfphd rqqfnlc mppf zzldmh thcs cbbkfx jmgt rcr pjln mrfxh jxjqp fmvvb pmvl mgxzl knqzf rbvdt gzgvdh jmdg qrsczjv nqfc vnmfg qszmzsh tjsdp ljhn qrftr ddbmq bkd fbcds (contains wheat, peanuts)
clqk rpmmv rkzhxmh pbn mrfxh pmvl hkxcb mvnqdh kbtx tzjnvp ncqdr kmsh dcbk zrgzf qchnn bkd kqzcj hlmvqh thvm cmnb mjpt knnmm pzxj frld gsgmdn pfqxsxd ltvr lqmfgp fkh rbvdt vgjbgj nldzpc jgtrnm dbx qrftr zdntns lbskg rpcdfph djpsmd vbqbkt dsmc jdtzr qmthj zmb hnmjfl sfk mppf fmvvb rcr xmjlsn qrsczjv csfmx dln vqrjn xbpb stcsp fdf rxrgtvs mstc jmdg ljhn npbnj thcs ddbmq knqzf dgrrm rqqfnlc mszc jnr lbfgp qsgb dtlhh pgb bcvmz qszmzsh rfh gjqfj xlzqfb rxr (contains peanuts)
clqk csfmx lvjpp kqzcj thvm zntrfp dcbk ghr vtljml pfqxsxd pjqdmpm jgtrnm flhfddq zzldmh llgsg nthhxn mjpt zrgzf pjln dznd mnvq bjvcg nfnzx tzjnvp vgp dtlhh qmmt rpmmv jmdg zfcvnj xzcdnr zmb tbm dbx bxv cxzkmr tfmgl mszc ttxx qkgqv qjsbk ckqq pgqxp zfml mhrm vpvj jdtzr mgxzl tvqbhv qfvfzg vhcnpg lbskg lqmfgp cnghsg rcvd hnmjfl zhghprj hlmvqh xjrpr xxfgvz dln gtgrcf sdccxkt kx qspfqb jfqqgtl pptgt dmxhhd rpcdfph fstgc rcr fmvvb ljmvpp mrxg gmc pgb mrfxh kmsh cmnb (contains soy, wheat, eggs)
klx nggcjr xjrpr zdntns kltcm vhcnpg xlnn kqzcj hlmvqh dnpgcd vht rpmmv bnzq hnmjfl lbskg fdf bkd dgrrm rvchbn mgxzl pgb jdtzr dcbk qszmzsh rpmqq hrfmdk qrftr dpfphd lxr ngqh xddkbd qrsczjv tbm vqrjn qchnn vpvj mstc ckqq pbn zrgzf jxjqp jgtrnm tfmgl zmb rqqfnlc xmjlsn rxr pmtfmv zmcj zfsks zqsc crnfzr jmdg fbcds mrfxh xgbvk hkxcb gmc nldzpc nfnzx xnfhq (contains peanuts, eggs, nuts)
csfmx zzldmh dcbk fdf rhrc fjgxv qchnn cxzkmr qmthj crnfzr nqfc zmcj mhrm ltvr sdccxkt flhfddq cbbkfx cmnb qdpbx thvm xmjlsn fhtsl knqzf bxv nggcjr vnmfg zmb cxfzhj jdtzr pnglkx jmdg lxr kmsh vgjbgj mrfxh dln mppf gzgvdh rpmmv zntrfp zrgzf pgqxp ckqq zfml vnfmc vht pmvl xlzqfb rxrgtvs kltcm pzxj dsmc dtlhh hrfmdk qmmt dnpgcd bjvcg gsgmdn cnghsg xhmmt gmc ttxx qjsbk hlmvqh fkh vhqfz xxfgvz (contains dairy, sesame, eggs)
jmgt mppf ttxx dsmc xnfhq bxv kglr bcvmz ckqq jmdg dfrg jnr mnvq ngqh sfk fdf xhmmt fjgxv zfcvnj rczbvg cmnb xjrpr szsbj dvcfx gtgrcf knqzf pjln mrfxh lbfgp vnmfg jdtzr mhrm fstgc tbm djpsmd pnglkx qkgqv zmb vfkpj hkxcb qfkjsq pgqxp xzcdnr nfnzx npbnj rbvdt jfqqgtl hlmvqh qfvfzg jvvmcq hnmjfl thvm rgdx gjqfj zhghprj kqzcj rcr zrgzf tvqbhv tshn (contains peanuts)
rknm lvjpp cnghsg qrsczjv sdccxkt zrgzf rcvd rxrgtvs stcsp thvm fstgc ttxx pmvl rpcdfph dznd ckqq pptgt mstc rpmmv fdf knnmm jnr bjvcg mnvq qdpbx zfml rqqfnlc zqsc zhghprj mgxzl qmmt fkh rxr dsmc lbskg sfk xhmmt kqzcj vfkpj mhrm hlmvqh mrfxh pcf zmb jmgt ljmvpp jfqqgtl szsbj xjrpr vnfmc qszmzsh dbx mszc xlnn qrftr qchnn mjpt zttx ddgdhg gmc djpsmd zfcvnj dln qkgqv rcr dnpgcd tzjnvp hkxcb zmcj lxr bcvmz fhtsl vnmfg vpgvm (contains dairy, sesame)
rgdx jmdg cmnb thvm fstgc pfqxsxd ncqdr dmxhhd glrc xjrpr rkzhxmh fhtsl mrfxh hkxcb pmtfmv zfsks knnmm pgb vnmfg thcs dfrg ddbmq clqk zntrfp nthhxn xjzc dgrrm lvjpp rpmmv vht lh jfqqgtl vgp mszc rczbvg jnr jngghk xhmmt vhqfz bcvmz zmb ckqq tjsdp bkd xlzqfb xddkbd pmvl qrsczjv ddgdhg djpsmd ttxx zfcvnj mjpt nldzpc qrftr kx xnfhq fjgxv jmgt ljhn mrxg pbn sdccxkt rxrgtvs dln dpfphd zrgzf tbm rfh tvqbhv (contains sesame, dairy, shellfish)
rczbvg cxfzhj lxr mgxzl hkxcb kbtx zmb jvvmcq pmtfmv jfqqgtl jxjqp mszc thvm rknm jmdg vfkpj qmmt hlmvqh ltvr cnghsg pjln mrfxh gzgvdh szsbj pgb dcbk lvjpp qchnn bcvmz sdccxkt llgsg xgbvk mrxg ghr zhghprj hkqp thcs zrgzf zzldmh ckqq frld gtgrcf pnglkx clqk kglr xhmmt hnmjfl qjsbk qfvfzg dnpgcd dbx djpsmd qrftr rgdx tvqbhv ncqdr (contains eggs)
pmvl zmb zrgzf rxrgtvs mvnqdh dznd srgnx qmmt pgb jmdg hlmvqh dgrrm xjdhk klx rcvd qrsczjv cnghsg ttxx hrfmdk qspfqb pfqxsxd fmvvb pzxj sfk rbvdt nggcjr zqsc npbnj kglr xddkbd lbskg lqmfgp mrxg mrfxh zfml rkzhxmh jfqqgtl vgjbgj rpmmv tphtz mszc dln zfcvnj vpgvm tzjnvp rhrc nldzpc rknm tshn jgtrnm mppf fjgxv ckqq ddgdhg vpvj fbcds (contains shellfish)
xlzqfb nthhxn dln rczbvg jmdg vgp cbbkfx gsgmdn jvvmcq glrc klmjmz stcsp bcvmz dbx vpvj cmnb sjgx rfh rrbndl mgxzl jnr rhrc thvm xlnn mhrm mrfxh bxv qrftr lvjpp fjgxv kglr cxfzhj zmb pptgt ghr kbtx pnglkx qjsbk ckqq jfqqgtl fstgc dznd qszmzsh jgtrnm zrgzf tjsdp klx pjln vgjbgj vbqbkt zkzdrn sfk qrsczjv vhqfz hrfmdk kltcm vnfmc zqsc xhmmt knnmm qfvfzg xjrpr nqfc jkbqk (contains nuts, sesame)
jgtrnm bxv fbcds dznd bkd ttxx rpmqq ckqq pmvl dtlhh xjdhk zdntns knnmm vqrjn dsmc lqmfgp ltvr jfqqgtl mszc xhmmt szsbj crnfzr fkh rbvdt pjqdmpm nggcjr qrftr bcvmz qmmt srgnx xddkbd rvchbn zmb cmnb pptgt xjzc llgsg rxr bnzq gsgmdn thvm zzldmh rcvd mrfxh dgrrm zfsks qsgb tvqbhv zkzdrn nzlks lh klmjmz rxrgtvs kqzcj mnvq ngqh rczbvg tshn tjsdp hlmvqh pcf fdf rfh pnglkx hkqp zrgzf jkbqk sdccxkt fstgc vpvj ddbmq zttx xlzqfb qfvfzg frld qrsczjv zlgztsbd xnfhq pfqxsxd cxfzhj cxzkmr tphtz clqk (contains shellfish, peanuts)
hrfmdk nthhxn lh zrgzf thvm rbvdt qdpbx mhrm vhqfz lqmfgp qjsbk vgp qfvfzg szsbj nldzpc vpgvm sdccxkt dgrrm tfmgl zdntns ddgdhg zfsks hlmvqh zmcj pnglkx ncqdr qrsczjv sfk mrfxh rqqfnlc vht mstc pmvl cmnb gmc ckqq jmdg thcs bjvcg nzlks klx jfqqgtl fkh ghr ddbmq htllnq xlnn kglr (contains nuts)
fkh knqzf tvqbhv mrfxh hkqp nqfc mvnqdh xxfgvz gzgvdh vnfmc qrftr qrsczjv ngqh cxzkmr mjpt dvcfx zmcj xddkbd clqk rvchbn dsmc xjzc pfqxsxd dfrg qmmt mhrm flhfddq rrbndl xnfhq hlmvqh jmdg dznd frld jnr djpsmd thvm qjsbk ddbmq qchnn pnglkx dtlhh zhghprj fhtsl vtljml nzlks qszmzsh lqmfgp pbn cmnb rpcdfph kx qkgqv zrgzf tshn zmb zlgztsbd xlnn (contains eggs, nuts, dairy)
gsgmdn zqsc cxzkmr xlnn htllnq vbqbkt pgb pnglkx tphtz jmgt mrfxh qkgqv pjqdmpm glrc sdccxkt rbvdt vht pzxj fstgc bcvmz mjpt dvcfx vpvj ljmvpp pfqxsxd tshn zmcj zrgzf qmmt pcf dpfphd xxfgvz jxjqp rczbvg mgxzl thvm fjgxv hnmjfl rkzhxmh qrsczjv jmdg cnghsg zfml gjqfj tbm lh mppf dcbk zntrfp dbx jvvmcq szsbj pjln xhmmt rcr nthhxn kx fmvvb xzcdnr klx rpcdfph zmb djpsmd jdtzr mnvq hlmvqh bjvcg mrxg (contains eggs)
vqrjn rhrc pzxj pjqdmpm tshn pjln nggcjr ljhn fkh qchnn kfsfn vgjbgj jmgt qkgqv stcsp knnmm dznd pgb csfmx fmvvb ltvr rknm rpcdfph thvm mrfxh qfvfzg zfcvnj zmb clqk kx ghr rpmmv vbqbkt tfmgl dfrg lxr hrfmdk vpgvm zlgztsbd rczbvg tvqbhv jnr qjsbk qfkjsq xxfgvz hlmvqh klx dnpgcd kbtx flhfddq jfqqgtl jmdg ddrd xgbvk rqqfnlc ckqq bnzq mnvq ncqdr dln qdpbx kltcm mppf zttx dbx pmtfmv klmjmz vnmfg pgqxp nthhxn crnfzr dmxhhd xhmmt rgdx mvnqdh gsgmdn nzlks xzcdnr fbcds djpsmd zfsks dpfphd lh ddbmq vfkpj vgp qrsczjv (contains peanuts, eggs, soy)
dsmc hlmvqh rqqfnlc dgrrm lbskg xxfgvz klmjmz jmgt jnr dznd npbnj rrbndl fkh vfkpj dvcfx hnmjfl qrftr pmtfmv kltcm xzcdnr gtgrcf lbfgp bcvmz xddkbd vgjbgj gjqfj kglr qchnn zlgztsbd rcvd xmjlsn bnzq kbtx vnfmc zmb srgnx pptgt llgsg thvm ckqq qrsczjv cbbkfx cnghsg xjzc rbvdt mnvq mrfxh mppf rknm jmdg tzjnvp rfh vgp vpvj nfnzx hkxcb zqsc lqmfgp kmsh dnpgcd sjgx sfk gmc jfqqgtl ltvr vpgvm pmvl qmthj klx tbm rvchbn pfqxsxd xjdhk glrc rczbvg knqzf (contains shellfish, dairy, nuts)
ngqh lxr qrftr nldzpc cbbkfx zdntns xxfgvz srgnx qspfqb zfsks tzjnvp tphtz qrsczjv lbfgp gjqfj xjrpr qfkjsq rfh xgbvk dtlhh mrfxh xjdhk qkgqv hkqp dsmc rczbvg klmjmz ckqq xlzqfb ddgdhg kltcm vhqfz kglr jxjqp xddkbd htllnq gtgrcf zrgzf lbskg gmc szsbj thvm zmb zfcvnj hlmvqh pjqdmpm (contains peanuts, shellfish)
xlzqfb vpgvm flhfddq kbtx zmcj jmdg vhqfz tphtz vqrjn stcsp ckqq rgdx nfnzx nggcjr qrsczjv xmjlsn pgb ngqh pjqdmpm qsgb nldzpc hkxcb klmjmz rpmmv xjrpr zlgztsbd ncqdr zmb rpcdfph qjsbk gzgvdh xnfhq hlmvqh cbbkfx knnmm qfkjsq xddkbd vgp pmtfmv qdpbx cnghsg hrfmdk fjgxv xlnn xjzc mszc ljmvpp zntrfp fdf pcf mnvq thvm bkd fbcds dbx fstgc dln pfqxsxd zrgzf mhrm pbn zttx zhghprj (contains peanuts, eggs, dairy)
nldzpc gmc mjpt knqzf rbvdt zntrfp nthhxn jmdg rxr xzcdnr kx ljmvpp kltcm jmgt gjqfj pgqxp xjrpr zmb qrsczjv hlmvqh dbx dmxhhd pnglkx gsgmdn vhcnpg zrgzf xjzc pjqdmpm rpcdfph lbfgp xgbvk jvvmcq qdpbx nqfc dvcfx thvm rknm kbtx npbnj mrxg klmjmz rrbndl xbpb ncqdr fdf vpvj kglr pptgt mrfxh (contains sesame)
tshn dmxhhd qmthj kqzcj rqqfnlc pcf dgrrm hkqp ckqq flhfddq qmmt thcs vqrjn vht tbm lqmfgp bcvmz fbcds jmdg rbvdt xzcdnr xlzqfb vfkpj mrfxh sdccxkt fstgc fhtsl qfvfzg kmsh dznd zrgzf bxv glrc thvm pmtfmv rkzhxmh zqsc xjzc fmvvb ddbmq qspfqb tjsdp rcvd xgbvk gzgvdh cmnb pptgt ngqh xlnn sjgx mrxg qdpbx rknm hnmjfl szsbj zntrfp gtgrcf fdf kltcm vhcnpg zmb pjln mppf dnpgcd ttxx qrsczjv srgnx qszmzsh (contains shellfish, nuts)

53
2020/input/2020/day22.txt Normal file
View File

@@ -0,0 +1,53 @@
Player 1:
1
43
24
34
13
7
10
36
14
12
47
32
11
3
9
25
37
21
2
45
26
8
23
6
49
Player 2:
44
5
46
18
39
50
4
41
17
28
30
42
33
38
35
22
16
27
40
48
19
29
15
31
20

View File

@@ -0,0 +1 @@
872495136

349
2020/input/2020/day24.txt Normal file
View File

@@ -0,0 +1,349 @@
sewnwwwswnwnwwneneeenwwseswseww
nwwseneswnwsenwwweseneenesenwwwnw
seswewnwnesewneneneseseswwsesesesesenew
sesewnwwwswesenwswswneswswswwwnew
nwswenenwswenwnwwnwnwnw
wwswwwswwnwwe
wewnwsenwswnenwneneesenwwswsene
nenwnwnwnenwnesewnwnwnenwnene
nwewwwnwnwnwswwnw
nwnwseesewswsenesenesesewswseseseeswe
swnweseseenwseeswewneeneswewesesenw
enwneneeswneesewneneneenwnwneeese
senwswseesesesenwswseswsenwneseseseswsese
seswswnewneswswseneswsweswsw
swnwnwnwnwnenwwnwnwenwnwswnenwsenwnwnw
nenesesenenenenewenwneneneneswnewnwne
seweeeseewseseewseewwneeee
nwwwswwewwwswnwswswewswwsw
nwnwnwsesenwnenenwnwsesenwnwnwnwenwswnww
wesewsewswneneesenenenwnenwwnenwnwnw
nwnenwnenenenenenwnwsenw
wesweeswenwenweeenweswsenweew
senwswswnenwwsweneswweswwswenesew
nwwnwenesenwnwnwnenesenwsenwnenwwnwesw
newnwenenenwnenwsenwnenwnenesenenesese
seswnewnewnwswewnwswwwnenwsweeeww
nenwnenenwnwnwnenwnwnwneseswne
enwswswswenenwwswswneswse
wwsenwsewnewnwswnwsweswewwwwsw
eseeneewnwwnwneswneweeeeesee
swwneswswesenwnenwnwsenewwseseeswseene
wwswneswswswswneswswswswsewswswenesesw
nenenenenenenenenenenenwnesene
nwwnweswnwwwswenwswswwwswswwneeese
swneswnwseseseswswswweseswswswnweswewsw
weseseeswesenwseeeeseesenwesene
wswswseewnewswwneneswseneswwseswsese
wswnwneeenenenenenesenenenenenenwsenene
neneneneneswnewneeswnenwneeeenenene
swseswsewseswwsenwswneseswswseeseswsw
wswswswnesweswswswswwewnewswneseswswsw
nwsenesesesewweseseswnesewswne
sewswwnenwneneseeneesw
nwwnwnwnwswnwwnwnwwwnwne
enwsewneweeeseeeseseseeseeee
seswneewneenenewneneneneneswnweswne
seswseenesesewswswswsenwseesenwsesesw
swnwwnwnwnwnwnwwswswnwnenwenwnwenwnww
nenwnwnwwenenwswswnwnwnwnwenwnenwnwne
nwsewsenwneswsenwsenenwwnwnewswsenwe
wneenewwnwseneeseseewwseswsesese
swswneeeseesenwneesweneseesesenwsww
wnwsweswswwnwswwswswswnesewseswswnwew
swsewsesesewswneseswswswsenwneewnwe
nenenwnenwnenwsewnwnwnene
neseswswwwnwseenwswswwswwwese
enwnewwswwesenwnwnwswnwnwwwnwwnww
nesewnenwwswnweenenenwnenenene
wnwseeneseswnwnwsese
wewswsewwnenwwsenwwwnwwwwnw
wsesewsenesesewesenweseswseseseneneswse
eeswswsenwnesenewne
wseseswswswswswswswwenewnwswnwswswne
wswswswswewwwwswenwewwswnwswsw
enwnwneseswneeneswneeeeneneeswenenw
nenwewnwnenwnwnwnenwswsenwenwnwwnw
swnewseswseseseseesesesenwnwswenwsew
seewwwwwnewswwwnwwwnwnewnenwnwse
neswenweneneseeeneewneswneewneenesw
nesenwsewnwsenenenwwswnw
sesweeeneseneeneenwweenenewwsene
neneneeswnewneseswnewenenwewnenene
swneneswwwsenwnesenwnwwwnewnwnwww
nwenenwnwnwswwnwwnwnwsesenwsenwnwsenenw
seseseseseswsenwseseseseseneswnwsesewsw
nwswweswswnenewneswswswewswswswese
seeneseswseeeeesewseseenwneeswesw
seseeswswsesesewsesenwseesesesenwsese
nwsenwnenweswswenenwswesenwnesenenene
nwnwnwnwnwwsenwswnenwwnwnwnenwnwsenwsene
nenwnwwseneenwnwsw
eeeneeeeeseswe
neneesweneneseswnenwneneseneenewnwwe
wswneneneswswswseswnenewswswswswswswsw
neswswseswewswnewswswewswnwwswswenw
wwwseneweswnesesweseseswneswseese
wneeswenesenweneweneeeswnwswseene
wseneseneswnwneeneenwnenenenewnewne
nwsenewenenesewwnese
sewwnenwewwwsewswewsewwnewwww
seeeenweneswnwswseswnwnwwswswenwne
senwwwnwenwewnwnwewnwwwesenwenw
neswnewseenenewsweeesewnwenenwe
seneneswseweewnwnenwseweneneewnew
swwswnewnweseseswwwneweeneneseswwne
sesenewswswseseseseseneswwse
swsenwnenwwnenenenwnenee
sweeweenweeeswenwee
swsenwneseswewsesesewesenwsenweesw
swwsewswwswwswwwswswnwsw
eswnwneseswneneenenesw
newswsenwesewwwwwnenwswnwnwenwnwnw
seeseseenwseneenwneeesweeswewesw
seeeseswesesewsesenweeenwseeeesw
nenesenewnenewnenewwswneseseseenwnene
swwswneswswswwswwsewsw
sewesweeseeseneeeeee
seseswswswnewnwewsweseneswswsesewwsw
wnesenesweeenenenenenenwewnenenesw
nesenewwnwwneswnwnwsenwsewnw
enwwswnwwwwnwnwwnww
sewneeeseseenwnwnwseswseseseeseneese
eseseseseswneseseenenweseswseswe
swsesesenwneswswwneseeseeswwnwswswse
swnwneseseseswseseswseseseseseswnesewsw
nwswwwseesweswwswwne
sewnwnwwsewsewsenenwnwnwwnenwwnwwesw
wwwnwwnwnwswwswwnwwnewwe
seswnwenweswewnwswseneseswneewnww
seseseseseneseesesesesesenwsewsewsese
swwsesenwswnwswnwewnwnwnwnenwnwnwnwwne
senwseeeeeeseeseewsese
swswenewswswneseseswseswnwswneseswww
neneneneseneneeneneneneswneswnwenwesene
swseswseseseneesenenewewwseeswnenew
swnwnewwwwwwsewwweswwwneww
wswswnwswwwswneseswswswswwswseweswsenw
enwswnwnesenwnwenwenwswneneswnwnwnww
eneesweneneneeswnwne
wnwwewwnwwnwwwnese
nwwewneseeeswenwseswswswswsenwwswnwsw
wnwnwnwwnwnwwwwwnesew
wnwswseeswenewww
nwnwnwnwnwwnwseswneenwnenw
enesweeneseeeweenwseneswwswee
sewwwswneswnwsewswsw
neseseswneswwswswseseswneseseswseswswse
eseswswswswnwswseswswswse
eeseswnwswswseenwwseswnwseneseswsene
wwswneneswsewwneswswseswseswwwwnw
newswwsewneeneseeseseewsewnwweswse
nwnenwnwnwnenwnwnwwnwswnwnwnwnwsweenw
neneenesewnenewsenenenenwswwneenenese
neneseneneneneneneseeneneneswwnenewnene
nweswnwseswsweeeeenenenwsweseweese
swneswseswswswnwseseswswswswnwseeswwsw
wnwsenwwnwsenwwswnenwnwwnwenenewsenesw
nweseseeswsweesenweswnenweseseee
wswnenwnwnwsenwwenwnwseenwswnwnwsenwnene
nwnwnewnwnwnwnwwnwswnwnesweswsenwnwnww
neweewenenwneeeeneeseseswseenew
weweesweseneeswwseenwnwnewneee
wnesweneeeneseenwwwseenesweww
wnewseneneswswseswswwnesenwneswnewsenw
seswnwewsewswswswwnenwswsene
swswwnewswsewswweswswneseswswsw
nwewsweeneneneneswnww
newneweneneneswneneneneneneeneeseswne
nenwewnewseswnewneeswswseesenenww
seswswswneswswwswswswseneswneseneswsesww
nenenenenenwneeneseeesweneswsenwnenwww
eeneeeeeneeenesweesw
swwseneswsweswseswwseswseswneseswsenewse
seenweneeswwwwswnenenewneseneene
swswneswswswsewseseneseswweeenwwnwswsw
newnwswnewwnewwsesenwswnw
weneswswnewnwsenwswnenesenwnenenwnene
sesesesweseweswsewsewenwseesenwse
nenweenwwnwwsewnwwswnwnesenwwswsw
swnwswnwseneneseseswswseswwswsewneswswsese
nenwnenwenenesenwnenwnwswnwne
nwswswweseswswneswseew
eeswseenweeeseweseeeesee
sewwswswswseneswsweseneswswswneseswwsw
ewewnwsweeenesweeneseeswneenwe
neneswesenwnwsweeseswnwswwswnwewesw
neeneneeswenweeeeneneee
nenesesenenwnwnwnesewnwneneneswnenwnenwne
seseseneweneswwseseswsenwseseseswsese
sewsewneewewnwswwwneww
seseseseeseseswsenwsesesenwsenwseseee
sewwwwneswwesenwwwswswswww
eneeswneseweeweeewenweeene
swswnwswsweswswseseseswse
seseseswsenwswseseseeseswsesesesenwe
nenenewnenwnenwneeenenwnenwneneneswse
eseeeeeenweeeeee
wwwwnwwnewnwsewswwswneweesesew
seenewwneneneseeeneneenenenewnene
seswswneneeenwswwnwenenewnenenenesene
eeewneseeeswseenweewseewee
eeeewsweeenwnwweeseeneenenew
nwneswswnenwnenwnesenwnwwnwneswnwseswsew
nwsweeneeneseeenewnwnwneneswneswne
swsesewseseesenenew
nenesweseeeeewesweeesenwseee
nwnwenwwswsewswwneenwwnwsewseene
enwneneneswneeneneneswnenweeneswsene
swswwswswneswseswswwwswswsw
swswswswseswseneeswnewswwsesese
wseeswesenenwenenenwneeneweeswnee
eseenwseeseenwnwsweseseesesenw
sewswseseeseseseneseswsenesesewsesesw
swswnesenenwnewseewsweswneswwswswswse
sewwswseswnenwwewwswwwsewwnwswnwnw
nwnwnwenwwnwnwnwsenenwnwnw
swwnwsweswseeewnewwwnese
swwenwnwnwwswseeewnwnwwewswnenwne
seseneesenenwswnewwseesewseeswsese
swsesweeswnesewweeneswwswwswseswne
wswsewwwswnwwwnwwnenewwwseewnw
eewswnesenwswnwnewseeswnwnwnw
nwwwnewwewnwnwwnwnewwnwewswsw
sesewneswneenwseswseesese
neswweneeenesweneenesenewne
nwwnwseswswnwnwnenwnweswnwswnwwweenw
enwnenwnewenwnenenwnwwnene
neswnwnenenwnwswenenwnewse
nwweneenenewswneswnwenenesenwnewnw
neeswsewswnwnewswswswsesewnwneseswswsw
senwneswwnwnenenwnenenesenewenenenenene
sesewneswswsweenwsesweswnw
ewneesewneeeenesenweswnesesweee
swsewwwwnwwwewnenwsewwwsewwnene
swswnwseswesesweswneseswswseswswnwswnwswse
swseswswneseeseswneswenwneeswwnwswnww
weeswswnwswswswnwnwswswsweeswswswsww
nesewnwswseswwenweweseeeswnesene
sweseswnesenwseesesweneeswsesenwnesw
nwseeswseseeneswseswnwsweswseswsewse
sesewsesesweseeneenwesee
seneesewswewswnwsesw
seseseeseseseesesewseenenwnwsesesee
wneeeseseewswswseewnesenenwesenw
eneneeeneewneeenee
eneneneenenenewnenenesenwwnesw
eeeeeseeeenwe
nwnwnwnwnwenwnwnwnwwnw
seenwnenwswsenenwnenenewnenwnenenwnwnw
swenewweeeneseneneneeenweewnesw
nwnwnwnenwnenwnwnwnwse
seswswseesewswwseswneswswseenw
senewsewswnwewneswsewneenewwswsw
nenenwenwnenwswnenwnwne
nenenenenenwnenenewneneneswenene
eseneseseseswseseseseeee
wseseeneeseswseseseseenwwsewseswse
enwneeneneeneeseweeeeeewnesw
swswswswswswenwneswswwswswswneseswswe
eeeeeweneeee
wswswswnwewswswnwnweswwwswweswwse
nenenewnewseneneesweenweeneneeene
nenwneseswnwnenenewsesenenenwnesenewsenene
wswsenwswswseseswsenewneneseseseswswsese
nenwnwneenwswnwenwnwnenwnenwnwnwnewsw
nwnwwwnwwwwwneswnwwww
senweneswseeseweeseeewenewseee
eseseeeweesesesesesee
senenwnenwnewneeswneseenenwswseneneswne
nenwnenenewseneenenesesenenenewnenene
wnwnenenenewnenwwsenewseeseeswnenw
nwnwswwnesewnweewswnenwenenwnwwene
senwnenwnwnwnenwwnwnwnwwnenwesenwnwnw
seeeeeenwswswesenwnwsewesew
newwswnewsenwwwswwwenwnewwww
neneswnenwseewneneneneneneneneesenewnw
eneeesenewseneweswneeneneeenewe
seesewseeesesenwnwnwsweseseswsesesesee
enweseeeeenweseeswnwseewseeese
eswneeeeeeeenweneeeeesw
senwseseswseseeneseeseseseesewswnewe
nwnwnwenwsenwesenewnwswnwswnwnwnwnwnwnenw
neeneeenwsweeeenwsesweneneeewe
sweenenenewwneneneneenenenene
enweeeeeeneneeneneese
eneeseswsewsenwneswsweseswneeesenesw
enwwnwswnwnwwwwnwewnwwsewnwnwnw
wnwwwnwwewswnww
nenwneeswweswnesweneneeeswswewse
eswweseeseneenweneeewenwe
eswswswnweswswsweswswwswswnwsenewswnwne
swwseweneeeeweseeseesenenw
eeeeeenesweseeeeswnesweenwe
swwswneswwswwwswnewswwwewwswnw
nwneswnwswnenenwneenwnwenwnwnwnenwew
newwnwsewsewnwwweneswswnwwnwnew
neesweswswnwseswwwwwswneneswsenwwww
wswnewwwwwswneseswnwneneswwswwsew
eneswwwswnewwswswweswwwwswnwnenw
eswseneseswswsewseseswseseswseswswnwne
eeeeeeeeeeewswenenwee
sewnenenenewnwnwseeenwseswswweee
nenenenenenwseseneneneenenewneswswwnwnenw
wswswnwswnwseswseneswswswnewsweswsesw
eeewnenwneswwseseneeswseesewww
wsesweswswswswswswswswswswswnwwnwswenw
nwseswswswwswswsene
sewwwswwnwswswwnewswwnesewsesww
swwswswswswswswwswsenwne
nwnenwnwsewwnwwnwnwnwnwseww
swewseewnwenweseseneswnwenwsweesee
eeweswswneneenwesweneeeeseee
wseseseesesenewnwnesewswseseseesee
wswwnesewwnwwwnwseneswwwwew
nwwnenwwswnwweseeeswseseneenwwnwne
sewwwnwwsewwnwesesewswnwnwwnewe
newsesenwwsenesesewwneseseseseseneseesw
sweweseneseswnwswweswseswnwswnwnwsww
swsenenwnwneswnwnenwnenwnenenwnwewnw
swswwewwswsewewwwsenwwwnewwww
nenwsenwnwswnenwnenenwsenenwwnwnesenwne
seseseeeesewswnesesenweseseneewse
esesenweswseseneweeseseesesesee
wwswsewwwnewenewwwwwwnwnww
nwneseneeseeeseswnewseeswse
nwneneneeneenenese
eswseeeseesenweesesenwweewsesesese
wneweseswswnwswneneeeeene
nenewnwnenenwswsenenenesenwswneswswnenenw
sewnenwseswsesenwswnenenwnwnwnwnwwenw
nwnwnwenenwnwnwnwswnenenwnwsewnwsenwse
sesenewwnenwwnwwneswwswnwewenenwsw
neneewnwnesenwnwnenewneswnenwnenenwenw
neseenweneswnwnwneswwnwnwnwnenenenwnenw
nenenweswwneswnwnenenenweneenwswnene
swnenesenenenenenenenenwnenenwene
wneswnenwswwswseenwwwwwsew
sewwwnenewwwwwnesewwwswsewwne
nesenwneenesweeenwenene
seseeseeeswsenwseseeseseesesewsenw
nwnenwnwneneeenwswnenwswnwswneenwnwnwnenw
seneneeesweewesewwsewwnewee
nwwnenwsewnwwnwnwnwenenwnwwsewsenwnw
wswwwwwwswswsewneneewseenenwnw
nwseeswesesesesenwseenweeeeeeesw
seenewnenwswsenwnenesewnwswsenwnewnenw
wnwnewseswneeneeweenwnenweenese
swswsweenwnesenwswwneswseswwseneswse
nwesenenwnewneenwnwnwnwneswsesenwnwnenene
enenewneneneneneswewswneeneweneese
nwwwnwsenwnwwwnwwnwnenww
nwnwwnwnwnwnenwnwnwnwseswnwnwnwnew
swnewnenwneswenesenenwneewneneswnenesw
nwsewnwnwwnwswnewnenwwnwnwse
seneneswneneewnenwnenenewneswenenwsene
sweseneeeenewenenenweneenewene
enwwwwwwwnwwwsewwwswnewsene
sewewseswwsenwnwwesewewwwwnenew
nenwnwnwnwewnwsww

View File

@@ -0,0 +1,2 @@
12092626
4707356

File diff suppressed because it is too large Load Diff

View File

@@ -48,6 +48,85 @@
//! Your goal is to determine the number of messages that completely match rule 0. In the above example, ababbb and abbbab match, but bababa, aaabbb, and aaaabbb do not, producing the answer 2. The whole message must match all of rule 0; there can't be extra unmatched characters in the message. (For example, aaaabbb might appear to match rule 0 above, but it has an extra unmatched b on the end.) //! Your goal is to determine the number of messages that completely match rule 0. In the above example, ababbb and abbbab match, but bababa, aaabbb, and aaaabbb do not, producing the answer 2. The whole message must match all of rule 0; there can't be extra unmatched characters in the message. (For example, aaaabbb might appear to match rule 0 above, but it has an extra unmatched b on the end.)
//! //!
//! How many messages completely match rule 0? //! How many messages completely match rule 0?
//!
//! --- Part Two ---
//! As you look over the list of messages, you realize your matching rules aren't quite right. To fix them, completely replace rules 8: 42 and 11: 42 31 with the following:
//!
//! 8: 42 | 42 8
//! 11: 42 31 | 42 11 31
//! This small change has a big impact: now, the rules do contain loops, and the list of messages they could hypothetically match is infinite. You'll need to determine how these changes affect which messages are valid.
//!
//! Fortunately, many of the rules are unaffected by this change; it might help to start by looking at which rules always match the same set of values and how those rules (especially rules 42 and 31) are used by the new versions of rules 8 and 11.
//!
//! (Remember, you only need to handle the rules you have; building a solution that could handle any hypothetical combination of rules would be significantly more difficult.)
//!
//! For example:
//!
//! 42: 9 14 | 10 1
//! 9: 14 27 | 1 26
//! 10: 23 14 | 28 1
//! 1: "a"
//! 11: 42 31
//! 5: 1 14 | 15 1
//! 19: 14 1 | 14 14
//! 12: 24 14 | 19 1
//! 16: 15 1 | 14 14
//! 31: 14 17 | 1 13
//! 6: 14 14 | 1 14
//! 2: 1 24 | 14 4
//! 0: 8 11
//! 13: 14 3 | 1 12
//! 15: 1 | 14
//! 17: 14 2 | 1 7
//! 23: 25 1 | 22 14
//! 28: 16 1
//! 4: 1 1
//! 20: 14 14 | 1 15
//! 3: 5 14 | 16 1
//! 27: 1 6 | 14 18
//! 14: "b"
//! 21: 14 1 | 1 14
//! 25: 1 1 | 1 14
//! 22: 14 14
//! 8: 42
//! 26: 14 22 | 1 20
//! 18: 15 15
//! 7: 14 5 | 1 21
//! 24: 14 1
//!
//! abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa
//! bbabbbbaabaabba
//! babbbbaabbbbbabbbbbbaabaaabaaa
//! aaabbbbbbaaaabaababaabababbabaaabbababababaaa
//! bbbbbbbaaaabbbbaaabbabaaa
//! bbbababbbbaaaaaaaabbababaaababaabab
//! ababaaaaaabaaab
//! ababaaaaabbbaba
//! baabbaaaabbaaaababbaababb
//! abbbbabbbbaaaababbbbbbaaaababb
//! aaaaabbaabaaaaababaa
//! aaaabbaaaabbaaa
//! aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
//! babaaabbbaaabaababbaabababaaab
//! aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba
//! Without updating rules 8 and 11, these rules only match three messages: bbabbbbaabaabba, ababaaaaaabaaab, and ababaaaaabbbaba.
//!
//! However, after updating rules 8 and 11, a total of 12 messages match:
//!
//! bbabbbbaabaabba
//! babbbbaabbbbbabbbbbbaabaaabaaa
//! aaabbbbbbaaaabaababaabababbabaaabbababababaaa
//! bbbbbbbaaaabbbbaaabbabaaa
//! bbbababbbbaaaaaaaabbababaaababaabab
//! ababaaaaaabaaab
//! ababaaaaabbbaba
//! baabbaaaabbaaaababbaababb
//! abbbbabbbbaaaababbbbbbaaaababb
//! aaaaabbaabaaaaababaa
//! aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
//! aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba
//! After updating rules 8 and 11, how many messages completely match rule 0?
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
@@ -88,6 +167,7 @@ struct Resolver {
impl Resolver { impl Resolver {
fn resolve(&mut self, e: &Entry) -> String { fn resolve(&mut self, e: &Entry) -> String {
assert_ne!(e, &Entry::Rule(0));
if let Some(v) = self.resolved.get(e) { if let Some(v) = self.resolved.get(e) {
return v.to_string(); return v.to_string();
} }
@@ -104,8 +184,10 @@ impl Resolver {
.clone() .clone()
.iter() .iter()
.map(|rule| { .map(|rule| {
let letters: Vec<_> = rule.iter().map(|e| self.resolve(e)).collect(); rule.iter()
letters.join("") .map(|e| self.resolve(e))
.collect::<Vec<_>>()
.join("")
}) })
.collect(); .collect();
let s = subrules.join("|"); let s = subrules.join("|");
@@ -121,14 +203,30 @@ impl Resolver {
} }
fn expand_rulemap(rule_map: HashMap<usize, Vec<Vec<Entry>>>) -> Regex { fn expand_rulemap(rule_map: HashMap<usize, Vec<Vec<Entry>>>) -> Regex {
// Hack
let part2 = rule_map.len() > 8 && rule_map[&8].len() > 1;
let mut r = Resolver { let mut r = Resolver {
rule_map, rule_map,
resolved: HashMap::new(), resolved: HashMap::new(),
}; };
let rule_zero = r.rule_map[&0][0].clone(); let re = if part2 {
let re = rule_zero let hack = (1..10_usize)
.iter() .map(|i| {
.fold("".to_string(), |acc, e| format!("{}{}", acc, r.resolve(e))); format!(
"{}{}",
r.resolve(&Entry::Rule(42)).repeat(i),
r.resolve(&Entry::Rule(31)).repeat(i)
)
})
.collect::<Vec<_>>()
.join("|");
format!("({})+({})", r.resolve(&Entry::Rule(42)), hack)
} else {
let rule_zero = r.rule_map[&0][0].clone();
rule_zero
.iter()
.fold("".to_string(), |acc, e| format!("{}{}", acc, r.resolve(e)))
};
Regex::new(&format!(r"^{}$", re)).unwrap() Regex::new(&format!(r"^{}$", re)).unwrap()
} }
@@ -146,13 +244,7 @@ fn make_rules(lines: Vec<String>) -> Regex {
sub.split(' ') sub.split(' ')
.map(|p| match p.parse() { .map(|p| match p.parse() {
Ok(n) => Entry::Rule(n), Ok(n) => Entry::Rule(n),
Err(_) => Entry::Char( Err(_) => Entry::Char(p[1..p.len() - 1].to_string()),
p.strip_prefix("\"")
.unwrap()
.strip_suffix("\"")
.unwrap()
.to_string(),
),
}) })
.collect() .collect()
}) })
@@ -162,8 +254,8 @@ fn make_rules(lines: Vec<String>) -> Regex {
expand_rulemap(rules) expand_rulemap(rules)
} }
#[aoc_generator(day19)] #[aoc_generator(day19, part1)]
fn generator(input: &str) -> Input { fn generator_part1(input: &str) -> Input {
let mut it = input.split("\n\n"); let mut it = input.split("\n\n");
let rules = make_rules( let rules = make_rules(
it.next() it.next()
@@ -191,10 +283,51 @@ fn solution1(input: &Input) -> usize {
.count() .count()
} }
#[aoc_generator(day19, part2)]
fn generator_part2(input: &str) -> Input {
let mut it = input.split("\n\n");
let rules = make_rules(
it.next()
.unwrap()
.split('\n')
.map(|s| s.trim())
.map(|s| {
if s.starts_with("8:") {
return "8: 42 | 42 8";
}
if s.starts_with("11:") {
return "11: 42 31 | 42 11 31";
}
s
})
.map(|s| s.to_string())
.collect(),
);
let messages = it
.next()
.unwrap()
.split('\n')
.map(|s| s.trim().to_string())
.collect();
Input { rules, messages }
}
#[aoc(day19, part2)]
fn solution2(input: &Input) -> usize {
input
.messages
.iter()
.filter(|msg| input.rules.is_match(msg))
.count()
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq;
use super::*; use super::*;
const INPUT: &'static str = r#"0: 4 1 5 const INPUT1: &'static str = r#"0: 4 1 5
1: 2 3 | 3 2 1: 2 3 | 3 2
2: 4 4 | 5 5 2: 4 4 | 5 5
3: 4 5 | 5 4 3: 4 5 | 5 4
@@ -209,13 +342,13 @@ mod tests {
#[test] #[test]
fn part1() { fn part1() {
assert_eq!(solution1(&generator(INPUT)), 2); assert_eq!(solution1(&generator_part1(INPUT1)), 2);
} }
#[test] #[test]
fn parse() { fn parse1() {
assert_eq!( assert_eq!(
generator(INPUT), generator_part1(INPUT1),
Input { Input {
rules: Regex::new("^a((aa|bb)(ab|ba)|(ab|ba)(aa|bb))b$").unwrap(), rules: Regex::new("^a((aa|bb)(ab|ba)|(ab|ba)(aa|bb))b$").unwrap(),
messages: vec!["ababbb", "bababa", "abbbab", "aaabbb", "aaaabbb",] messages: vec!["ababbb", "bababa", "abbbab", "aaabbb", "aaaabbb",]
@@ -242,4 +375,82 @@ mod tests {
Regex::new("^(aa|bb)$").unwrap().as_str() Regex::new("^(aa|bb)$").unwrap().as_str()
); );
} }
const INPUT2: &'static str = r#"42: 9 14 | 10 1
9: 14 27 | 1 26
10: 23 14 | 28 1
1: "a"
11: 42 31
5: 1 14 | 15 1
19: 14 1 | 14 14
12: 24 14 | 19 1
16: 15 1 | 14 14
31: 14 17 | 1 13
6: 14 14 | 1 14
2: 1 24 | 14 4
0: 8 11
13: 14 3 | 1 12
15: 1 | 14
17: 14 2 | 1 7
23: 25 1 | 22 14
28: 16 1
4: 1 1
20: 14 14 | 1 15
3: 5 14 | 16 1
27: 1 6 | 14 18
14: "b"
21: 14 1 | 1 14
25: 1 1 | 1 14
22: 14 14
8: 42
26: 14 22 | 1 20
18: 15 15
7: 14 5 | 1 21
24: 14 1
abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa
bbabbbbaabaabba
babbbbaabbbbbabbbbbbaabaaabaaa
aaabbbbbbaaaabaababaabababbabaaabbababababaaa
bbbbbbbaaaabbbbaaabbabaaa
bbbababbbbaaaaaaaabbababaaababaabab
ababaaaaaabaaab
ababaaaaabbbaba
baabbaaaabbaaaababbaababb
abbbbabbbbaaaababbbbbbaaaababb
aaaaabbaabaaaaababaa
aaaabbaaaabbaaa
aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
babaaabbbaaabaababbaabababaaab
aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba"#;
#[test]
fn part2_matches() {
let input = generator_part2(INPUT2);
assert_eq!(
input
.messages
.iter()
.filter(|msg| input.rules.is_match(msg))
.collect::<Vec<_>>(),
vec![
"bbabbbbaabaabba",
"babbbbaabbbbbabbbbbbaabaaabaaa",
"aaabbbbbbaaaabaababaabababbabaaabbababababaaa",
"bbbbbbbaaaabbbbaaabbabaaa",
"bbbababbbbaaaaaaaabbababaaababaabab",
"ababaaaaaabaaab",
"ababaaaaabbbaba",
"baabbaaaabbaaaababbaababb",
"abbbbabbbbaaaababbbbbbaaaababb",
"aaaaabbaabaaaaababaa",
"aaaabbaabbaaaaaaabbbabbbaaabbaabaaa",
"aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba",
]
);
}
#[test]
fn part2() {
assert_eq!(solution2(&generator_part2(INPUT2)), 12);
}
} }

987
2020/src/day20.rs Normal file
View File

@@ -0,0 +1,987 @@
//! --- Day 20: Jurassic Jigsaw ---
//! The high-speed train leaves the forest and quickly carries you south. You can even see a desert in the distance! Since you have some spare time, you might as well see if there was anything interesting in the image the Mythical Information Bureau satellite captured.
//!
//! After decoding the satellite messages, you discover that the data actually contains many small images created by the satellite's camera array. The camera array consists of many cameras; rather than produce a single square image, they produce many smaller square image tiles that need to be reassembled back into a single image.
//!
//! Each camera in the camera array returns a single monochrome image tile with a random unique ID number. The tiles (your puzzle input) arrived in a random order.
//!
//! Worse yet, the camera array appears to be malfunctioning: each image tile has been rotated and flipped to a random orientation. Your first task is to reassemble the original image by orienting the tiles so they fit together.
//!
//! To show how the tiles should be reassembled, each tile's image data includes a border that should line up exactly with its adjacent tiles. All tiles have this border, and the border lines up exactly when the tiles are both oriented correctly. Tiles at the edge of the image also have this border, but the outermost edges won't line up with any other tiles.
//!
//! For example, suppose you have the following nine tiles:
//!
//! Tile 2311:
//! ..##.#..#.
//! ##..#.....
//! #...##..#.
//! ####.#...#
//! ##.##.###.
//! ##...#.###
//! .#.#.#..##
//! ..#....#..
//! ###...#.#.
//! ..###..###
//!
//! Tile 1951:
//! #.##...##.
//! #.####...#
//! .....#..##
//! #...######
//! .##.#....#
//! .###.#####
//! ###.##.##.
//! .###....#.
//! ..#.#..#.#
//! #...##.#..
//!
//! Tile 1171:
//! ####...##.
//! #..##.#..#
//! ##.#..#.#.
//! .###.####.
//! ..###.####
//! .##....##.
//! .#...####.
//! #.##.####.
//! ####..#...
//! .....##...
//!
//! Tile 1427:
//! ###.##.#..
//! .#..#.##..
//! .#.##.#..#
//! #.#.#.##.#
//! ....#...##
//! ...##..##.
//! ...#.#####
//! .#.####.#.
//! ..#..###.#
//! ..##.#..#.
//!
//! Tile 1489:
//! ##.#.#....
//! ..##...#..
//! .##..##...
//! ..#...#...
//! #####...#.
//! #..#.#.#.#
//! ...#.#.#..
//! ##.#...##.
//! ..##.##.##
//! ###.##.#..
//!
//! Tile 2473:
//! #....####.
//! #..#.##...
//! #.##..#...
//! ######.#.#
//! .#...#.#.#
//! .#########
//! .###.#..#.
//! ########.#
//! ##...##.#.
//! ..###.#.#.
//!
//! Tile 2971:
//! ..#.#....#
//! #...###...
//! #.#.###...
//! ##.##..#..
//! .#####..##
//! .#..####.#
//! #..#.#..#.
//! ..####.###
//! ..#.#.###.
//! ...#.#.#.#
//!
//! Tile 2729:
//! ...#.#.#.#
//! ####.#....
//! ..#.#.....
//! ....#..#.#
//! .##..##.#.
//! .#.####...
//! ####.#.#..
//! ##.####...
//! ##..#.##..
//! #.##...##.
//!
//! Tile 3079:
//! #.#.#####.
//! .#..######
//! ..#.......
//! ######....
//! ####.#..#.
//! .#...#.##.
//! #.#####.##
//! ..#.###...
//! ..#.......
//! ..#.###...
//! By rotating, flipping, and rearranging them, you can find a square arrangement that causes all adjacent borders to line up:
//!
//! #...##.#.. ..###..### #.#.#####.
//! ..#.#..#.# ###...#.#. .#..######
//! .###....#. ..#....#.. ..#.......
//! ###.##.##. .#.#.#..## ######....
//! .###.##### ##...#.### ####.#..#.
//! .##.#....# ##.##.###. .#...#.##.
//! #...###### ####.#...# #.#####.##
//! .....#..## #...##..#. ..#.###...
//! #.####...# ##..#..... ..#.......
//! #.##...##. ..##.#..#. ..#.###...
//!
//! #.##...##. ..##.#..#. ..#.###...
//! ##..#.##.. ..#..###.# ##.##....#
//! ##.####... .#.####.#. ..#.###..#
//! ####.#.#.. ...#.##### ###.#..###
//! .#.####... ...##..##. .######.##
//! .##..##.#. ....#...## #.#.#.#...
//! ....#..#.# #.#.#.##.# #.###.###.
//! ..#.#..... .#.##.#..# #.###.##..
//! ####.#.... .#..#.##.. .######...
//! ...#.#.#.# ###.##.#.. .##...####
//!
//! ...#.#.#.# ###.##.#.. .##...####
//! ..#.#.###. ..##.##.## #..#.##..#
//! ..####.### ##.#...##. .#.#..#.##
//! #..#.#..#. ...#.#.#.. .####.###.
//! .#..####.# #..#.#.#.# ####.###..
//! .#####..## #####...#. .##....##.
//! ##.##..#.. ..#...#... .####...#.
//! #.#.###... .##..##... .####.##.#
//! #...###... ..##...#.. ...#..####
//! ..#.#....# ##.#.#.... ...##.....
//! For reference, the IDs of the above tiles are:
//!
//! 1951 2311 3079
//! 2729 1427 2473
//! 2971 1489 1171
//! To check that you've assembled the image correctly, multiply the IDs of the four corner tiles together. If you do this with the assembled tiles from the example above, you get 1951 * 3079 * 2971 * 1171 = 20899048083289.
//!
//! Assemble the tiles into an image. What do you get if you multiply together the IDs of the four corner tiles?
//!
//! --- Part Two ---
//! Now, you're ready to check the image for sea monsters.
//!
//! The borders of each tile are not part of the actual image; start by removing them.
//!
//! In the example above, the tiles become:
//!
//! .#.#..#. ##...#.# #..#####
//! ###....# .#....#. .#......
//! ##.##.## #.#.#..# #####...
//! ###.#### #...#.## ###.#..#
//! ##.#.... #.##.### #...#.##
//! ...##### ###.#... .#####.#
//! ....#..# ...##..# .#.###..
//! .####... #..#.... .#......
//!
//! #..#.##. .#..###. #.##....
//! #.####.. #.####.# .#.###..
//! ###.#.#. ..#.#### ##.#..##
//! #.####.. ..##..## ######.#
//! ##..##.# ...#...# .#.#.#..
//! ...#..#. .#.#.##. .###.###
//! .#.#.... #.##.#.. .###.##.
//! ###.#... #..#.##. ######..
//!
//! .#.#.### .##.##.# ..#.##..
//! .####.## #.#...## #.#..#.#
//! ..#.#..# ..#.#.#. ####.###
//! #..####. ..#.#.#. ###.###.
//! #####..# ####...# ##....##
//! #.##..#. .#...#.. ####...#
//! .#.###.. ##..##.. ####.##.
//! ...###.. .##...#. ..#..###
//! Remove the gaps to form the actual image:
//!
//! .#.#..#.##...#.##..#####
//! ###....#.#....#..#......
//! ##.##.###.#.#..######...
//! ###.#####...#.#####.#..#
//! ##.#....#.##.####...#.##
//! ...########.#....#####.#
//! ....#..#...##..#.#.###..
//! .####...#..#.....#......
//! #..#.##..#..###.#.##....
//! #.####..#.####.#.#.###..
//! ###.#.#...#.######.#..##
//! #.####....##..########.#
//! ##..##.#...#...#.#.#.#..
//! ...#..#..#.#.##..###.###
//! .#.#....#.##.#...###.##.
//! ###.#...#..#.##.######..
//! .#.#.###.##.##.#..#.##..
//! .####.###.#...###.#..#.#
//! ..#.#..#..#.#.#.####.###
//! #..####...#.#.#.###.###.
//! #####..#####...###....##
//! #.##..#..#...#..####...#
//! .#.###..##..##..####.##.
//! ...###...##...#...#..###
//! Now, you're ready to search for sea monsters! Because your image is monochrome, a sea monster will look like this:
//!
//! #
//! # ## ## ###
//! # # # # # #
//! When looking for this pattern in the image, the spaces can be anything; only the # need to match. Also, you might need to rotate or flip your image before it's oriented correctly to find sea monsters. In the above image, after flipping and rotating it to the appropriate orientation, there are two sea monsters (marked with O):
//!
//! .####...#####..#...###..
//! #####..#..#.#.####..#.#.
//! .#.#...#.###...#.##.O#..
//! #.O.##.OO#.#.OO.##.OOO##
//! ..#O.#O#.O##O..O.#O##.##
//! ...#.#..##.##...#..#..##
//! #.##.#..#.#..#..##.#.#..
//! .###.##.....#...###.#...
//! #.####.#.#....##.#..#.#.
//! ##...#..#....#..#...####
//! ..#.##...###..#.#####..#
//! ....#.##.#.#####....#...
//! ..##.##.###.....#.##..#.
//! #...#...###..####....##.
//! .#.##...#.##.#.#.###...#
//! #.###.#..####...##..#...
//! #.###...#.##...#.##O###.
//! .O##.#OO.###OO##..OOO##.
//! ..O#.O..O..O.#O##O##.###
//! #.#..##.########..#..##.
//! #.#####..#.#...##..#....
//! #....##..#.#########..##
//! #...#.....#..##...###.##
//! #..###....##.#...##.##.#
//! Determine how rough the waters are in the sea monsters' habitat by counting the number of # that are not part of a sea monster. In the above example, the habitat's water roughness is 273.
//!
//! How many # are not part of a sea monster?
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::ops::{Index, IndexMut};
use std::str::FromStr;
use aoc_runner_derive::{aoc, aoc_generator};
use crate::debug_println;
#[derive(Clone, Default, Hash, Eq, PartialEq)]
struct Tile {
id: usize,
pixels: Vec<u8>,
width: usize,
height: usize,
}
impl fmt::Debug for Tile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Tile {} ({}x{}):\n", self.id, self.width, self.height)?;
for y in 0..self.height {
for x in 0..self.width {
write!(f, "{}", self[(x, y)] as char)?;
}
write!(f, "\n")?;
}
write!(f, "\n")
}
}
impl FromStr for Tile {
type Err = ();
fn from_str(s: &str) -> Result<Tile, ()> {
let mut it = s.split('\n');
let id = it
.next()
.expect("couldn't get first line of tile")
.trim()
.split(' ')
.skip(1)
.next()
.expect("couldn't get second word of tile header")
.strip_suffix(':')
.expect("couldn't strip ':' from tile header")
.parse()
.expect("couldn't parse tile number");
let rows: Vec<_> = it.map(|l| l.trim()).collect();
let height = rows.len();
let mut width = 0;
let mut pixels = Vec::with_capacity(height * height);
rows.iter().for_each(|row| {
width = row.len();
pixels.extend(row.bytes());
});
Ok(Tile {
id,
pixels,
height,
width,
})
}
}
impl IndexMut<(usize, usize)> for Tile {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
&mut self.pixels[x + y * self.width]
}
}
impl Index<(usize, usize)> for Tile {
type Output = u8;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
#[cfg(any(debug_assertions, test))]
fn border_to_str(border: &[u8]) -> String {
std::str::from_utf8(border).unwrap().to_string()
}
impl Tile {
/// Copy `t` into self @ x_off,y_off.
fn blit(&mut self, t: &Tile, x_off: usize, y_off: usize) {
debug_println!(
"blitting tile {} {}x{} @ {},{}",
t.id,
t.width,
t.height,
x_off,
y_off
);
(0..t.height)
.for_each(|y| (0..t.width).for_each(|x| self[(x_off + x, y_off + y)] = t[(x, y)]));
}
/// Builds a set containing all the borders of this tile and their reverse (useful if the tile
/// is in the wrong orientation).
fn border_set(&self) -> HashSet<Vec<u8>> {
let mut set = HashSet::new();
set.insert(self.top_border());
set.insert(self.right_border());
set.insert(self.bottom_border());
set.insert(self.left_border());
let rev_set: HashSet<_> = set
.iter()
.map(|b| {
let mut b = b.clone();
b.reverse();
b
})
.collect();
set.union(&rev_set).cloned().collect()
}
fn top_border(&self) -> Vec<u8> {
(0..self.width).map(|x| self[(x, 0)]).collect()
}
fn right_border(&self) -> Vec<u8> {
(0..self.height)
.map(|y| self[(self.width - 1, y)])
.collect()
}
fn bottom_border(&self) -> Vec<u8> {
(0..self.width)
.map(|x| self[(x, self.height - 1)])
.collect()
}
fn left_border(&self) -> Vec<u8> {
(0..self.height).map(|y| self[(0, y)]).collect()
}
fn strip_border(&self) -> Tile {
let pixels = (1..self.height - 1)
.map(|y| (1..self.width - 1).map(move |x| self[(x, y)]))
.flatten()
.collect();
Tile {
id: self.id,
width: self.width - 2,
height: self.height - 2,
pixels,
}
}
fn search(&self, needle: &Tile, x_off: usize, y_off: usize) -> bool {
for n_y in 0..needle.height {
for n_x in 0..needle.width {
if needle[(n_x, n_y)] != b'#' {
continue;
}
if self[(x_off + n_x, y_off + n_y)] != b'#' {
return false;
}
}
}
true
}
fn count_hashes(&self) -> usize {
self.pixels.iter().filter(|b| *b == &b'#').count()
}
fn rotate90(&self) -> Tile {
let pixels = (0..self.height)
.map(|y| (0..self.width).map(move |x| self[(y, self.height - x - 1)]))
.flatten()
.collect();
Tile {
id: self.id,
width: self.width,
height: self.height,
pixels,
}
}
/// Slow but easy to implement.
fn rotate180(&self) -> Tile {
self.rotate90().rotate90()
}
/// Slow but easy to implement.
fn rotate270(&self) -> Tile {
self.rotate180().rotate90()
}
fn flip_horizontal(&self) -> Tile {
let pixels = (0..self.height)
.map(|y| (0..self.width).map(move |x| self[(self.width - x - 1, y)]))
.flatten()
.collect();
Tile {
id: self.id,
width: self.width,
height: self.height,
pixels,
}
}
/// Finds number of occurrences of needle in self. A match requires all '#' in needle to be
/// found in self. Extra '#' in self are ignored. The returned vector is the x,y of the upper
/// left pixel for the match.
fn find_hashes(&self, needle: &Tile) -> Vec<(usize, usize)> {
let mut res = Vec::new();
for y_off in 0..self.height - needle.height {
for x_off in 0..self.width - needle.width {
if self.search(needle, x_off, y_off) {
res.push((x_off, y_off));
}
}
}
res
}
}
/// Tries various orientations, until predicate matches.
fn reorient<F>(img: &Tile, predicate: F) -> Option<Tile>
where
F: Fn(&Tile) -> bool,
{
if predicate(&img) {
return Some(img.clone());
}
let rotated = img.rotate90();
if predicate(&rotated) {
return Some(rotated);
}
let rotated = img.rotate180();
if predicate(&rotated) {
return Some(rotated);
}
let rotated = img.rotate270();
if predicate(&rotated) {
return Some(rotated);
}
let horiz = img.flip_horizontal();
if predicate(&horiz) {
return Some(horiz);
}
let rotated = horiz.rotate90();
if predicate(&rotated) {
return Some(rotated);
}
let rotated = horiz.rotate180();
if predicate(&rotated) {
return Some(rotated);
}
let rotated = horiz.rotate270();
if predicate(&rotated) {
return Some(rotated);
}
None
}
fn stitch(tiles: &[Tile]) -> Tile {
// Make sure there's a square number of tiles.
let sqrt = (tiles.len() as f32).sqrt() as usize;
assert_eq!(sqrt * sqrt, tiles.len());
let width = sqrt * (tiles[0].width - 2);
let height = sqrt * (tiles[0].height - 2);
let mut image = Tile {
id: 0,
width,
height,
pixels: vec![b'X'; width * height],
};
let mut border_counts = HashMap::new();
let mut border_map = HashMap::new();
tiles.iter().for_each(|t| {
t.border_set().iter().for_each(|b| {
border_map.insert(b.clone(), t.id);
let c = border_counts.entry(b.clone()).or_insert(0);
*c += 1;
})
});
#[cfg(any(debug_assertions, test))]
border_counts.iter().for_each(|(b, c)| {
let _ = b;
let _ = c;
debug_println!("{}: {}", border_to_str(b), c);
});
let edge_borders: HashSet<_> = border_counts
.iter()
.filter(|(_b, c)| **c == 1)
.map(|(b, _c)| b)
.collect();
// Count the number of borders that are in edge_borders. The answer should be 0, 1 or 2
// if the tile is a middle, edge or corner, respectively.
let (corner_tiles, _edge_tiles, _center_tiles) = tiles.iter().fold(
(vec![], vec![], vec![]),
|(mut corner, mut edge, mut center), t| {
let edge_count = vec![
t.top_border(),
t.right_border(),
t.bottom_border(),
t.left_border(),
]
.into_iter()
.filter(|b| edge_borders.contains(b))
.count();
match edge_count {
0 => center.push(t),
1 => edge.push(t),
2 => corner.push(t),
c => panic!(format!("unexpected edge_count for {:?}: {}", t, c)),
};
(corner, edge, center)
},
);
let mut tile_map = vec![vec![None; sqrt]; sqrt];
let corner = corner_tiles[0];
// Make this the upper-left corner at 0,0.
let corner = reorient(corner, |im| {
edge_borders.contains(&im.left_border()) && edge_borders.contains(&im.top_border())
})
.expect("couldn't find proper orientation");
let mut remaining_tiles: HashSet<_> = tiles.iter().filter(|t| t.id != corner.id).collect();
let mut last = corner.clone();
tile_map[0][0] = Some(corner);
(0..sqrt)
.map(|y| (0..sqrt).map(move |x| (x, y)))
.flatten()
.skip(1)
.for_each(|(x, y)| {
debug_println!("Solving for tile {},{}", x, y);
let mut local_last = last.clone();
let orientation_check: Box<dyn Fn(&Tile) -> bool> = if y == 0 {
debug_println!("search for top row tiles");
// Top row, tiles should be match the tile to the left and have their top_border in the
// edge set.
// Find a tile that matches last and reorient so it's edge is on top.
Box::new(|im: &Tile| {
edge_borders.contains(&im.top_border())
&& im.left_border() == local_last.right_border()
})
} else if x == 0 {
debug_println!("search for left column tiles");
// When we're in the first column, we need to match against the tile above, instead of
// the last tile on the previous row.
local_last = tile_map[0][y - 1]
.as_ref()
.expect(&format!("couldn't file tile above {},{}", x, y))
.clone();
Box::new(|im: &Tile| {
edge_borders.contains(&im.left_border())
&& im.top_border() == local_last.bottom_border()
})
} else {
debug_println!("search for regular tiles");
// Default, last is to the left match shared edge.
Box::new(|im: &Tile| im.left_border() == local_last.right_border())
};
debug_println!("last tile {}", last.id);
let mut found: Option<Tile> = None;
for candidate in &remaining_tiles {
match reorient(candidate, &orientation_check) {
Some(good) => {
debug_println!("found3 {}", good.id);
found = Some(good);
break;
}
None => continue,
};
}
match found {
Some(rm) => {
debug_println!(
"rm3 {} {:?}",
rm.id,
remaining_tiles.iter().map(|t| t.id).collect::<Vec<_>>()
);
last = rm.clone();
tile_map[x][y] = Some(last.clone());
let rm = remaining_tiles
.iter()
.filter(|t| t.id == rm.id)
.nth(0)
.expect(&format!("Couldn't find {} in remaining_tiles", rm.id))
.clone();
remaining_tiles.remove(rm);
}
None => panic!("couldn't find match for {},{}", x, y),
};
});
debug_println!("Stitched titles");
#[cfg(debug_assertions)]
(0..sqrt).for_each(|y| {
let row_ids: Vec<_> = (0..sqrt)
.map(|x| tile_map[x][y].as_ref().unwrap().id)
.collect();
debug_println!("{:?}", row_ids);
});
(0..sqrt)
.map(|y| (0..sqrt).map(move |x| (x, y)))
.flatten()
.for_each(|(x, y)| {
let t = tile_map[x][y]
.as_ref()
.expect(&format!("missing tile {},{} in completed tile_map", x, y));
let out = t.strip_border();
image.blit(&out, x * out.width, y * out.height);
});
// TODO(wathiede) paste oriented into image.
image
}
#[aoc_generator(day20)]
fn generator(input: &str) -> Vec<Tile> {
input
.split("\n\n")
.map(|s| s.parse().expect("failed to parse tile"))
.collect()
}
fn seamonster() -> Tile {
const MONSTER: &'static str = r#"Tile 666:
..................#.
#....##....##....###
.#..#..#..#..#..#..."#;
MONSTER.parse().expect("failed to parse seamonster")
}
#[aoc(day20, part1)]
fn solution1(tiles: &[Tile]) -> usize {
let mut border_counts = HashMap::new();
tiles.iter().for_each(|t| {
t.border_set().iter().for_each(|b| {
let c = border_counts.entry(b.clone()).or_insert(0);
*c += 1;
})
});
let corner_tiles: Vec<_> = tiles
.iter()
.filter(|t| {
let matches: usize = t.border_set().iter().map(|b| border_counts[b]).sum();
matches == 12
})
.collect();
corner_tiles.iter().map(|t| t.id).product()
}
fn habitat(img: &Tile) -> usize {
let monster = seamonster();
let num_monsters = img.find_hashes(&monster).len();
img.count_hashes() - (num_monsters * monster.count_hashes())
}
fn contains_seamonster(t: &Tile) -> bool {
let monster = seamonster();
t.find_hashes(&monster).len() > 0
}
#[aoc(day20, part2)]
fn solution2(tiles: &[Tile]) -> usize {
let full_map = stitch(tiles);
debug_println!("Full map\n{:?}", full_map);
habitat(&reorient(&full_map, contains_seamonster).expect("couldn't find proper orientation"))
}
#[cfg(test)]
mod tests {
//use pretty_assertions::assert_eq;
use super::*;
const INPUT: &'static str = r#"Tile 2311:
..##.#..#.
##..#.....
#...##..#.
####.#...#
##.##.###.
##...#.###
.#.#.#..##
..#....#..
###...#.#.
..###..###
Tile 1951:
#.##...##.
#.####...#
.....#..##
#...######
.##.#....#
.###.#####
###.##.##.
.###....#.
..#.#..#.#
#...##.#..
Tile 1171:
####...##.
#..##.#..#
##.#..#.#.
.###.####.
..###.####
.##....##.
.#...####.
#.##.####.
####..#...
.....##...
Tile 1427:
###.##.#..
.#..#.##..
.#.##.#..#
#.#.#.##.#
....#...##
...##..##.
...#.#####
.#.####.#.
..#..###.#
..##.#..#.
Tile 1489:
##.#.#....
..##...#..
.##..##...
..#...#...
#####...#.
#..#.#.#.#
...#.#.#..
##.#...##.
..##.##.##
###.##.#..
Tile 2473:
#....####.
#..#.##...
#.##..#...
######.#.#
.#...#.#.#
.#########
.###.#..#.
########.#
##...##.#.
..###.#.#.
Tile 2971:
..#.#....#
#...###...
#.#.###...
##.##..#..
.#####..##
.#..####.#
#..#.#..#.
..####.###
..#.#.###.
...#.#.#.#
Tile 2729:
...#.#.#.#
####.#....
..#.#.....
....#..#.#
.##..##.#.
.#.####...
####.#.#..
##.####...
##..#.##..
#.##...##.
Tile 3079:
#.#.#####.
.#..######
..#.......
######....
####.#..#.
.#...#.##.
#.#####.##
..#.###...
..#.......
..#.###..."#;
#[test]
fn test_generator() {
assert_eq!(
generator(&INPUT).iter().map(|t| t.id).collect::<Vec<_>>(),
vec![2311, 1951, 1171, 1427, 1489, 2473, 2971, 2729, 3079,]
);
}
#[test]
fn test_solution1() {
assert_eq!(solution1(&generator(&INPUT)), 1951 * 3079 * 2971 * 1171);
}
const OUTPUT_IMAGE: &'static str = r#"Tile 0:
.#.#..#.##...#.##..#####
###....#.#....#..#......
##.##.###.#.#..######...
###.#####...#.#####.#..#
##.#....#.##.####...#.##
...########.#....#####.#
....#..#...##..#.#.###..
.####...#..#.....#......
#..#.##..#..###.#.##....
#.####..#.####.#.#.###..
###.#.#...#.######.#..##
#.####....##..########.#
##..##.#...#...#.#.#.#..
...#..#..#.#.##..###.###
.#.#....#.##.#...###.##.
###.#...#..#.##.######..
.#.#.###.##.##.#..#.##..
.####.###.#...###.#..#.#
..#.#..#..#.#.#.####.###
#..####...#.#.#.###.###.
#####..#####...###....##
#.##..#..#...#..####...#
.#.###..##..##..####.##.
...###...##...#...#..###"#;
#[test]
fn make_image() {
let _: Tile = OUTPUT_IMAGE.parse().expect("failed to part want image");
}
#[test]
fn find_monster() {
let img: Tile = OUTPUT_IMAGE.parse().expect("failed to part want image");
let monster = seamonster();
dbg!(&img);
dbg!(&monster);
assert_eq!(img.find_hashes(&monster).len(), 0);
assert_eq!(img.rotate90().find_hashes(&monster).len(), 0);
assert_eq!(img.rotate180().find_hashes(&monster).len(), 0);
assert_eq!(img.rotate270().find_hashes(&monster).len(), 0);
let horiz = img.flip_horizontal();
assert_eq!(horiz.rotate90().find_hashes(&monster).len(), 0);
assert_eq!(horiz.rotate180().find_hashes(&monster).len(), 0);
assert_eq!(horiz.rotate270().find_hashes(&monster).len(), 2);
let correct = horiz.rotate270();
dbg!(&correct);
assert_eq!(correct.find_hashes(&monster), vec![(2, 2), (1, 16),]);
}
#[test]
fn test_reorient() {
let img: Tile = OUTPUT_IMAGE.parse().expect("failed to part want image");
let monster = seamonster();
assert_eq!(
reorient(&img, contains_seamonster)
.expect("couldn't find proper orientation")
.find_hashes(&monster)
.len(),
2
);
}
const TEST_ROTATE: &'static str = "Tile 0:\n#.\n..";
#[test]
fn rotate90() {
let img: Tile = TEST_ROTATE.parse().expect("failed to part rotate image");
let want: Tile = "Tile 0:\n.#\n.."
.parse()
.expect("failed to parse rotate90 want");
assert_eq!(img.rotate90(), want);
}
#[test]
fn rotate180() {
let img: Tile = TEST_ROTATE.parse().expect("failed to part rotate image");
let want: Tile = "Tile 0:\n..\n.#"
.parse()
.expect("failed to parse rotate180 want");
assert_eq!(img.rotate180(), want);
}
#[test]
fn rotate270() {
let img: Tile = TEST_ROTATE.parse().expect("failed to part rotate image");
let want: Tile = "Tile 0:\n..\n#."
.parse()
.expect("failed to parse rotate270 want");
assert_eq!(img.rotate270(), want);
}
#[test]
fn flip_horizontal() {
let img: Tile = TEST_ROTATE.parse().expect("failed to part rotate image");
let want: Tile = "Tile 0:\n.#\n.."
.parse()
.expect("failed to parse flip_horizontal want");
assert_eq!(img.flip_horizontal(), want);
}
#[test]
fn test_habitat() {
let img: Tile = OUTPUT_IMAGE.parse().expect("failed to part want image");
dbg!(img.count_hashes());
dbg!(seamonster().count_hashes());
assert_eq!(
habitat(
&reorient(&img, contains_seamonster).expect("couldn't find proper orientation")
),
273
);
}
#[test]
fn test_stitch() {
let want: Tile = OUTPUT_IMAGE.parse().expect("can't parse stitched input");
let output = stitch(&generator(INPUT));
let output = reorient(&output, contains_seamonster);
match output {
None => assert!(false, "Failed to reorient stitched image to reference"),
Some(im) => {
dbg!(&im);
assert_eq!(
habitat(&im),
273,
"\n im {}\nwant {}",
border_to_str(&im.pixels),
border_to_str(&want.pixels)
);
}
}
}
#[test]
fn test_solution2() {
assert_eq!(solution2(&generator(&INPUT)), 273);
}
}

246
2020/src/day21.rs Normal file
View File

@@ -0,0 +1,246 @@
//! --- Day 21: Allergen Assessment ---
//! You reach the train's last stop and the closest you can get to your vacation island without getting wet. There aren't even any boats here, but nothing can stop you now: you build a raft. You just need a few days' worth of food for your journey.
//!
//! You don't speak the local language, so you can't read any ingredients lists. However, sometimes, allergens are listed in a language you do understand. You should be able to use this information to determine which ingredient contains which allergen and work out which foods are safe to take with you on your trip.
//!
//! You start by compiling a list of foods (your puzzle input), one food per line. Each line includes that food's ingredients list followed by some or all of the allergens the food contains.
//!
//! Each allergen is found in exactly one ingredient. Each ingredient contains zero or one allergen. Allergens aren't always marked; when they're listed (as in (contains nuts, shellfish) after an ingredients list), the ingredient that contains each listed allergen will be somewhere in the corresponding ingredients list. However, even if an allergen isn't listed, the ingredient that contains that allergen could still be present: maybe they forgot to label it, or maybe it was labeled in a language you don't know.
//!
//! For example, consider the following list of foods:
//!
//! mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
//! trh fvjkl sbzzf mxmxvkd (contains dairy)
//! sqjhc fvjkl (contains soy)
//! sqjhc mxmxvkd sbzzf (contains fish)
//! The first food in the list has four ingredients (written in a language you don't understand): mxmxvkd, kfcds, sqjhc, and nhms. While the food might contain other allergens, a few allergens the food definitely contains are listed afterward: dairy and fish.
//!
//! The first step is to determine which ingredients can't possibly contain any of the allergens in any food in your list. In the above example, none of the ingredients kfcds, nhms, sbzzf, or trh can contain an allergen. Counting the number of times any of these ingredients appear in any ingredients list produces 5: they all appear once each except sbzzf, which appears twice.
//!
//! Determine which ingredients cannot possibly contain any of the allergens in your list. How many times do any of those ingredients appear?
//!
//! --- Part Two ---
//! Now that you've isolated the inert ingredients, you should have enough information to figure out which ingredient contains which allergen.
//!
//! In the above example:
//!
//! mxmxvkd contains dairy.
//! sqjhc contains fish.
//! fvjkl contains soy.
//! Arrange the ingredients alphabetically by their allergen and separate them by commas to produce your canonical dangerous ingredient list. (There should not be any spaces in your canonical dangerous ingredient list.) In the above example, this would be mxmxvkd,sqjhc,fvjkl.
//!
//! Time to stock your raft with supplies. What is your canonical dangerous ingredient list?
use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use aoc_runner_derive::{aoc, aoc_generator};
use crate::{debug_print, debug_println};
struct Food {
ingredients: Vec<String>,
allergens: Vec<String>,
}
impl FromStr for Food {
type Err = ();
fn from_str(s: &str) -> Result<Food, ()> {
let ingredients = s
.split(' ')
.take_while(|s| !s.starts_with('('))
.map(|s| s.to_string())
.collect();
let allergens = s
.split(' ')
.skip_while(|s| !s.starts_with('('))
.skip(1)
.map(|s| s.trim_matches(&[',', ')'][..]).to_string())
.collect();
Ok(Food {
ingredients,
allergens,
})
}
}
impl Food {}
fn count_ingredients(foods: &[Food], ingredients: &HashSet<String>) -> usize {
foods
.iter()
.map(|food| {
food.ingredients
.iter()
.filter(|i| ingredients.contains(*i))
.count()
})
.sum()
}
#[aoc_generator(day21)]
fn generator(input: &str) -> Vec<Food> {
input
.split('\n')
.map(|s| s.parse().expect("couldn't parse food"))
.collect()
}
fn find_non_allergens(foods: &[Food]) -> HashSet<String> {
// Find ingredients common across all foods for a given allergen. The remaining ingredients
// are non-allergens.
//
let mut allergen_map = HashMap::new();
let mut ingredient_map = HashMap::new();
foods.iter().for_each(|f| {
f.allergens.iter().for_each(|allergen| {
let a = allergen_map.entry(allergen).or_insert(0);
*a += 1;
f.ingredients.iter().for_each(|ingredient| {
let i = ingredient_map
.entry(ingredient)
.or_insert(HashMap::new())
.entry(allergen)
.or_insert(0);
*i += 1;
});
});
});
ingredient_map
.iter()
.filter(|(_, v)| !v.iter().any(|(a, c)| &allergen_map[a] == c))
.map(|(k, _)| k.to_string())
.collect()
}
#[aoc(day21, part1)]
fn solution1(foods: &[Food]) -> usize {
let ingredients = find_non_allergens(foods);
count_ingredients(&foods, &ingredients)
}
fn allergen_ingredients(foods: &[Food], non_allergens: &HashSet<String>) -> Vec<(String, String)> {
let mut allergen_only = HashMap::new();
foods.iter().for_each(|food| {
debug_print!("{:?}:", food.allergens);
food.ingredients.iter().for_each(|i| {
for a in &food.allergens {
let v = allergen_only
.entry(a)
.or_insert(HashMap::new())
.entry(i)
.or_insert(0);
*v += 1;
}
if !non_allergens.contains(i) {
debug_print!(" {}", i);
}
});
food.ingredients.iter().for_each(|i| {
if non_allergens.contains(i) {
debug_print!(" *{}", i);
}
});
debug_println!();
});
let mut answer = HashMap::new();
let mut limit = 0;
loop {
if allergen_only.is_empty() {
return answer.into_iter().collect();
};
let mut rm = ("".to_string(), "".to_string());
allergen_only.iter().for_each(|(a, i_counts)| {
let max = i_counts.values().max().unwrap();
if i_counts.iter().filter(|(_i, c)| c == &max).count() == 1 {
let i = i_counts
.iter()
.filter(|(_i, c)| c == &max)
.map(|(i, _c)| i)
.nth(0)
.unwrap();
answer.insert(a.to_string(), i.to_string());
rm = (a.to_string(), i.to_string());
}
});
debug_println!("removing {:?}", rm);
allergen_only.iter_mut().for_each(|(_, i_counts)| {
i_counts.remove(&rm.1);
});
allergen_only.remove(&rm.0);
limit += 1;
if limit > 10 {
panic!()
};
}
}
#[aoc(day21, part2)]
fn solution2(foods: &[Food]) -> String {
let non_allergens = find_non_allergens(foods);
let mut allergens = allergen_ingredients(foods, &non_allergens);
allergens.sort_by(|l, r| l.0.cmp(&r.0));
allergens
.iter()
.map(|(_, a)| a.as_str())
.collect::<Vec<_>>()
.as_slice()
.join(",")
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &'static str = r#"mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
trh fvjkl sbzzf mxmxvkd (contains dairy)
sqjhc fvjkl (contains soy)
sqjhc mxmxvkd sbzzf (contains fish)"#;
#[test]
fn parse() {
let foods = generator(INPUT);
assert_eq!(foods.len(), 4);
assert_eq!(
foods[0].ingredients,
["mxmxvkd", "kfcds", "sqjhc", "nhms"]
.iter()
.map(|s| s.to_string())
.collect::<Vec<_>>()
);
assert_eq!(
foods[0].allergens,
["dairy", "fish"]
.iter()
.map(|s| s.to_string())
.collect::<Vec<_>>()
);
}
#[test]
fn part1() {
assert_eq!(solution1(&generator(INPUT)), 5);
}
#[test]
fn part2() {
assert_eq!(solution2(&generator(INPUT)), "mxmxvkd,sqjhc,fvjkl");
}
#[test]
fn non_allergens() {
assert_eq!(
find_non_allergens(&generator(INPUT)),
["kfcds", "nhms", "sbzzf", "trh"]
.iter()
.map(|s| s.to_string())
.collect()
);
}
#[test]
fn count() {
let ingredients: HashSet<String> = vec!["kfcds", "nhms", "sbzzf", "trh"]
.iter()
.map(|s| s.to_string())
.collect();
let foods = generator(INPUT);
assert_eq!(count_ingredients(&foods, &ingredients), 5);
}
}

561
2020/src/day22.rs Normal file
View File

@@ -0,0 +1,561 @@
//! --- Day 22: Crab Combat ---
//! It only takes a few hours of sailing the ocean on a raft for boredom to sink in. Fortunately, you brought a small deck of space cards! You'd like to play a game of Combat, and there's even an opponent available: a small crab that climbed aboard your raft before you left.
//!
//! Fortunately, it doesn't take long to teach the crab the rules.
//!
//! Before the game starts, split the cards so each player has their own deck (your puzzle input). Then, the game consists of a series of rounds: both players draw their top card, and the player with the higher-valued card wins the round. The winner keeps both cards, placing them on the bottom of their own deck so that the winner's card is above the other card. If this causes a player to have all of the cards, they win, and the game ends.
//!
//! For example, consider the following starting decks:
//!
//! Player 1:
//! 9
//! 2
//! 6
//! 3
//! 1
//!
//! Player 2:
//! 5
//! 8
//! 4
//! 7
//! 10
//! This arrangement means that player 1's deck contains 5 cards, with 9 on top and 1 on the bottom; player 2's deck also contains 5 cards, with 5 on top and 10 on the bottom.
//!
//! The first round begins with both players drawing the top card of their decks: 9 and 5. Player 1 has the higher card, so both cards move to the bottom of player 1's deck such that 9 is above 5. In total, it takes 29 rounds before a player has all of the cards:
//!
//! -- Round 1 --
//! Player 1's deck: 9, 2, 6, 3, 1
//! Player 2's deck: 5, 8, 4, 7, 10
//! Player 1 plays: 9
//! Player 2 plays: 5
//! Player 1 wins the round!
//!
//! -- Round 2 --
//! Player 1's deck: 2, 6, 3, 1, 9, 5
//! Player 2's deck: 8, 4, 7, 10
//! Player 1 plays: 2
//! Player 2 plays: 8
//! Player 2 wins the round!
//!
//! -- Round 3 --
//! Player 1's deck: 6, 3, 1, 9, 5
//! Player 2's deck: 4, 7, 10, 8, 2
//! Player 1 plays: 6
//! Player 2 plays: 4
//! Player 1 wins the round!
//!
//! -- Round 4 --
//! Player 1's deck: 3, 1, 9, 5, 6, 4
//! Player 2's deck: 7, 10, 8, 2
//! Player 1 plays: 3
//! Player 2 plays: 7
//! Player 2 wins the round!
//!
//! -- Round 5 --
//! Player 1's deck: 1, 9, 5, 6, 4
//! Player 2's deck: 10, 8, 2, 7, 3
//! Player 1 plays: 1
//! Player 2 plays: 10
//! Player 2 wins the round!
//!
//! ...several more rounds pass...
//!
//! -- Round 27 --
//! Player 1's deck: 5, 4, 1
//! Player 2's deck: 8, 9, 7, 3, 2, 10, 6
//! Player 1 plays: 5
//! Player 2 plays: 8
//! Player 2 wins the round!
//!
//! -- Round 28 --
//! Player 1's deck: 4, 1
//! Player 2's deck: 9, 7, 3, 2, 10, 6, 8, 5
//! Player 1 plays: 4
//! Player 2 plays: 9
//! Player 2 wins the round!
//!
//! -- Round 29 --
//! Player 1's deck: 1
//! Player 2's deck: 7, 3, 2, 10, 6, 8, 5, 9, 4
//! Player 1 plays: 1
//! Player 2 plays: 7
//! Player 2 wins the round!
//!
//!
//! == Post-game results ==
//! Player 1's deck:
//! Player 2's deck: 3, 2, 10, 6, 8, 5, 9, 4, 7, 1
//! Once the game ends, you can calculate the winning player's score. The bottom card in their deck is worth the value of the card multiplied by 1, the second-from-the-bottom card is worth the value of the card multiplied by 2, and so on. With 10 cards, the top card is worth the value on the card multiplied by 10. In this example, the winning player's score is:
//!
//! 3 * 10
//! + 2 * 9
//! + 10 * 8
//! + 6 * 7
//! + 8 * 6
//! + 5 * 5
//! + 9 * 4
//! + 4 * 3
//! + 7 * 2
//! + 1 * 1
//! = 306
//! So, once the game ends, the winning player's score is 306.
//!
//! Play the small crab in a game of Combat using the two decks you just dealt. What is the winning player's score?
//!
//! --- Part Two ---
//! You lost to the small crab! Fortunately, crabs aren't very good at recursion. To defend your honor as a Raft Captain, you challenge the small crab to a game of Recursive Combat.
//!
//! Recursive Combat still starts by splitting the cards into two decks (you offer to play with the same starting decks as before - it's only fair). Then, the game consists of a series of rounds with a few changes:
//!
//! Before either player deals a card, if there was a previous round in this game that had exactly the same cards in the same order in the same players' decks, the game instantly ends in a win for player 1. Previous rounds from other games are not considered. (This prevents infinite games of Recursive Combat, which everyone agrees is a bad idea.)
//! Otherwise, this round's cards must be in a new configuration; the players begin the round by each drawing the top card of their deck as normal.
//! If both players have at least as many cards remaining in their deck as the value of the card they just drew, the winner of the round is determined by playing a new game of Recursive Combat (see below).
//! Otherwise, at least one player must not have enough cards left in their deck to recurse; the winner of the round is the player with the higher-value card.
//! As in regular Combat, the winner of the round (even if they won the round by winning a sub-game) takes the two cards dealt at the beginning of the round and places them on the bottom of their own deck (again so that the winner's card is above the other card). Note that the winner's card might be the lower-valued of the two cards if they won the round due to winning a sub-game. If collecting cards by winning the round causes a player to have all of the cards, they win, and the game ends.
//!
//! Here is an example of a small game that would loop forever without the infinite game prevention rule:
//!
//! Player 1:
//! 43
//! 19
//!
//! Player 2:
//! 2
//! 29
//! 14
//! During a round of Recursive Combat, if both players have at least as many cards in their own decks as the number on the card they just dealt, the winner of the round is determined by recursing into a sub-game of Recursive Combat. (For example, if player 1 draws the 3 card, and player 2 draws the 7 card, this would occur if player 1 has at least 3 cards left and player 2 has at least 7 cards left, not counting the 3 and 7 cards that were drawn.)
//!
//! To play a sub-game of Recursive Combat, each player creates a new deck by making a copy of the next cards in their deck (the quantity of cards copied is equal to the number on the card they drew to trigger the sub-game). During this sub-game, the game that triggered it is on hold and completely unaffected; no cards are removed from players' decks to form the sub-game. (For example, if player 1 drew the 3 card, their deck in the sub-game would be copies of the next three cards in their deck.)
//!
//! Here is a complete example of gameplay, where Game 1 is the primary game of Recursive Combat:
//!
//! === Game 1 ===
//!
//! -- Round 1 (Game 1) --
//! Player 1's deck: 9, 2, 6, 3, 1
//! Player 2's deck: 5, 8, 4, 7, 10
//! Player 1 plays: 9
//! Player 2 plays: 5
//! Player 1 wins round 1 of game 1!
//!
//! -- Round 2 (Game 1) --
//! Player 1's deck: 2, 6, 3, 1, 9, 5
//! Player 2's deck: 8, 4, 7, 10
//! Player 1 plays: 2
//! Player 2 plays: 8
//! Player 2 wins round 2 of game 1!
//!
//! -- Round 3 (Game 1) --
//! Player 1's deck: 6, 3, 1, 9, 5
//! Player 2's deck: 4, 7, 10, 8, 2
//! Player 1 plays: 6
//! Player 2 plays: 4
//! Player 1 wins round 3 of game 1!
//!
//! -- Round 4 (Game 1) --
//! Player 1's deck: 3, 1, 9, 5, 6, 4
//! Player 2's deck: 7, 10, 8, 2
//! Player 1 plays: 3
//! Player 2 plays: 7
//! Player 2 wins round 4 of game 1!
//!
//! -- Round 5 (Game 1) --
//! Player 1's deck: 1, 9, 5, 6, 4
//! Player 2's deck: 10, 8, 2, 7, 3
//! Player 1 plays: 1
//! Player 2 plays: 10
//! Player 2 wins round 5 of game 1!
//!
//! -- Round 6 (Game 1) --
//! Player 1's deck: 9, 5, 6, 4
//! Player 2's deck: 8, 2, 7, 3, 10, 1
//! Player 1 plays: 9
//! Player 2 plays: 8
//! Player 1 wins round 6 of game 1!
//!
//! -- Round 7 (Game 1) --
//! Player 1's deck: 5, 6, 4, 9, 8
//! Player 2's deck: 2, 7, 3, 10, 1
//! Player 1 plays: 5
//! Player 2 plays: 2
//! Player 1 wins round 7 of game 1!
//!
//! -- Round 8 (Game 1) --
//! Player 1's deck: 6, 4, 9, 8, 5, 2
//! Player 2's deck: 7, 3, 10, 1
//! Player 1 plays: 6
//! Player 2 plays: 7
//! Player 2 wins round 8 of game 1!
//!
//! -- Round 9 (Game 1) --
//! Player 1's deck: 4, 9, 8, 5, 2
//! Player 2's deck: 3, 10, 1, 7, 6
//! Player 1 plays: 4
//! Player 2 plays: 3
//! Playing a sub-game to determine the winner...
//!
//! === Game 2 ===
//!
//! -- Round 1 (Game 2) --
//! Player 1's deck: 9, 8, 5, 2
//! Player 2's deck: 10, 1, 7
//! Player 1 plays: 9
//! Player 2 plays: 10
//! Player 2 wins round 1 of game 2!
//!
//! -- Round 2 (Game 2) --
//! Player 1's deck: 8, 5, 2
//! Player 2's deck: 1, 7, 10, 9
//! Player 1 plays: 8
//! Player 2 plays: 1
//! Player 1 wins round 2 of game 2!
//!
//! -- Round 3 (Game 2) --
//! Player 1's deck: 5, 2, 8, 1
//! Player 2's deck: 7, 10, 9
//! Player 1 plays: 5
//! Player 2 plays: 7
//! Player 2 wins round 3 of game 2!
//!
//! -- Round 4 (Game 2) --
//! Player 1's deck: 2, 8, 1
//! Player 2's deck: 10, 9, 7, 5
//! Player 1 plays: 2
//! Player 2 plays: 10
//! Player 2 wins round 4 of game 2!
//!
//! -- Round 5 (Game 2) --
//! Player 1's deck: 8, 1
//! Player 2's deck: 9, 7, 5, 10, 2
//! Player 1 plays: 8
//! Player 2 plays: 9
//! Player 2 wins round 5 of game 2!
//!
//! -- Round 6 (Game 2) --
//! Player 1's deck: 1
//! Player 2's deck: 7, 5, 10, 2, 9, 8
//! Player 1 plays: 1
//! Player 2 plays: 7
//! Player 2 wins round 6 of game 2!
//! The winner of game 2 is player 2!
//!
//! ...anyway, back to game 1.
//! Player 2 wins round 9 of game 1!
//!
//! -- Round 10 (Game 1) --
//! Player 1's deck: 9, 8, 5, 2
//! Player 2's deck: 10, 1, 7, 6, 3, 4
//! Player 1 plays: 9
//! Player 2 plays: 10
//! Player 2 wins round 10 of game 1!
//!
//! -- Round 11 (Game 1) --
//! Player 1's deck: 8, 5, 2
//! Player 2's deck: 1, 7, 6, 3, 4, 10, 9
//! Player 1 plays: 8
//! Player 2 plays: 1
//! Player 1 wins round 11 of game 1!
//!
//! -- Round 12 (Game 1) --
//! Player 1's deck: 5, 2, 8, 1
//! Player 2's deck: 7, 6, 3, 4, 10, 9
//! Player 1 plays: 5
//! Player 2 plays: 7
//! Player 2 wins round 12 of game 1!
//!
//! -- Round 13 (Game 1) --
//! Player 1's deck: 2, 8, 1
//! Player 2's deck: 6, 3, 4, 10, 9, 7, 5
//! Player 1 plays: 2
//! Player 2 plays: 6
//! Playing a sub-game to determine the winner...
//!
//! === Game 3 ===
//!
//! -- Round 1 (Game 3) --
//! Player 1's deck: 8, 1
//! Player 2's deck: 3, 4, 10, 9, 7, 5
//! Player 1 plays: 8
//! Player 2 plays: 3
//! Player 1 wins round 1 of game 3!
//!
//! -- Round 2 (Game 3) --
//! Player 1's deck: 1, 8, 3
//! Player 2's deck: 4, 10, 9, 7, 5
//! Player 1 plays: 1
//! Player 2 plays: 4
//! Playing a sub-game to determine the winner...
//!
//! === Game 4 ===
//!
//! -- Round 1 (Game 4) --
//! Player 1's deck: 8
//! Player 2's deck: 10, 9, 7, 5
//! Player 1 plays: 8
//! Player 2 plays: 10
//! Player 2 wins round 1 of game 4!
//! The winner of game 4 is player 2!
//!
//! ...anyway, back to game 3.
//! Player 2 wins round 2 of game 3!
//!
//! -- Round 3 (Game 3) --
//! Player 1's deck: 8, 3
//! Player 2's deck: 10, 9, 7, 5, 4, 1
//! Player 1 plays: 8
//! Player 2 plays: 10
//! Player 2 wins round 3 of game 3!
//!
//! -- Round 4 (Game 3) --
//! Player 1's deck: 3
//! Player 2's deck: 9, 7, 5, 4, 1, 10, 8
//! Player 1 plays: 3
//! Player 2 plays: 9
//! Player 2 wins round 4 of game 3!
//! The winner of game 3 is player 2!
//!
//! ...anyway, back to game 1.
//! Player 2 wins round 13 of game 1!
//!
//! -- Round 14 (Game 1) --
//! Player 1's deck: 8, 1
//! Player 2's deck: 3, 4, 10, 9, 7, 5, 6, 2
//! Player 1 plays: 8
//! Player 2 plays: 3
//! Player 1 wins round 14 of game 1!
//!
//! -- Round 15 (Game 1) --
//! Player 1's deck: 1, 8, 3
//! Player 2's deck: 4, 10, 9, 7, 5, 6, 2
//! Player 1 plays: 1
//! Player 2 plays: 4
//! Playing a sub-game to determine the winner...
//!
//! === Game 5 ===
//!
//! -- Round 1 (Game 5) --
//! Player 1's deck: 8
//! Player 2's deck: 10, 9, 7, 5
//! Player 1 plays: 8
//! Player 2 plays: 10
//! Player 2 wins round 1 of game 5!
//! The winner of game 5 is player 2!
//!
//! ...anyway, back to game 1.
//! Player 2 wins round 15 of game 1!
//!
//! -- Round 16 (Game 1) --
//! Player 1's deck: 8, 3
//! Player 2's deck: 10, 9, 7, 5, 6, 2, 4, 1
//! Player 1 plays: 8
//! Player 2 plays: 10
//! Player 2 wins round 16 of game 1!
//!
//! -- Round 17 (Game 1) --
//! Player 1's deck: 3
//! Player 2's deck: 9, 7, 5, 6, 2, 4, 1, 10, 8
//! Player 1 plays: 3
//! Player 2 plays: 9
//! Player 2 wins round 17 of game 1!
//! The winner of game 1 is player 2!
//!
//!
//! == Post-game results ==
//! Player 1's deck:
//! Player 2's deck: 7, 5, 6, 2, 4, 1, 10, 8, 9, 3
//! After the game, the winning player's score is calculated from the cards they have in their original deck using the same rules as regular Combat. In the above game, the winning player's score is 291.
//!
//! Defend your honor as Raft Captain by playing the small crab in a game of Recursive Combat using the same two decks as before. What is the winning player's score?
use std::collections::{HashSet, VecDeque};
use aoc_runner_derive::aoc;
use crate::debug_println;
#[derive(Clone, Debug, PartialEq)]
struct Players {
p1: VecDeque<usize>,
p2: VecDeque<usize>,
}
fn generator(input: &str) -> Players {
let players: Vec<_> = input.split("\n\n").collect();
Players {
p1: players[0]
.split('\n')
.skip(1)
.map(|s| s.trim().parse().expect("couldn't parse p1 number"))
.collect::<VecDeque<usize>>(),
p2: players[1]
.split('\n')
.skip(1)
.map(|s| s.trim().parse().expect("couldn't parse p2 number"))
.collect::<VecDeque<usize>>(),
}
}
fn deck_to_str(deck: &VecDeque<usize>) -> String {
let mut s = format!("{}", deck.iter().nth(0).unwrap());
for c in deck.iter().skip(1) {
s = format!("{}, {}", s, c);
}
s
}
use std::sync::atomic::{AtomicUsize, Ordering};
static GAME_NUM: AtomicUsize = AtomicUsize::new(1);
impl Players {
fn play_recursive(&mut self, game: usize, parent_game: usize) -> bool {
debug_println!("=== Game {} ===\n", game);
let mut round = 0;
// For debug builds only.
let _ = round;
let _ = parent_game;
let mut previous_rounds = HashSet::new();
while !self.p1.is_empty() && !self.p2.is_empty() {
let p1s = deck_to_str(&self.p1);
let p2s = deck_to_str(&self.p2);
let deck_key = format!("{} *** {}", p1s, p2s);
if previous_rounds.contains(&deck_key) {
// Loop detected, p1 wins
return true;
}
debug_println!("{}: {}", game, deck_key);
previous_rounds.insert(deck_key);
let p1 = self.p1.pop_front().unwrap();
let p2 = self.p2.pop_front().unwrap();
round += 1;
debug_println!("-- Round {} (Game {}) --", round, game);
debug_println!("Player 1's deck: {}", p1s);
debug_println!("Player 2's deck: {}", p2s);
debug_println!("Player 1 plays: {}", p1);
debug_println!("Player 2 plays: {}", p2);
//dbg!(p1, self.p1.len(), p2, self.p2.len());
let p1_won = if p1 <= self.p1.len() && p2 <= self.p2.len() {
// Recurse
debug_println!("Playing a sub-game to determine the winner...\n");
let mut sub_game = self.clone();
sub_game.p1.truncate(p1);
sub_game.p2.truncate(p2);
let next_game = GAME_NUM.fetch_add(1, Ordering::SeqCst);
let p1_won = sub_game.play_recursive(next_game, game);
p1_won
} else {
p1 > p2
};
if p1_won {
debug_println!("Player 1 wins round {} of game {}!", round, game);
self.p1.push_back(p1);
self.p1.push_back(p2);
} else {
debug_println!("Player 2 wins round {} of game {}!", round, game);
self.p2.push_back(p2);
self.p2.push_back(p1);
}
debug_println!();
}
let p1_won = self.p1.len() > self.p2.len();
if p1_won {
debug_println!("The winner of game {} is player 1!", game);
} else {
debug_println!("The winner of game {} is player 2!", game);
}
debug_println!("...anyway, back to game {}.", parent_game);
p1_won
}
fn play(&mut self) {
//let mut round = 0;
while !self.p1.is_empty() && !self.p2.is_empty() {
let p1 = self.p1.pop_front().unwrap();
let p2 = self.p2.pop_front().unwrap();
//round += 1;
//println!("-- Round {} --", round);
//println!("Player 1's deck: {:?}", self.p1);
//println!("Player 2's deck: {:?}", self.p2);
//println!("Player 1 plays: {}", p1);
//println!("Player 2 plays: {}", p2);
if p1 > p2 {
//println!("Play 1 wins the round!");
self.p1.push_back(p1);
self.p1.push_back(p2);
} else {
//println!("Play 2 wins the round!");
self.p2.push_back(p2);
self.p2.push_back(p1);
}
//println!();
}
}
fn winning_score(&self) -> usize {
let winner = if self.p1.len() > self.p2.len() {
&self.p1
} else {
&self.p2
};
winner
.iter()
.rev()
.enumerate()
.map(|(i, n)| (i + 1) * *n)
.sum()
}
}
#[aoc(day22, part1)]
fn solution1(input: &str) -> usize {
let mut players = generator(input);
players.play();
players.winning_score()
}
#[aoc(day22, part2)]
fn solution2(input: &str) -> usize {
let mut players = generator(input);
players.play_recursive(GAME_NUM.fetch_add(1, Ordering::SeqCst), 0);
players.winning_score()
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &'static str = r#"Player 1:
9
2
6
3
1
Player 2:
5
8
4
7
10"#;
#[test]
fn test_generator() {
assert_eq!(
generator(INPUT),
Players {
p1: vec![9, 2, 6, 3, 1].into(),
p2: vec![5, 8, 4, 7, 10].into(),
}
);
}
#[test]
fn test_solution1() {
assert_eq!(solution1(INPUT), 306);
}
#[test]
fn test_solution2() {
assert_eq!(solution2(INPUT), 291);
}
}

461
2020/src/day23.rs Normal file
View File

@@ -0,0 +1,461 @@
//! --- Day 23: Crab Cups ---
//! The small crab challenges you to a game! The crab is going to mix up some cups, and you have to predict where they'll end up.
//!
//! The cups will be arranged in a circle and labeled clockwise (your puzzle input). For example, if your labeling were 32415, there would be five cups in the circle; going clockwise around the circle from the first cup, the cups would be labeled 3, 2, 4, 1, 5, and then back to 3 again.
//!
//! Before the crab starts, it will designate the first cup in your list as the current cup. The crab is then going to do 100 moves.
//!
//! Each move, the crab does the following actions:
//!
//! The crab picks up the three cups that are immediately clockwise of the current cup. They are removed from the circle; cup spacing is adjusted as necessary to maintain the circle.
//! The crab selects a destination cup: the cup with a label equal to the current cup's label minus one. If this would select one of the cups that was just picked up, the crab will keep subtracting one until it finds a cup that wasn't just picked up. If at any point in this process the value goes below the lowest value on any cup's label, it wraps around to the highest value on any cup's label instead.
//! The crab places the cups it just picked up so that they are immediately clockwise of the destination cup. They keep the same order as when they were picked up.
//! The crab selects a new current cup: the cup which is immediately clockwise of the current cup.
//! For example, suppose your cup labeling were 389125467. If the crab were to do merely 10 moves, the following changes would occur:
//!
//! -- move 1 --
//! cups: (3) 8 9 1 2 5 4 6 7
//! pick up: 8, 9, 1
//! destination: 2
//!
//! -- move 2 --
//! cups: 3 (2) 8 9 1 5 4 6 7
//! pick up: 8, 9, 1
//! destination: 7
//!
//! -- move 3 --
//! cups: 3 2 (5) 4 6 7 8 9 1
//! pick up: 4, 6, 7
//! destination: 3
//!
//! -- move 4 --
//! cups: 7 2 5 (8) 9 1 3 4 6
//! pick up: 9, 1, 3
//! destination: 7
//!
//! -- move 5 --
//! cups: 3 2 5 8 (4) 6 7 9 1
//! pick up: 6, 7, 9
//! destination: 3
//!
//! -- move 6 --
//! cups: 9 2 5 8 4 (1) 3 6 7
//! pick up: 3, 6, 7
//! destination: 9
//!
//! -- move 7 --
//! cups: 7 2 5 8 4 1 (9) 3 6
//! pick up: 3, 6, 7
//! destination: 8
//!
//! -- move 8 --
//! cups: 8 3 6 7 4 1 9 (2) 5
//! pick up: 5, 8, 3
//! destination: 1
//!
//! -- move 9 --
//! cups: 7 4 1 5 8 3 9 2 (6)
//! pick up: 7, 4, 1
//! destination: 5
//!
//! -- move 10 --
//! cups: (5) 7 4 1 8 3 9 2 6
//! pick up: 7, 4, 1
//! destination: 3
//!
//! -- final --
//! cups: 5 (8) 3 7 4 1 9 2 6
//! In the above example, the cups' values are the labels as they appear moving clockwise around the circle; the current cup is marked with ( ).
//!
//! After the crab is done, what order will the cups be in? Starting after the cup labeled 1, collect the other cups' labels clockwise into a single string with no extra characters; each number except 1 should appear exactly once. In the above example, after 10 moves, the cups clockwise from 1 are labeled 9, 2, 6, 5, and so on, producing 92658374. If the crab were to complete all 100 moves, the order after cup 1 would be 67384529.
//!
//! Using your labeling, simulate 100 moves. What are the labels on the cups after cup 1?
//! --- Part Two ---
//! Due to what you can only assume is a mistranslation (you're not exactly fluent in Crab), you are quite surprised when the crab starts arranging many cups in a circle on your raft - one million (1000000) in total.
//!
//! Your labeling is still correct for the first few cups; after that, the remaining cups are just numbered in an increasing fashion starting from the number after the highest number in your list and proceeding one by one until one million is reached. (For example, if your labeling were 54321, the cups would be numbered 5, 4, 3, 2, 1, and then start counting up from 6 until one million is reached.) In this way, every number from one through one million is used exactly once.
//!
//! After discovering where you made the mistake in translating Crab Numbers, you realize the small crab isn't going to do merely 100 moves; the crab is going to do ten million (10000000) moves!
//!
//! The crab is going to hide your stars - one each - under the two cups that will end up immediately clockwise of cup 1. You can have them if you predict what the labels on those cups will be when the crab is finished.
//!
//! In the above example (389125467), this would be 934001 and then 159792; multiplying these together produces 149245887792.
//!
//! Determine which two cups will end up immediately clockwise of cup 1. What do you get if you multiply their labels together?
use std::fmt;
use aoc_runner_derive::aoc;
use crate::debug_println;
trait Hand {
fn play(&mut self, rounds: usize) {
use std::time::{Duration, Instant};
let start = Instant::now();
let mut last_report = Instant::now();
(0..rounds).for_each(|i| {
debug_println!("-- move {} --", i + 1);
if last_report.elapsed() > Duration::new(1, 0) {
let elapsed = start.elapsed();
let runtime = elapsed * rounds as u32 / i as u32;
let eta = runtime - elapsed;
println!(
"{} steps ({}%) in {}s, Estimated runtime {}s, ETA {}s",
i,
100 * i / rounds,
elapsed.as_secs_f32(),
runtime.as_secs_f32(),
eta.as_secs_f32(),
);
last_report = Instant::now();
}
self.step();
});
}
fn part1_answer(&self) -> String;
fn part2_answer(&self) -> usize;
fn step(&mut self);
fn test_cur_to_end(&self) -> Vec<usize>;
}
/// TODO(wathiede): redo based on this sentence from glenng:
/// `So a circular linked list containing 2,1,3 would be [3,1,2]`
#[derive(Debug)]
struct FastHand {
// A cup labeled `1` will be represented by the index 0, in that cell will be the index of cup
// clockwise to `1`.
// Stores the next cup as indexed value (i.e. label-1).
cups: Vec<usize>,
cur: Cup,
min: usize,
max: usize,
}
/// Stores the label of a cup. Use `as_idx` to compute the index into FastHand.cups. Use
/// `from_idx` to build a `Cup` from a given index into FastHand.cups.
#[derive(Copy, Clone, Debug, PartialEq)]
struct Cup(usize);
impl Cup {
fn new(val: usize) -> Cup {
Cup(val)
}
fn from_idx(idx: usize) -> Cup {
Cup(idx + 1)
}
fn as_idx(&self) -> usize {
self.0 - 1
}
}
impl FastHand {
fn new(s: &str) -> FastHand {
let data: Vec<_> = s.bytes().map(|s| (s - b'0') as usize).collect();
let min = *data.iter().min().unwrap();
let max = *data.iter().max().unwrap();
let mut cups = vec![0; max];
let mut last = 0;
data.windows(2).for_each(|nums| {
let cur_cup = Cup::new(nums[0]);
let next_cup = Cup::new(nums[1]);
last = next_cup.as_idx();
cups[cur_cup.as_idx()] = next_cup.as_idx();
});
let cur = Cup(data[0]);
cups[last] = cur.as_idx();
FastHand {
cups,
cur,
min,
max,
}
}
fn new_part2(s: &str) -> FastHand {
let mut data: Vec<_> = s.bytes().map(|s| (s - b'0') as usize).collect();
let min = *data.iter().min().unwrap();
let mut max = *data.iter().max().unwrap();
data.extend(max + 1..=1000000);
max = 1000000;
let mut cups = vec![0; max];
let mut last = 0;
data.windows(2).for_each(|nums| {
let cur_cup = Cup::new(nums[0]);
let next_cup = Cup::new(nums[1]);
last = next_cup.as_idx();
cups[cur_cup.as_idx()] = next_cup.as_idx();
});
let cur = Cup(data[0]);
cups[last] = cur.as_idx();
FastHand {
cups,
cur,
min,
max,
}
}
fn destination(&self, skip_vals: &[Cup]) -> Cup {
let mut search_val = Cup::new(self.cur.0 - 1);
while skip_vals.contains(&search_val) {
search_val = Cup::new(search_val.0 - 1);
}
if search_val.0 < self.min {
search_val = Cup::new(self.max);
}
while skip_vals.contains(&search_val) {
search_val = Cup::new(search_val.0 - 1);
}
search_val
}
fn next(&self, c: Cup) -> Cup {
//dbg!(c.as_idx(), self.cups[c.as_idx()]);
Cup::from_idx(self.cups[c.as_idx()])
}
}
impl fmt::Display for FastHand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut cur = self.cur;
write!(f, "({}) ", cur.0)?;
for _ in 1..self.cups.len() {
cur = Cup::from_idx(self.cups[cur.as_idx()]);
write!(f, "{} ", cur.0)?;
}
Ok(())
}
}
impl Hand for FastHand {
fn step(&mut self) {
let mut cur = self.cur;
let three: Vec<_> = (0..3)
.map(|_| {
cur = self.next(cur);
cur
})
.collect();
let dst = self.destination(&three);
debug_println!(
"cur {} cups {} three {:?} destination {:?}",
self.cur.0,
self,
three,
dst
);
debug_println!("cups (raw) {:?}", self.cups);
// Cur points to whatever end of three used to.
self.cups[self.cur.as_idx()] = self.cups[three[2].as_idx()];
// End of three points to whatever dst used to point to.
self.cups[three[2].as_idx()] = self.cups[dst.as_idx()];
// Dst points to the beginning of three.
self.cups[dst.as_idx()] = three[0].as_idx();
// Cur points to whatever is next in the circle.
self.cur = self.next(self.cur);
}
fn test_cur_to_end(&self) -> Vec<usize> {
let mut res = Vec::with_capacity(self.cups.len());
let mut cur = self.cur;
(0..self.cups.len()).for_each(|_| {
res.push(cur.0);
cur = Cup::from_idx(self.cups[cur.as_idx()]);
});
res
}
fn part1_answer(&self) -> String {
let mut cur = Cup::new(1);
let mut s = "".to_string();
for _ in 1..self.cups.len() {
cur = self.next(cur);
s = format!("{}{}", s, cur.0);
}
s
}
fn part2_answer(&self) -> usize {
let one = Cup::new(1);
let v1 = self.next(one);
let v2 = self.next(v1);
v1.0 * v2.0
}
}
struct SlowHand {
cups: Vec<usize>,
cur: usize,
min: usize,
max: usize,
}
impl fmt::Display for SlowHand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for (i, cup) in self.cups.iter().enumerate() {
if i == self.cur {
write!(f, "({}) ", cup)?;
} else {
write!(f, "{} ", cup)?;
};
}
Ok(())
}
}
impl SlowHand {
#[allow(dead_code)]
fn new(s: &str) -> SlowHand {
let cups: Vec<_> = s.bytes().map(|s| (s - b'0') as usize).collect();
let min = *cups.iter().min().unwrap();
let max = *cups.iter().max().unwrap();
SlowHand {
cups,
cur: 0,
min,
max,
}
}
}
impl Hand for SlowHand {
fn part1_answer(&self) -> String {
let idx = self.cups.iter().position(|i| i == &1).unwrap();
let s = self.cups[idx + 1..]
.iter()
.fold("".to_string(), |acc, c| format!("{}{}", acc, c));
self.cups[..idx]
.iter()
.fold(s, |acc, c| format!("{}{}", acc, c))
}
fn step(&mut self) {
debug_println!("{}", self);
let cur = self.cups[self.cur];
let mut pickups = Vec::new();
let mut destination = self.cups[self.cur] - 1;
let mut rm_idx = (self.cur + 1) % self.cups.len();
(0..3).for_each(|_| {
pickups.push(self.cups.remove(rm_idx));
if rm_idx >= self.cups.len() {
rm_idx -= self.cups.len();
}
});
let cur = self.cups.iter().position(|i| i == &cur).unwrap();
let next = self.cups[(cur + 1) % self.cups.len()];
while pickups.contains(&destination) {
destination -= 1;
}
if destination < self.min {
destination = self.max;
while pickups.contains(&destination) {
destination -= 1;
}
}
//dbg!(&pickups, &self.cups, destination);
let idx = self.cups.iter().position(|i| i == &destination).unwrap();
debug_println!("pick up: {:?}", pickups);
debug_println!("destination: {}({})", destination, idx);
debug_println!("next destination: {}", next);
pickups
.into_iter()
.rev()
.for_each(|v| self.cups.insert(idx + 1, v));
self.cur = self.cups.iter().position(|i| i == &next).unwrap();
}
/// Return internal state in a way unit tests can use
fn test_cur_to_end(&self) -> Vec<usize> {
self.cups[self.cur..]
.iter()
.chain(self.cups[..self.cur].iter())
.cloned()
.collect()
}
fn part2_answer(&self) -> usize {
let one = self.cups.iter().position(|n| n == &1).unwrap();
self.cups[one + 1] * self.cups[one + 2]
}
}
#[aoc(day23, part1)]
fn solution1(input: &str) -> String {
let mut hand = FastHand::new(input);
hand.play(100);
hand.part1_answer()
}
#[aoc(day23, part2)]
fn solution2(input: &str) -> usize {
let mut hand = FastHand::new_part2(input);
hand.play(10_000_000);
hand.part2_answer()
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &'static str = "389125467";
fn test_hand<H: Hand>(mut hand: H) {
let want = vec![
[3, 8, 9, 1, 2, 5, 4, 6, 7],
[2, 8, 9, 1, 5, 4, 6, 7, 3],
[5, 4, 6, 7, 8, 9, 1, 3, 2],
[8, 9, 1, 3, 4, 6, 7, 2, 5],
[4, 6, 7, 9, 1, 3, 2, 5, 8],
[1, 3, 6, 7, 9, 2, 5, 8, 4],
[9, 3, 6, 7, 2, 5, 8, 4, 1],
[2, 5, 8, 3, 6, 7, 4, 1, 9],
[6, 7, 4, 1, 5, 8, 3, 9, 2],
[5, 7, 4, 1, 8, 3, 9, 2, 6],
[8, 3, 7, 4, 1, 9, 2, 6, 5],
];
want.iter().enumerate().for_each(|(step, want)| {
assert_eq!(hand.test_cur_to_end(), want, "step0 {}", step);
hand.step();
});
}
#[test]
fn slow_step() {
let hand = SlowHand::new(INPUT);
test_hand(hand);
}
#[test]
fn fast_step() {
let hand = FastHand::new(INPUT);
test_hand(hand);
}
#[test]
fn part1_10step_slow() {
let mut hand = SlowHand::new(INPUT);
hand.play(10);
assert_eq!(hand.part1_answer(), "92658374");
}
#[test]
fn part1_10step_fast() {
let mut hand = FastHand::new(INPUT);
hand.play(10);
assert_eq!(hand.part1_answer(), "92658374");
}
#[test]
fn part1() {
assert_eq!(solution1(INPUT), "67384529");
}
// This is too slow in debug mode due to debug_println, build in release to run.
#[cfg(not(debug_assertions))]
#[test]
fn part2() {
assert_eq!(solution2("389125467"), 149245887792);
}
}

294
2020/src/day24.rs Normal file
View File

@@ -0,0 +1,294 @@
//! --- Day 24: Lobby Layout ---
//! Your raft makes it to the tropical island; it turns out that the small crab was an excellent navigator. You make your way to the resort.
//!
//! As you enter the lobby, you discover a small problem: the floor is being renovated. You can't even reach the check-in desk until they've finished installing the new tile floor.
//!
//! The tiles are all hexagonal; they need to be arranged in a hex grid with a very specific color pattern. Not in the mood to wait, you offer to help figure out the pattern.
//!
//! The tiles are all white on one side and black on the other. They start with the white side facing up. The lobby is large enough to fit whatever pattern might need to appear there.
//!
//! A member of the renovation crew gives you a list of the tiles that need to be flipped over (your puzzle input). Each line in the list identifies a single tile that needs to be flipped by giving a series of steps starting from a reference tile in the very center of the room. (Every line starts from the same reference tile.)
//!
//! Because the tiles are hexagonal, every tile has six neighbors: east, southeast, southwest, west, northwest, and northeast. These directions are given in your list, respectively, as e, se, sw, w, nw, and ne. A tile is identified by a series of these directions with no delimiters; for example, esenee identifies the tile you land on if you start at the reference tile and then move one tile east, one tile southeast, one tile northeast, and one tile east.
//!
//! Each time a tile is identified, it flips from white to black or from black to white. Tiles might be flipped more than once. For example, a line like esew flips a tile immediately adjacent to the reference tile, and a line like nwwswee flips the reference tile itself.
//!
//! Here is a larger example:
//!
//! sesenwnenenewseeswwswswwnenewsewsw
//! neeenesenwnwwswnenewnwwsewnenwseswesw
//! seswneswswsenwwnwse
//! nwnwneseeswswnenewneswwnewseswneseene
//! swweswneswnenwsewnwneneseenw
//! eesenwseswswnenwswnwnwsewwnwsene
//! sewnenenenesenwsewnenwwwse
//! wenwwweseeeweswwwnwwe
//! wsweesenenewnwwnwsenewsenwwsesesenwne
//! neeswseenwwswnwswswnw
//! nenwswwsewswnenenewsenwsenwnesesenew
//! enewnwewneswsewnwswenweswnenwsenwsw
//! sweneswneswneneenwnewenewwneswswnese
//! swwesenesewenwneswnwwneseswwne
//! enesenwswwswneneswsenwnewswseenwsese
//! wnwnesenesenenwwnenwsewesewsesesew
//! nenewswnwewswnenesenwnesewesw
//! eneswnwswnwsenenwnwnwwseeswneewsenese
//! neswnwewnwnwseenwseesewsenwsweewe
//! wseweeenwnesenwwwswnew
//! In the above example, 10 tiles are flipped once (to black), and 5 more are flipped twice (to black, then back to white). After all of these instructions have been followed, a total of 10 tiles are black.
//!
//! Go through the renovation crew's list and determine which tiles they need to flip. After all of the instructions have been followed, how many tiles are left with the black side up?
//!
//! --- Part Two ---
//! The tile floor in the lobby is meant to be a living art exhibit. Every day, the tiles are all flipped according to the following rules:
//!
//! Any black tile with zero or more than 2 black tiles immediately adjacent to it is flipped to white.
//! Any white tile with exactly 2 black tiles immediately adjacent to it is flipped to black.
//! Here, tiles immediately adjacent means the six tiles directly touching the tile in question.
//!
//! The rules are applied simultaneously to every tile; put another way, it is first determined which tiles need to be flipped, then they are all flipped at the same time.
//!
//! In the above example, the number of black tiles that are facing up after the given number of days has passed is as follows:
//!
//! Day 1: 15
//! Day 2: 12
//! Day 3: 25
//! Day 4: 14
//! Day 5: 23
//! Day 6: 28
//! Day 7: 41
//! Day 8: 37
//! Day 9: 49
//! Day 10: 37
//!
//! Day 20: 132
//! Day 30: 259
//! Day 40: 406
//! Day 50: 566
//! Day 60: 788
//! Day 70: 1106
//! Day 80: 1373
//! Day 90: 1844
//! Day 100: 2208
//! After executing this process a total of 100 times, there would be 2208 black tiles facing up.
//!
//! How many tiles will be black after 100 days?
use std::collections::HashMap;
use aoc_runner_derive::{aoc, aoc_generator};
#[derive(Debug, PartialEq)]
enum Direction {
East,
SouthEast,
SouthWest,
West,
NorthWest,
NorthEast,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
struct TileCoord((isize, isize, isize));
#[derive(Debug, PartialEq)]
struct Tile {
directions: Vec<Direction>,
}
impl std::str::FromStr for Tile {
type Err = ();
fn from_str(s: &str) -> Result<Tile, ()> {
let mut it = s.bytes();
let mut directions = Vec::new();
use Direction::*;
while let Some(b) = it.next() {
match b {
b'n' => match it.next().unwrap() {
b'e' => directions.push(NorthEast),
b'w' => directions.push(NorthWest),
c => panic!(format!("unexpected tile direction {}", c)),
},
b's' => match it.next().unwrap() {
b'e' => directions.push(SouthEast),
b'w' => directions.push(SouthWest),
c => panic!(format!("unexpected tile direction {}", c)),
},
b'e' => directions.push(East),
b'w' => directions.push(West),
c => panic!(format!("unexpected tile direction {}", c)),
}
}
Ok(Tile { directions })
}
}
impl Tile {
fn coord(&self) -> TileCoord {
// Based on 'cube coordinates' from https://www.redblobgames.com/grids/hexagons/
TileCoord(
self.directions
.iter()
.fold((0, 0, 0), |(x, y, z), dir| match dir {
Direction::East => (x + 1, y - 1, z),
Direction::SouthEast => (x, y - 1, z + 1),
Direction::SouthWest => (x - 1, y, z + 1),
Direction::West => (x - 1, y + 1, z),
Direction::NorthWest => (x, y + 1, z - 1),
Direction::NorthEast => (x + 1, y, z - 1),
}),
)
}
}
#[aoc_generator(day24)]
fn parse(input: &str) -> Vec<Tile> {
input
.split('\n')
.map(|l| l.parse().expect("Failed to parse tile"))
.collect()
}
fn follow_instructions(instructions: &[Tile]) -> HashMap<TileCoord, bool> {
// False == white
// True == black
// Default == white
let mut tiles: HashMap<TileCoord, bool> = HashMap::new();
instructions.iter().for_each(|t| {
let v = tiles.entry(t.coord()).or_insert(false);
*v = !*v;
});
tiles
}
#[aoc(day24, part1)]
fn solution1(instructions: &[Tile]) -> usize {
let tiles = follow_instructions(instructions);
count_black(&tiles)
}
const NEIGHBOR_OFFSETS: [(isize, isize, isize); 6] = [
(-1, 1, 0),
(1, -1, 0),
(-1, 0, 1),
(1, 0, -1),
(0, -1, 1),
(0, 1, -1),
];
fn count_neighbors(coord: &TileCoord, tiles: &HashMap<TileCoord, bool>) -> usize {
let (x, y, z) = coord.0;
NEIGHBOR_OFFSETS
.iter()
.filter(|(x_o, y_o, z_o)| {
*tiles
.get(&TileCoord((x + x_o, y + y_o, z + z_o)))
.unwrap_or(&false)
})
.count()
}
fn count_black(tiles: &HashMap<TileCoord, bool>) -> usize {
tiles.values().filter(|v| **v).count()
}
fn step(tiles: HashMap<TileCoord, bool>) -> HashMap<TileCoord, bool> {
let mut output = HashMap::new();
tiles
.iter()
.filter_map(|(k, v)| if *v { Some(k) } else { None })
.for_each(|coord| {
match count_neighbors(coord, &tiles) {
1 | 2 => {
// Leave black
output.insert(*coord, true);
}
_ => {
// 0 or >=2, default is white, so don't set anything in new map.
}
};
let (x, y, z) = coord.0;
// TODO search white neighbors.
NEIGHBOR_OFFSETS.iter().for_each(|(x_o, y_o, z_o)| {
let coord = TileCoord((x + x_o, y + y_o, z + z_o));
if *tiles.get(&coord).unwrap_or(&false) {
// Black, we can skip
return;
}
if count_neighbors(&coord, &tiles) == 2 {
output.insert(coord, true);
}
});
});
output
}
#[aoc(day24, part2)]
fn solution2(instructions: &[Tile]) -> usize {
let tiles = follow_instructions(instructions);
let tiles = (0..100).fold(tiles, |tiles, _| step(tiles));
count_black(&tiles)
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &'static str = r#"
sesenwnenenewseeswwswswwnenewsewsw
neeenesenwnwwswnenewnwwsewnenwseswesw
seswneswswsenwwnwse
nwnwneseeswswnenewneswwnewseswneseene
swweswneswnenwsewnwneneseenw
eesenwseswswnenwswnwnwsewwnwsene
sewnenenenesenwsewnenwwwse
wenwwweseeeweswwwnwwe
wsweesenenewnwwnwsenewsenwwsesesenwne
neeswseenwwswnwswswnw
nenwswwsewswnenenewsenwsenwnesesenew
enewnwewneswsewnwswenweswnenwsenwsw
sweneswneswneneenwnewenewwneswswnese
swwesenesewenwneswnwwneseswwne
enesenwswwswneneswsenwnewswseenwsese
wnwnesenesenenwwnenwsewesewsesesew
nenewswnwewswnenesenwnesewesw
eneswnwswnwsenenwnwnwwseeswneewsenese
neswnwewnwnwseenwseesewsenwsweewe
wseweeenwnesenwwwswnew
"#;
#[test]
fn tile() {
use Direction::*;
assert_eq!(
"esenee".parse::<Tile>().expect("failed to parse tile"),
Tile {
directions: vec![East, SouthEast, NorthEast, East]
}
);
}
#[test]
fn part1() {
assert_eq!(solution1(&parse(INPUT)), 10);
}
#[test]
fn test_step() {
let instructions = parse(INPUT);
let tiles = follow_instructions(&instructions);
let wants = vec![15, 12, 25, 14, 23, 28, 41, 37, 49, 37];
wants
.iter()
.enumerate()
.fold(tiles, |mut tiles, (i, want)| {
tiles = step(tiles);
assert_eq!(count_black(&tiles), *want, "step {}", i);
tiles
});
}
#[test]
fn part2() {
assert_eq!(solution2(&parse(INPUT)), 2208);
}
}

114
2020/src/day25.rs Normal file
View File

@@ -0,0 +1,114 @@
//! --- Day 25: Combo Breaker ---
//! You finally reach the check-in desk. Unfortunately, their registration systems are currently offline, and they cannot check you in. Noticing the look on your face, they quickly add that tech support is already on the way! They even created all the room keys this morning; you can take yours now and give them your room deposit once the registration system comes back online.
//!
//! The room key is a small RFID card. Your room is on the 25th floor and the elevators are also temporarily out of service, so it takes what little energy you have left to even climb the stairs and navigate the halls. You finally reach the door to your room, swipe your card, and - beep - the light turns red.
//!
//! Examining the card more closely, you discover a phone number for tech support.
//!
//! "Hello! How can we help you today?" You explain the situation.
//!
//! "Well, it sounds like the card isn't sending the right command to unlock the door. If you go back to the check-in desk, surely someone there can reset it for you." Still catching your breath, you describe the status of the elevator and the exact number of stairs you just had to climb.
//!
//! "I see! Well, your only other option would be to reverse-engineer the cryptographic handshake the card does with the door and then inject your own commands into the data stream, but that's definitely impossible." You thank them for their time.
//!
//! Unfortunately for the door, you know a thing or two about cryptographic handshakes.
//!
//! The handshake used by the card and the door involves an operation that transforms a subject number. To transform a subject number, start with the value 1. Then, a number of times called the loop size, perform the following steps:
//!
//! Set the value to itself multiplied by the subject number.
//! Set the value to the remainder after dividing the value by 20201227.
//! The card always uses a specific, secret loop size when it transforms a subject number. The door always uses a different, secret loop size.
//!
//! The cryptographic handshake works like this:
//!
//! The card transforms the subject number of 7 according to the card's secret loop size. The result is called the card's public key.
//! The door transforms the subject number of 7 according to the door's secret loop size. The result is called the door's public key.
//! The card and door use the wireless RFID signal to transmit the two public keys (your puzzle input) to the other device. Now, the card has the door's public key, and the door has the card's public key. Because you can eavesdrop on the signal, you have both public keys, but neither device's loop size.
//! The card transforms the subject number of the door's public key according to the card's loop size. The result is the encryption key.
//! The door transforms the subject number of the card's public key according to the door's loop size. The result is the same encryption key as the card calculated.
//! If you can use the two public keys to determine each device's loop size, you will have enough information to calculate the secret encryption key that the card and door use to communicate; this would let you send the unlock command directly to the door!
//!
//! For example, suppose you know that the card's public key is 5764801. With a little trial and error, you can work out that the card's loop size must be 8, because transforming the initial subject number of 7 with a loop size of 8 produces 5764801.
//!
//! Then, suppose you know that the door's public key is 17807724. By the same process, you can determine that the door's loop size is 11, because transforming the initial subject number of 7 with a loop size of 11 produces 17807724.
//!
//! At this point, you can use either device's loop size with the other device's public key to calculate the encryption key. Transforming the subject number of 17807724 (the door's public key) with a loop size of 8 (the card's loop size) produces the encryption key, 14897079. (Transforming the subject number of 5764801 (the card's public key) with a loop size of 11 (the door's loop size) produces the same encryption key: 14897079.)
//!
//! What encryption key is the handshake trying to establish?
//! --- Part Two ---
//! The light turns green and the door unlocks. As you collapse onto the bed in your room, your pager goes off!
//!
//! "It's an emergency!" the Elf calling you explains. "The soft serve machine in the cafeteria on sub-basement 7 just failed and you're the only one that knows how to fix it! We've already dispatched a reindeer to your location to pick you up."
//!
//! You hear the sound of hooves landing on your balcony.
//!
//! The reindeer carefully explores the contents of your room while you figure out how you're going to pay the 50 stars you owe the resort before you leave. Noticing that you look concerned, the reindeer wanders over to you; you see that it's carrying a small pouch.
//!
//! "Sorry for the trouble," a note in the pouch reads. Sitting at the bottom of the pouch is a gold coin with a little picture of a starfish on it.
//!
//! Looks like you only needed 49 stars after all.
//!
//! You don't have enough stars to pay the deposit, though. You need 2 more.
use aoc_runner_derive::aoc;
const MOD: usize = 20201227;
const SUBJECT_NUM: usize = 7;
// Returns loop size for given initial state.
fn solve(subject: usize, pk: usize) -> usize {
let mut acc = subject;
(0..)
.position(|_| {
acc = (acc * subject) % MOD;
acc == pk
})
.unwrap()
+ 1
}
fn find_encryption_key(pk0: usize, pk1: usize, subject: usize) -> usize {
//let l0 = solve(subject, pk0);
let l1 = solve(subject, pk1);
//(0..l0).fold(pk1, |acc, _| (acc * pk1) % MOD);
(0..l1).fold(pk0, |acc, _| (acc * pk0) % MOD)
}
#[aoc(day25, part1)]
fn solution1(input: &str) -> usize {
let pks: Vec<usize> = input
.split('\n')
.map(|l| l.parse::<usize>().expect("couldn't parse public key"))
.collect();
find_encryption_key(pks[0], pks[1], SUBJECT_NUM)
}
#[cfg(test)]
mod tests {
use super::*;
const CARD_PUBKEY: usize = 5764801;
const DOOR_PUBKEY: usize = 17807724;
#[test]
fn loop_solver() {
// Puzzle gives input in 1's based numbering.
assert_eq!(solve(SUBJECT_NUM, CARD_PUBKEY), 8 - 1);
assert_eq!(solve(SUBJECT_NUM, DOOR_PUBKEY), 11 - 1);
}
#[test]
fn enc_solver() {
assert_eq!(
find_encryption_key(CARD_PUBKEY, DOOR_PUBKEY, SUBJECT_NUM),
14897079
);
}
#[test]
fn part1() {
assert_eq!(
solution1(&format!("{}\n{}", CARD_PUBKEY, DOOR_PUBKEY)),
14897079
)
}
}

View File

@@ -7,9 +7,15 @@ pub mod day14;
pub mod day15; pub mod day15;
pub mod day16; pub mod day16;
pub mod day17; pub mod day17;
//pub mod day18; pub mod day18;
pub mod day19; pub mod day19;
pub mod day2; pub mod day2;
pub mod day20;
pub mod day21;
pub mod day22;
pub mod day23;
pub mod day24;
pub mod day25;
pub mod day3; pub mod day3;
pub mod day4; pub mod day4;
pub mod day5; pub mod day5;
@@ -20,4 +26,14 @@ pub mod day9;
use aoc_runner_derive::aoc_lib; use aoc_runner_derive::aoc_lib;
#[macro_export]
macro_rules! debug_print{
($($arg:tt)*) => (#[cfg(debug_assertions)] print!($($arg)*));
}
#[macro_export]
macro_rules! debug_println {
($($arg:tt)*) => (#[cfg(debug_assertions)] println!($($arg)*));
}
aoc_lib! { year = 2020 } aoc_lib! { year = 2020 }

225
2021/Cargo.lock generated Normal file
View File

@@ -0,0 +1,225 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "advent"
version = "0.1.0"
dependencies = [
"anyhow",
"aoc-runner",
"aoc-runner-derive",
"pretty_assertions",
"thiserror",
]
[[package]]
name = "advent2021"
version = "0.1.0"
dependencies = [
"advent",
"ansi_term",
"anyhow",
"aoc-runner",
"aoc-runner-derive",
"pretty_assertions",
"thiserror",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
[[package]]
name = "aoc-runner"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d21ef9204ad206a5a3e918e9920da04e1118ad91ce4f23570be964b9d6b9dfcb"
[[package]]
name = "aoc-runner-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba8b944269d3fee645d281b1335e1797044db497bb02d0098cc3fdb8900069cc"
dependencies = [
"aoc-runner-internal",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "aoc-runner-internal"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "274b0ba7f3669a45ec0aaacf94eb032a749de880ab776091576cca94037c9982"
dependencies = [
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "ctor"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "diff"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "output_vt100"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
dependencies = [
"winapi",
]
[[package]]
name = "pretty_assertions"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0cfe1b2403f172ba0f234e500906ee0a3e493fb81092dac23ebefe129301cc"
dependencies = [
"ansi_term",
"ctor",
"diff",
"output_vt100",
]
[[package]]
name = "proc-macro2"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
[[package]]
name = "serde"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
[[package]]
name = "serde_derive"
version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

15
2021/Cargo.toml Normal file
View File

@@ -0,0 +1,15 @@
[package]
name = "advent2021"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ansi_term = "0.12.1"
anyhow = "1.0.45"
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
pretty_assertions = "1.0.0"
thiserror = "1.0.30"
advent = { path = "../" }

2000
2021/input/2021/day1.txt Normal file

File diff suppressed because it is too large Load Diff

98
2021/input/2021/day10.txt Normal file
View File

@@ -0,0 +1,98 @@
{<[[<<<[[{[[<<()()>>[([]<>){{}{}}]]]<(<{{}<>}{{}{}}><{<>[]}[{}{}]>)({(())}<[(){}][(){}]>)>}]<<<(<<{}
{[({({([({(((<[]()>[()<>]){[<>[]](<>[])})<<<[]()}>(<()()>)>)}[{((<{}[]>{<>()}){[<>{}]<<><>>})(({[]()}<<>()>)<
(((([{{{<{<[[<()<>><<>{}>]]{<(<>())>}>{<[([]<>)<{}{}>][[<><>][<>[]]]>[{(<>{})[<>()]}<<()[]>[[]<
<<[<([[{{{[({<<>()>}<<<>[]>([]())>){{{{}[]}<(){}>)}]{{[(()())[(){}]]<<[]{}>({}[])>}({<<><>>}<([]<>){()[]}>)}
<[(({[({<<[[[{<>{}}(<><>))<(<>[])[{}[]]>]<[([][])[(){}]]>]([<[()()](<>[])>]<(<{}()>[{}<>])({<>[
(<[[{[[[(<((<<{}{}><[]<>>><[{}<>][<>[]]>)<(<{}<>><{}{}>)[{()[]}<<>()>]>)>[(<{({}{})}[{()[]}{[]<>}]>){<(([]
(([[({{{(<([({[]{}}){{[][]]}])>)[<([[[{}]{(){}}][([]())]]([{[][]}{<>()}](({}()){<>{}})))[{({
{(<<([([(<<[{((){})([]<>)}]<{{{}{}}{{}[]}}<{(){}}{()[]})>><([<[]{}>([]<>)](<()<>>)){<([]<>
{[<<[<{{((({<[[]{}]{{}}>{<{}<>>[<>[]]}})<{[(<><>><{}<>>][{[]{}}]}[[[[][]]<<>{}>]{[[]()][[]<>]}]>)[(
({<(<([{<{<[(((){}){(){}})]>}[{{{{()()}<[]()>}{{<>()}<{}{}>}}[[{{}{}}[<><>]]{({}[]>[[]{}]}]}({{{()()
{[[{([{<<{<(<<{}()>[()]>)<{{()()}}[<[][]>(<>{})]>>{[<{<>()){()<>}>{{()()}[<>()]}][[[{}[]]]<{{}[]}<()(
{{<<<<<[[([{<[{}[]]{()<>}>{<<>()>{{}<>}}}<<{{}()}{()()}>{[()<>]({}[])]>]{[(<{}{}>)<({}[])>]<{({}<>)}{({}())
({(<<{[<<{<(<[<>()][[][]]><[{}<>]({}[])>)[[[<>[]][[]()]]<{[]{}}[{}{}]>]>{[(<[]()>{<>{}})][<{{}}<{
(<<<[[({<[[(<<[]{}>>[(()<>)[<>{}]])<{(<>[])}(<<>()>[[]{}])>]<[({[]()}{{}{}})<{{}()}<{}<>>>]>][[({<<>()>{[]()}
{{{[<[([<(<{[([][])[{}[]]]{[()()]{{}()}}}><[<([][])(<>())><{()[]}({}<>)>]<<<(){}><<><>>>((()()){
[(((([{({<(<(<[]<>>{()[]})><{(<><>){{}[]}}{(()<>)([][])}>)>})}][({{[[{<(<><>){{}()}>((<>()){<>[]
([{<{<({(<[(<({}<>)><{[]}[{}[]]>)(<[[][]]{[]{}}>{{[]}((){})})]{(((()){{}()})(([][])({}{})))[(<()[]><(
[([{{<{(<[{{((()())<[]{}>){{{}<>}<<><>>}}[<([]())>[(()[])<{}{}>]]}{[({(){}}{(){}])<<[]()>{{}()}>
(<[<{{[<<({<<{<><>}><<()[]>[<><>]>>}{[(((){}){()<>}}<<[]()>{(){}}>]{{{{}[]}[{}<>]}[{{}{}}<(){}>]}}){{({
<([([[<[({<<{{[][]}<{}[]>}<<()[]>[()<>]>>>})((<(<[[]]((){})>{([]()){<><>}})>)(<<<<[]<>>[[]()])>>([[
[<<{<(<<{{[({<<>()><{}[]>})<{[<>()](<><>)}[{{}()}{[]()}]>]}}({<[{<()<>>}[<<>>]]((<[][]>{[][
{{(<({[((<([({()<>})[{{}[]}(()<>))]{[{[]<>}][{()<>}]})([({<><>}{{}()})])>)({<(((()<>)(<><>)))>((
[(<{({[<{<[<([{}()](<>{}))>]([([[]<>]<()<>>){<()>}]{{[[]()]{{}{}}}[{[]}{{}<>}]})>}<([<[<<>[]>]{<(){}>{
[[[[<(<({<[[<{()}{{}[]}><[<><>]<()[]>>](<([]{})[{}]>)]>}<[{[[{(){}}]{(<><>)}][<<[][]>{(){}
{(({({[{{((<[([]())((){})]>){[{(<>[])}<([]{})[[]<>]>]({<()<>>[[]<>]}[<()>{<>[]}])})({<([[][]]((){}))([<>{}])
<(<(<<{[<<{<<[()[]][[]()]><([][])<{}()>>}}>[<<<<{}<>>>{[{}][{}{}]}>[<[()()]{{}[]}>[{[][]}([])]]>[[<<[][]>(
<<{{({<<(([{{([][])(()<>)}}(<<[]{}>>)])([{[(()[])]}<{{<><>}<[]<>>}[<{}<>><[]<>)]>]{{<[{}[]]
({[[[[(([[[{<({})([]())>{{<>{}}}}][[<<[]>[<>()]>]{[[[]<>][<>{}]]{[<>[]]}})][[<(<(){}>{()[]})><[[()[
(((((([{{{(<<(<>{}){<>}><(()[])<()[]>>>{[<{}<>>(<>())}<{{}()}>})((([(){}]{<>})[{[]{}}{{}[]
(([([(((<[(({[<>()]{[][]}})[{{[]()>[[]{}]}(<<>{}><{}<>>)]){[({[]}(<>[]))([()()][<>{}])]({({}
[(<({{([[<(((<<>()>[[]<>])({{}()}<()<>>))[[{[]()}<()<>>][{()()}<{}[]>]])>({(<({}{})<()[]}>[{()
{{{[([<{{{([<<<>{}>{()<>}>{<{}()><<><>>}]([{()}]))<{[<()()>{()[]}]{({}[])[<>()]}}>}}}({<(({({
[([([<[<(<[{{{<>()}{()[]}}({()[]}[{}<>])}{[{<>}]([[][]]<(){}>)}]>[[{<[<>()][{}()]>(((){}>[<>[]])}{{{<>(
{{[{{[[<{(<([[[][]]([]<>)])>)<{<<{<>()}[<>()]><((){})<<><>>>>([<<><>>(()<>)]([(){}}{[]<>}))}>}(({{{{[]}{
[[[[({[<({{[[(<><>)]{<<>[]>([]{})}]<[{[]}{()()}]([<>()]([]<>>)>}})>{{<([{<{}{}>{()}}])({<[<>()](<><>)>
{[({<[({[{[({[{}()][[]<>]}((()<>)<{}<>>))<[{{}}({}{})]>]{[<<<>[]>[[][]]>(({}[])(()[]))>{(([]{})({}[]))([
[<<([{{(<<[<[[{}[]]](<[]{}>[<>{}])>[[<{}[]>(<>[])]{([][])[()[]]}]][[{{()[]}[<>{}]}(<<>{}>[[]
<[(([{([([<{[[(){}]<<>{}>]}[[[()()]{{}<>}]]>[[{({}{})[()()]}([()()][<>[]])]{<[[]<>][[][]]>}]]{{<{[<>
[<[[[[([[{[[<[{}{}]([]<>)>[({}[])<[]<>>]][<{()()}[<>[]]>([[]]<<><>>)]]}([<{{{}[]}}{(()<>>({}[
<[<{[(<{({[<[[[][]]([][])]<([]){{}<>}>>[({<>{}}<[]>)]]([[([]{})[[]()]][[[]{}]({}{})]](<[{}<>
({[<([(<[[<([[(){}]<<>{}>])({[[]{}]<()[]>}<<[]<>>{[][]}>)>{<[<[]()><{}[]>]([<>()]({}[]))><(
({<<<{<({[[{[{<>{}}[<><>]]}{(({})[()()])<<()<>>([]{})>}]]]{<{{([[]<>](<>[]))[[{}()]({}())]}}>((<([{}<>])>{{<[
[{([{[[{{<{<[{[]()}<[]{}>]>({<{}[]>{<>[]}})}[(({{}<>}<{}<>]){[[]{}]({}[])})]>}}]({([[([<()()>{[]
<[{([([{[{<(([<>[]]{<>()})<{{}<>}>){([<><>])<(()[])<<>{}>>}><{{[{}<>]{<>}}[(())[()<>]]}<{[{}{}]{{}{}}}<{{}<>
[{<<([{{(((<{<<>()>[{}()]}>{<<<>[]><[]()>>}){[(([][])([]()))<{{}[]}[[]()]>][[{{}<>}({}{})]{({}{})(<
{({[((<([[[{{([])[()()]}({{}{}}))<(<[]<>>[()[]])>]<<([[]<>])<[<>()][[]<>]>>({[<><>]{{}[]}}({()[]
{[(<(<{[({[(<<[]>{<>{}}>[{<><>}([]())])(<[[][]]<()<>>>[(()[])])]<{[{()[]}[<>{}]]}[{<(){}>(<>{})}<<<>()>>]
(<{<[<({{{{([({}{})[[]{}]]({{}<>}<()[]}))}(<<{<>()}{()<>}>{[<>{}][()[]]}>{<<[][]>{<>()}><(<>{})<{}[]>>})}
{(<<{[({<<[(<{{}{}}<[]<>>>((<>())([]<>)))]>><<({<{[]<>}([]<>)>{[()()]}}<<{{}<>}<()()>>(<()()
<([([<(<[({[[({}()){()<>}](({}{})(<><>))][{({}<>)<{}{}>}{([]){(){}}}]})]>)<[[{<{{(()){<>[]}}({{}()}
<<<([{[({{{((<{}()>{()()})[[<>()]])[[[{}()]<{}()>]{{[]<>}{{}())}]}<<{<<>><<><>>}[{{}[]}(<><>)
<([<[<{[[[{[{[<><>][{}<>]}(<[]{}>)]}([{{<>()}<{}[]>}{([]<>)[(){}]}]<{((){})<[]()>}[<[]()><()[]>]>
[([[[[[({{[(<[{}<>]<{}()>><[<><>]{<>()}>)]}<{(<(()<>)<{}{}>>{{()<>}(()()}})}>})(<[<([<<>[]>((){})]([[]<>]<()
{(<[[{(((([[([{}()]<{}()))[({}{}){[]}]](<<<>[]>>([<>{}]))][(<({}{})<()[]>><<[]{}><{}[]>>)])(<([([][])[
({(([{{<{{{<[<<>[]>{()<>}][([][]){()<>}]>([<()>(<><>)]<{<><>}<[]>>)}<{[[<>[]][<>{}]]<{<>()}{[][]
{[([[[(([<{<{[[]<>]<<>()>}<<()()>([]{})>>[<<()[]>(<>())>[(()<>)]]}>]{{({{{{}[]}({})}<{{}<>}[[]()]>}((
[<([[<[{{{[[[<<>{}>]{<()[]>{[]<>}}]{([[]{}]({}()))}]}}}(<{<[[({}{})<()()>]]({({}<>)[[]]}{[<><>]{<>{}}})>(<[
<<(<<{{(({<[<<[]{}>{()()}}[[()[]]]]{[(<>{}){<>}]{[{}](<>)}}><{<(()())<[]<>>>[<(){}>(<>[])]
{<(<[<[(((<{((()[])([]<>))([[]<>]({}[]))}><<([<>())<[]<>>)(<{}[]>({}<>))>[[([]())]({()()}{{}<>})
[[((<[[[{{<{<{{}()}[{}()]>{{[]{}}[<><>]}}>}<{[<[(){}]<<><>>]([{}<>]<<><>>)]}(<<[{}<>]<<>{}>
<[{{[[{<[{(({[(){}]({}{})})[([{}<>][()()])[<[][]><{}<>>]])}](<({(([]<>){()[]})[([]())((){})]}{{{<>{}}<[]()>}<
<{((<([[{<<[(<{}()><{}[]>)]>[([{<>()}<()()>]<{()[]><()[]>>){<[{}[]]>[{[][]}(<><>)]}]>{{[{{{}<>}{<>}}[[(){}]<(
{<[({(<{{[([{{[]{}}((){})}[[{}[]]<{}()>]]((<[]<>>)<([]()){{}[]}>))(<<{()[]}{[]})>[[(()())]{[()<>][<>(
<<{[[[[{<({<[[{}()]]{{[]<>}{[]}}><{{{}()}({}{})}>}{([({}[])({}())](({}[])))[<{[]<>}[<>()]><<[]<>>(<>[])>]}
[(([<<[{[{<({{()[]}<<><>>})[[([]())[[]{}])(<<>{}>)]>(<{{[][]}[{}()]}([{}{}][(){}])>((<<>[]>(()
[({<<[[<{[<<({[]()}<()<>>)>]]{{<[[[]][{}<>]]>}{([[<>{}][{}{}]]<((){})(()[])>)}}}([{((<{}[]>)[<{}[]><{}()>])}
{[[((<[{<<([{<<><>>([]{})}<(<><>)<<>()>>][{[[]{}]{()()}}<({}{})([][])>])><<{({<>{}}[<>()])((
[[[<{{(<((([{<[]{}>({}<>)}[<<>()>]]<<(()[]){{}[]}>{(()<>){{}<>}}>){{{(()())[<><>]}[[[]<>]{<>[]}]}}))[
(<({[({[[({{<{<>{}}<()[]>>[{(){}}<<>[]>]}[[<[][]><()<>>]({<>{}}{[]()})]}{(([[]<>][{}[]])(<[]<>>([
{([<{[<({{{({[[][]][()()])[<<>()><[][]>])}<{{{[]()}[{}()]}{{<>()}{<>}}}((({}())<{}{}>){(<>{})[<>{}]})>}})(((
([[[[[[{(((((<<>()>[[]<>])<{()()}[()<>]>){<[()[]]<<>[]>>(<<>{}}{{}[]})}))<<[([()()][[]()])[{()[]}([]())]][<([
({{((((<{<[{[(<>{})][<()()>[[]()]]}]{({(<>())[[]()]}{<[][]><[][]>})}>}>{<<{{(({}())[<>])((()[])<[]<>>)}}[
<(<[[[<<{([<<[[]<>]{<>[]}><{()()}([]<>)>>]{<{(<>())((){})}{[{}{}]<<>{}>}>})({([[{}{}]])[(<<>()>[
{[(<{<[[{<{{(<()[]><<>{}>){[()<>]<{}<>>}}[[[<>{}][[]<>]]]}<[[({})<<>[]>]]{{<()<>><<>[]>}<{()[]}((){}
({[{(<<{[<{({[()()]{{}}}<({}{}){()()}>)}<{(({}{})[<>[]]){([]())[[][]]}}{(<[]<>)[()])[[<>()]]}>>
(({<<[<[<<<({<{}[]>({}{})}{<{}[]><{}[]>})>>(<<(<()()>{[]{}})({()<>}[()()])>[{[{}()][[]]}({<>()}}]>(
<<(<(<[{([{<[[<>{}]<{}<>>]>{<(()[])(()())><{<>[]}{()()}>}}([{({}<>){<>{}}}{{<>[]}[{}{}]}]([<[]()>((){})
{[{([({[[<<<{{[]{}}<[]{}>}[<()[]><[]<>>]>([{{}[]][[][]]]{{(){}}({}[])})>(<{[<>{}](()<>)}>{[<[]()>
([[[<(<{[({<({()()}{<>()})((<>[])<[]<>>)>}<{<<{}()><<>>>}({{{}[]}}[(()[])[()<>]])>)<[<((()())[<>{}])(
{<(((<[((((({<[]>[[]{}]}))[(<[[][]][{}{}]>){{[<>()][[]<>]}([()()](<><>))}])){(<[{[<>()][{}()]
({([{<(((<{[<[{}[]]<<>>>({{}[]}[[]()])]([<(){}>])}{<[{<>[]}{[]<>}][<<><>){<>{}}]>[<((){})([]{})>[[{}{}][()
<[{[<[{[({{<(({}<>}[[]()])>({{[][]}}<[(){}](()[])>)}})([[{{<<>()>([]{})}[<<>{}>[<><>]]}]])]
{(<{([{[[({[(<[]{}>)({{}[]}{()()}))<{(()[])}[[()()]{{}[]}]>}<{<(()<>)>{{[]{}}({}())}}({{{}[]}{<
[<<{<{<<(<([<(<>()){[]()}>[({}<>)({}<>)]][(([]{}){()[]})[{{}()}(()())]])>{([{{()[]}<<>[]>}<{<>[
{{[[(([([({([([]<>)(()())][{<>()}{(){}}])})])]([{{[<{{{}<>}(<>())>{[()()]<<>[]>}>[{(()){{}[
[({({({(({{(<[()()][{}<>]>[[{}()]{(){}}])<[<<>[]>][<{}>(<>{})]>}(((({}())({}{}))){{(()[])<[][
<(<(<[([<[{[<(()<>)<()[]>><(<>())([][])>]{<[{}<>]{{}()}>{[[]{}](<>{})}}}<[<([]{})><{{}<>}([]())>]>]>
<<<(<<[({{{<{({}<>)<()[]>}<[()<>]{(){}}>><{[[]()]<[]{}>}[({}{})<(){}>]>}(<[<<>[]>{()[]}]>)}[<{[<{}>[{}{
{(<((<[{{[[[[<{}{}]<{}()>]][{({}{})<<>{}>}[<()[]>(()())]]]{([<[]()><[]{}>](<{}()>))({<<><>>(<>())}{
{({{[[<[{<{{(<<>>)(<[]()>[()])}([({}<>)])}[[{[()<>][()[]]}]({<[]<>>{<>()}})]><<(<<{}()>{<>[]
{{{[{[<<{[[{[{{}<>}<[][]>]{(()[])<<>()>}}[<{()()}[(){}]><<()[]>>]]{<((<>{})({}()))[<(){}>([][])]>{({{}[]}<
<{{[<{({{{[<{{<>()}{{}()}}>]<{<[()[]](<><>)><[<>[]]{(){}}>}<([(){}]<{}{}>){(())}>>}[([{[[]<>][{}<>]}[{()}(
[<<[{{(({({<{{{}{}}{<>[]}}({[][]}{<>[]})>[{[{}<>][<>[]]}[({}[])[[]<>]]]})}))<(<[[<(({}()))[<<>()>{(
{<<([<{({[{{[({}[])<<>{}>]([()<>]<(){}>)}<([{}[]]({}{}))>}[<<<<>{}>[[][]]>{<<>[]><()>}>[<<<>><[][]>
[({(<({[<[{{[<<>[]>[()[]]]<<<>[]>>}}<{([{}[]](<>{}))[{<>}{{}<>}]}(<<[][]>>[{[]<>}])>]>[(<(({<>[]}{<><>}))(<
{<[[{{<<{(<(<([]<>)[[][]]>[([]{})[<>{}]])<[{<>()}{[]<>}]>>>[{(({()()}[<>[]]){({}())<[]<>>})}[(<{<>
{[[{{{<[<[{<(({}{})[{}()])[(<><>)({}())]>}{[<{[]{}}[()[]]>]<{[()()]<[]()>}<[[][]]>>}]>{{({{{()[]}{{}(
<{[<([{{[[<(<{<><>}[{}{}]><((){})>){[[()()][()[]]]{[[]<>]}}>]<<(<({}[])<{}[]>>{(<><>)<[]()>}){(<

10
2021/input/2021/day11.txt Normal file
View File

@@ -0,0 +1,10 @@
7313511551
3724855867
2374331571
4438213437
6511566287
6727245532
3736868662
2348138263
2417483121
8812617112

22
2021/input/2021/day12.txt Normal file
View File

@@ -0,0 +1,22 @@
zs-WO
zs-QJ
WO-zt
zs-DP
WO-end
gv-zt
iu-SK
HW-zs
iu-WO
gv-WO
gv-start
gv-DP
start-WO
HW-zt
iu-HW
gv-HW
zs-SK
HW-end
zs-end
DP-by
DP-iu
zt-start

910
2021/input/2021/day13.txt Normal file
View File

@@ -0,0 +1,910 @@
724,201
596,511
883,560
637,47
869,537
251,505
851,618
980,544
818,661
1093,390
641,95
1006,621
447,434
820,865
475,847
788,72
1066,829
1303,882
1165,696
164,229
202,333
244,485
261,840
1116,581
976,513
550,635
1151,728
1211,570
228,422
223,539
406,369
306,758
1247,894
760,859
826,737
340,637
1293,47
99,187
264,553
927,523
940,189
586,313
525,67
296,581
353,694
55,264
582,491
264,154
512,394
1101,225
555,187
1021,535
805,772
783,891
403,402
1243,94
495,593
1031,695
13,472
705,637
459,618
939,322
251,82
899,523
301,131
873,891
880,374
894,737
306,593
1257,280
88,885
621,655
38,640
514,539
1222,885
1257,135
1191,303
1034,715
649,738
719,103
1131,367
907,402
169,297
482,408
977,866
1280,432
1087,803
473,810
182,546
785,155
1257,871
1091,483
310,52
758,712
870,715
1211,772
1173,40
73,460
117,312
228,243
918,822
475,50
765,3
1113,410
127,544
880,422
291,675
1088,187
957,506
591,791
566,437
1178,593
159,728
1237,684
490,665
929,311
641,267
966,766
1081,253
735,649
857,750
999,367
989,221
0,185
445,395
108,168
586,761
1203,595
1115,89
838,665
487,301
289,647
903,133
251,53
887,800
1093,443
775,684
1026,481
601,311
661,476
1198,627
0,753
1231,786
410,821
358,742
1179,780
763,435
1077,133
927,182
681,144
497,597
1088,483
649,476
1202,415
440,583
1198,14
104,775
619,443
410,660
1034,656
115,575
601,728
338,222
84,301
1111,891
1211,122
653,614
1290,282
209,582
440,43
929,583
53,166
1004,301
263,572
818,233
1183,319
228,472
1257,166
656,329
53,135
669,267
815,593
1111,767
802,576
1226,660
1215,800
341,218
181,422
1046,565
159,280
119,303
1027,303
147,417
571,859
1173,261
1054,885
239,302
228,131
85,217
1231,226
137,709
21,131
1290,612
718,845
837,782
164,141
632,467
749,313
525,379
858,561
851,786
1228,857
33,239
868,670
1183,3
248,548
328,345
898,436
438,893
823,301
820,589
937,771
875,58
790,617
64,504
95,675
508,576
729,434
186,91
1092,392
403,166
87,514
1261,114
1141,597
217,390
689,151
457,515
585,805
1131,360
1212,472
669,464
318,682
485,73
1154,644
738,37
1297,870
361,207
932,238
880,264
376,738
87,380
174,94
411,819
845,633
1288,721
189,261
1294,374
72,267
649,642
156,644
517,406
705,562
1059,614
813,856
623,702
619,462
403,728
344,52
1178,634
1275,238
656,47
1176,169
244,821
328,121
1092,255
872,1
845,185
251,707
79,674
659,705
1048,520
1121,709
107,768
427,334
1257,311
112,14
997,351
552,429
1064,159
1114,453
398,306
1208,182
187,175
654,719
1225,665
735,245
1078,245
544,598
691,238
1168,164
264,740
855,833
1260,267
661,156
333,194
1212,870
555,803
445,11
1275,443
1067,35
783,787
785,379
162,141
661,866
873,3
321,476
1136,800
673,47
723,800
1129,84
127,891
927,371
781,647
1099,247
1275,3
691,891
218,639
731,626
1093,504
550,735
1019,880
477,142
147,508
392,822
542,432
209,235
410,234
895,113
107,798
7,23
119,591
709,364
1059,340
1198,148
179,360
226,49
43,98
195,640
452,561
49,52
359,761
1307,749
1235,392
556,355
547,58
790,725
8,683
1261,724
301,185
69,89
545,339
957,759
509,84
1235,564
663,12
1017,743
739,332
1213,392
1067,444
291,616
969,851
353,819
669,95
902,436
127,575
887,143
671,79
796,539
865,11
289,247
465,709
605,724
194,581
1223,788
810,771
932,208
333,225
1308,96
1257,23
709,311
87,123
845,807
845,574
552,630
1226,234
16,374
1247,0
381,311
957,11
393,392
545,219
523,332
820,661
472,229
1079,542
99,570
311,847
1130,500
519,135
207,434
435,235
373,499
731,368
800,348
373,771
904,861
687,192
1297,24
681,131
545,555
705,170
1009,200
63,828
1193,582
211,647
982,495
1206,159
1014,581
284,481
1294,394
5,156
641,627
744,885
900,212
557,887
908,289
786,856
785,515
527,61
73,684
698,637
522,294
79,226
843,175
754,315
798,606
25,730
790,169
947,686
509,646
157,38
994,451
31,702
622,453
390,742
256,558
1274,448
950,833
619,238
723,94
67,94
490,383
447,658
654,686
407,313
1054,9
982,175
1215,766
1198,880
1054,306
1305,156
407,245
328,208
273,787
693,807
939,751
232,245
1047,770
1063,133
87,828
1285,409
787,803
1056,715
654,701
1201,56
865,728
1000,318
546,31
671,63
490,29
863,658
234,841
940,481
7,460
1213,495
411,75
1280,856
949,599
743,106
301,435
390,497
416,157
411,523
1057,12
907,492
1138,486
132,301
383,571
833,304
271,323
788,238
726,112
30,432
1288,313
688,441
605,649
982,345
174,652
527,721
284,257
927,571
623,254
1082,243
977,669
472,665
705,724
947,768
559,800
951,133
207,460
279,247
360,833
1223,514
63,0
182,5
522,520
17,495
555,324
390,397
827,882
107,683
430,856
1150,656
579,788
769,170
164,677
1082,651
883,894
982,656
641,198
576,320
863,210
857,144
984,549
672,766
67,800
35,443
412,682
326,529
304,621
556,539
117,669
918,72
654,47
219,388
654,753
1246,56
654,641
1250,848
562,681
72,403
1228,305
641,422
758,856
1082,472
701,256
1077,761
820,511
755,324
658,509
960,733
801,10
769,378
430,38
647,12
129,291
201,750
522,374
837,422
75,564
977,225
609,256
855,350
1128,5
1245,495
1240,530
591,551
555,154
45,275
381,359
922,253
1026,257
251,280
629,798
739,371
492,708
719,551
508,318
678,427
1109,302
754,539
884,472
705,245
654,453
256,530
1184,793
79,201
731,788
1076,53
430,264
999,54
691,432
837,810
669,696
181,810
132,520
885,641
117,480
729,460
437,891
242,212
1263,507
353,75
316,787
179,24
967,815
490,305
214,583
801,646
1278,441
1163,392
485,521
845,709
104,159
276,715
85,229
522,145
214,851
377,257
490,661
1285,485
278,828
492,661
363,686
709,82
970,705
535,882
256,364
131,114
427,635
440,179
890,681
1029,571
360,61
78,413
746,179
1128,889
1288,173
1213,47
321,700
137,40
720,315
1241,89
137,807
99,539
104,287
527,891
415,116
229,253
574,605
276,686
329,838
1309,728
95,667
899,819
561,805
669,430
1206,735
1006,313
231,542
438,669
1211,355
947,880
783,168
93,581
415,302
195,254
231,784
442,670
872,225
800,98
817,58
1079,94
341,340
131,780
426,315
1211,826
1247,707
363,219
406,817
820,383
465,633
547,459
334,605
1115,254
927,164
5,866
239,778
97,847
271,730
75,392
438,225
326,686
570,301
564,179
195,192
1225,217
751,367
477,116
1116,805
801,84
247,674
189,126
1101,499
1161,570
989,418
400,491
810,123
468,397
1235,523
803,607
247,133
0,847
1146,305
884,315
164,569
913,313
412,212
112,627
209,312
711,523
427,894
1235,140
131,803
1232,413
199,891
49,724
947,14
313,351
898,10
1277,655
887,334
982,719
1230,829
316,222
209,728
592,845
1285,803
490,589
903,245
283,591
1197,516
197,827
619,451
509,884
1297,43
1141,73
1131,63
584,530
820,29
107,836
251,841
529,247
400,715
607,387
301,759
1048,374
227,707
281,771
711,607
1049,392
304,313
1235,626
209,883
452,333
30,408
403,492
510,98
933,68
161,58
1242,693
251,389
1191,322
1131,527
1213,439
586,201
904,369
783,319
929,359
838,348
878,411
109,443
1082,131
350,621
1048,889
326,208
763,96
132,593
84,350
1059,82
678,467
1091,836
1235,371
582,715
641,464
55,795
293,687
723,336
341,472
371,322
555,602
840,500
199,833
455,833
169,73
97,392
783,385
623,640
1111,840
765,891
1046,553
383,164
907,812
1131,870
1067,892
1129,472
246,436
644,670
624,38
353,135
666,227
835,399
112,148
247,859
383,99
535,684
338,555
552,805
594,17
880,472
801,436
997,472
559,667
341,676
247,35
1193,225
1,56
545,3
1149,58
455,710
753,887
687,640
1220,379
1115,724
1203,574
465,320
84,772
1273,359
873,339
783,3
199,54
1193,669
264,329
246,513
33,655
1293,495
432,187
601,871
803,47
825,373
259,110
586,245
412,436
927,347
345,775
970,257
870,311
fold along x=655
fold along y=447
fold along x=327
fold along y=223
fold along x=163
fold along y=111
fold along x=81
fold along y=55
fold along x=40
fold along y=27
fold along y=13
fold along y=6

102
2021/input/2021/day14.txt Normal file
View File

@@ -0,0 +1,102 @@
VHCKBFOVCHHKOHBPNCKO
SO -> F
OP -> V
NF -> F
BO -> V
BH -> S
VB -> B
SV -> B
BK -> S
KC -> N
SP -> O
CP -> O
VN -> O
HO -> S
PC -> B
CS -> O
PO -> K
KF -> B
BP -> K
VO -> O
HB -> N
PH -> O
FF -> O
FB -> K
CC -> H
FK -> F
HV -> P
CO -> S
OC -> N
KV -> V
SS -> O
FC -> O
NP -> B
OH -> B
OF -> K
KB -> K
BN -> C
OK -> C
NC -> O
NO -> O
FS -> C
VP -> K
KP -> S
VS -> B
VV -> N
NN -> P
KH -> P
OB -> H
HP -> H
KK -> H
FH -> F
KS -> V
BS -> V
SN -> H
CB -> B
HN -> K
SB -> O
OS -> K
BC -> H
OV -> N
PN -> B
VH -> N
SK -> C
PV -> K
VC -> N
PF -> S
NB -> B
PP -> S
NS -> F
PB -> B
CV -> C
HK -> P
PK -> S
NH -> B
SH -> V
KO -> H
NV -> B
HH -> V
FO -> O
CK -> O
VK -> F
HF -> O
BF -> C
BV -> P
KN -> K
VF -> C
FN -> V
ON -> C
SF -> F
SC -> C
OO -> S
FP -> K
PS -> C
NK -> O
BB -> V
HC -> H
FV -> V
CH -> N
HS -> V
CF -> F
CN -> S

100
2021/input/2021/day15.txt Normal file
View File

@@ -0,0 +1,100 @@
1377191657764644549114627284634913412287739519982496231416283824918194961929936311588211113324916282
1212297521448698359953919612341968949351139967911631956522229222119792152999899993551168415419536961
6159423311678979112521371444921299897197276181489988271511963872918146853113979656119891919929116284
4791323871358399412199298219622788641186798927938163199341117218462279651818983841791285198158689197
7974189811899763275179618283116319192597185732127393472591197762491696726534696112661928998124191441
1719457851119351145679896476439455919892412234291392849988759922872162286199995759192522267673971911
5158991981989914259268282912286934836159941437649989252868156886971224151841291227119542781714229192
8971141349643841951211794248819968548427435466191723999244827371882121325261988461388697379557117813
6984596925919191179943678951217187999979717952993237915971469193192562968292161332928141319899991618
9198522521864259381829335129227674372277199124547185988889492259941882883937916158399823156688865128
8124682618753649934148821878377819747891787181829195781346118199594997697952812114668182584998375593
9981691284313278913662888992426344931897231669692112847984979448943849148537789387936982196747899979
4612594287729384862398119828742189442883965266198489994718698924935284181865741287193312419976111121
9698161969149478565386491726144137461938929999938688185784251478539975684351897911814796415999137427
4215198687955128645232416239572133179888263876627217299182179119281398198291519743556311698595119447
4769546216536687838722946279539949718927689379457711267152121289312649499122925941999769894516538948
2995881981397899317151897695171147699149921139717478649199572991745138182938859417981979318636371733
5896265687179618976487519127375146169177832848256796867888967833698488841993835411394159986678877843
3216645889149389762597933279559298615997238172696673733899239658535753129812911379977549791117989658
3884816682163948316281466989293387989351399981758245478789465919897897823972111872243196689493592859
2147411131991983852642238326868847926889726486359749798736947597961361232791761388538288138311778889
9667691879291819996979958298917569848789574811461556979737155191582528998586729496138919417641516671
2985749275368176832969872226792613823962499974291511594718356964791163978998319397955899236233367196
9146792975371119515819629946162595322898172566118389981777412389859448518999793848789641614927396527
3837698153921119789191289266863437969919159469416859886989979288999338293364182598593531435838918299
3116635237718874995349321215895321218981134288293817795799641825791914139998851951282874988993695793
7561593471951437617129518549197936965341984929165166946255778981198999251529198369291988622121996798
5671179846637276839326113991917774391317631914135868839991981526789969485778186774513984993819918858
6829332192876499239259333179131416651652797879989678673653791799313167962195825894623277922675147419
2114199213615191896184775491411521611589987859919419942228661718872131759515219245894537581322719999
9111987791914149296428193389129811532587733939222947217392149842114232514793791618151173592229671281
6995979618889983189931395618837152991881964616562117919875424671693616994916979814989851972258726362
8173982492272918487736387139295771914721973489627891148815174139856171119417695981112277482189839214
1973523966752994411692968746997296995879577697121374597143849499591366213426378939791149178595161638
5585893988624565875416425158849421541992777828132459639548799994998964889296735678462311472353412967
7998888978481899581293841169535632193113981375899864159935724481141949931596889935158262842998335918
3628289787876715955926724188591588897816776996999489661971733199394273281174961857913237989933989451
8999891193589892228558191976973146639339899432418722147824142953482626221311856529949321934951835227
3992588951996859132652698919297445999986186384145475156862729991985721181638964313723299881446598791
8998893814179771279297296539879723788234226489159913739727989917182438292712863462491283593165387584
2225959678947915336339588711833943992739379439179861836978399199426662599832739483128822695786825928
4919938138891315978138689416887291774881364839148591162128739219164535299459734549155337432999197911
5811216519919174895539797554977936679185698239492921912567121774999488711422544391969771432876537978
5239614948192317841478695119921598999373194178187891395921768432788912522293359417821221957119946281
1988479858958131921192883481392499559613188252381615491311198981658653691389656839995274969418186999
7681966495996941919639623988649188782853795834411334478225123731129587739936417679491619562326995611
5163121511288963298982952314191859371657513679589589729491476296199145629795989556991718931869954195
5286192694799561972391914255528729388961162579826999991948753996967849341943671642439977232844987241
4428178895995144247759399167269333681679595491292381917995999298326832893137644125138231529974592499
4818747595975454796832557299789738541316991638259842799695195686599979445783273918859921299915986952
9417754891252219525194996254344713299966647874186411227972277894179442589131199217999933824814123221
4994994141179221782999435468132963989941331328924377879416667894964349919881719919273389195858632919
6976968727729789979799866987389137352126998771769996593346529935239178231461934599332849891191669783
3638279769222728924783398321639372424899579939421986797719284324742197761998188819691989998694456134
7942399772312398643212169162588662393626113494573293938992496629858316948459199523796897485999921378
1618926196928832916821317498771468433845191219257749761298211872798193673922139789349388129994864112
2744672662951116969991384387997932899791711411128942949881741539172615486131619958932849888897989682
8193685169797222169278874619231971178551717869816119199998223293869323667584378393769322171757659961
3567192399993235879219629458779937992841292566997843196897379191646481548121489984711917991295935959
9145791161291867819713918855165912963216971699817988984653272136935995972742126586832589192163991927
8712419729372896439849678162371923271999124418917611596199166288782836898567935828461556972645691618
1974943823672482569954185719922998567599896762236938717767279661182995366114432538799683897379592854
9379716279297768319753269447991272919214661239572849997471968329889977329941157596172896596534356541
6646625991776574551798145872614721797912217571335478976189691399885799159954742823589679431499683381
8989686475467621429635363139819837633819917676359955759915798412948369139162496822357488719729929699
9952575399865114983355711819388989998898752988216171812892716892892635288989999528963419618898418969
5628277482612799192913177936216253978413218756816239842196325888285889223998597986171699813494975765
8787997189686121858117929165777499728392581119799148997676831848921925893394992791762794499675789289
7568442691119995411445659817292988957454727197967556114172439626332319694755129914814595388989917393
1167946915152153284992129919799398949246947728761958125919513931223797949156627271789872543952184319
4333282313991449435292492972979115959364971739574697214551891471125231369421937456949722396783112819
7993297562943921256985797994839951414791377275818117983949117165983469235412826115996393789982931376
1298945898187917593419458849192816235299119793321858952722674788872499636859117952152983654581115748
4878958876835131628931718969837331917173664888187661244567581167587853362752963213489995238858567899
9168679699798852526937699621149596872192558861969279971951421899916958917919199222795984799115181512
8495992724128927671571265912135878347948681836489591199188311363919513913891778977157177888916936997
8999191812299999181826412647458779129464557453899711499291711727199181999313788754481739897894282299
2297358211198319622489958131157137589129796865587176999673399971359991483798893432429642581288291194
9191151249993972592269748389939197998879479776716874389424892989896918395262244556692919498634767192
3146999389982294398923279851895822879874999174675832246619395368959948618376991191857891919997189827
9252644326896871318783941879993798291951189674981419995699216498289849253481984958375343761948696962
4149366989699391314516198739739998365611211146769689837964632818199827733417982911432639733919961118
3785694943346449113313437192173297234317511989486918779179169811959978466519619814382389974795179229
8173193661981438212589321931819226834981393943686781771986927128994261912991939615971363661699439979
8479197349619477856688178917192741661541913841798699288998264161919784358998345986951361544895722194
9387823917552123692884995799334448659591539912212939191659149351819987712961219375817984328598599894
7812964315918866599999396818117119925739213839329419979879298266584522638128949596632628794899927594
2391843348716127619923835446829918293129713997618113899286695811914941791777191781188282864971628831
9869814173464627244763819721441998547833914115357196275866981483721979728829754991183494575248873899
3759525119799512972171139432761121922192889938411511154289933278983814729624198361288155121749742596
2429134344895591883761666874289213982919652654471211641928968826911633151195891488124183473783171928
8886181492349995235524939198716394499923967835658289266169965949434995834857389557293375945691237192
2153231111419541496813818582276229211229793882886697591279261494221346473438333716131521195987982819
9983399491911518719129352817678695921953245885213828259983567431899628715997395359992977155298181325
3474642518564151369499969799513918368919798899185479829989997639246197855513493872738928431872179498
2732318412186196256356897928718985284818126794829779199946899179899192919186578957838955489991999919
5174898514492714279961793617689337727531149659179437978254251988382912951529715877997391742994559149
6441191197877982527547982766164652298155632979453683329949678198587924143899618194194673133812385279
9721933192312647794494392675978994249714237519435528899779968981967867171823197399159123171497951794
9529734972179199615231232651591988769887899696743322386222999813557814511366456767451396998925196619

View File

@@ -0,0 +1 @@
6051639005B56008C1D9BB3CC9DAD5BE97A4A9104700AE76E672DC95AAE91425EF6AD8BA5591C00F92073004AC0171007E0BC248BE0008645982B1CA680A7A0CC60096802723C94C265E5B9699E7E94D6070C016958F99AC015100760B45884600087C6E88B091C014959C83E740440209FC89C2896A50765A59CE299F3640D300827902547661964D2239180393AF92A8B28F4401BCC8ED52C01591D7E9D2591D7E9D273005A5D127C99802C095B044D5A19A73DC0E9C553004F000DE953588129E372008F2C0169FDB44FA6C9219803E00085C378891F00010E8FF1AE398803D1BE25C743005A6477801F59CC4FA1F3989F420C0149ED9CF006A000084C5386D1F4401F87310E313804D33B4095AFBED32ABF2CA28007DC9D3D713300524BCA940097CA8A4AF9F4C00F9B6D00088654867A7BC8BCA4829402F9D6895B2E4DF7E373189D9BE6BF86B200B7E3C68021331CD4AE6639A974232008E663C3FE00A4E0949124ED69087A848002749002151561F45B3007218C7A8FE600FC228D50B8C01097EEDD7001CF9DE5C0E62DEB089805330ED30CD3C0D3A3F367A40147E8023221F221531C9681100C717002100B36002A19809D15003900892601F950073630024805F400150D400A70028C00F5002C00252600698400A700326C0E44590039687B313BF669F35C9EF974396EF0A647533F2011B340151007637C46860200D43085712A7E4FE60086003E5234B5A56129C91FC93F1802F12EC01292BD754BCED27B92BD754BCED27B100264C4C40109D578CA600AC9AB5802B238E67495391D5CFC402E8B325C1E86F266F250B77ECC600BE006EE00085C7E8DF044001088E31420BCB08A003A72BF87D7A36C994CE76545030047801539F649BF4DEA52CBCA00B4EF3DE9B9CFEE379F14608

View File

@@ -0,0 +1 @@
target area: x=88..125, y=-157..-103

100
2021/input/2021/day18.txt Normal file
View File

@@ -0,0 +1,100 @@
[[2,[2,[4,0]]],[6,1]]
[[3,[4,[2,4]]],[[6,9],[6,1]]]
[7,[8,[8,[0,8]]]]
[[[[2,9],5],5],[[[0,1],8],[[7,9],5]]]
[[[[3,0],[7,0]],[[9,6],[1,9]]],4]
[[[0,[4,8]],8],[[[2,1],9],6]]
[[[5,[7,7]],[[9,6],2]],[[[5,8],8],0]]
[[0,3],[[8,2],[6,[2,2]]]]
[[[9,0],[4,[4,7]]],[7,[[9,1],9]]]
[0,[7,[1,1]]]
[[[4,[0,1]],[[1,0],8]],[[[3,9],[0,1]],[[9,1],[8,8]]]]
[[[6,0],3],2]
[[[[4,1],[2,7]],[9,[8,9]]],[[3,0],0]]
[[[[2,4],[8,7]],[9,[9,7]]],[[[2,5],6],9]]
[[7,6],[[4,[2,4]],[3,8]]]
[[7,2],[[8,8],7]]
[[[[6,0],4],[[4,7],4]],[[6,[2,7]],[[6,5],3]]]
[[[[8,8],[7,6]],4],5]
[[0,[[6,9],[7,9]]],[9,5]]
[9,[[[0,4],6],[[7,0],0]]]
[[[[4,4],0],[3,[3,9]]],[[7,5],[5,[7,2]]]]
[[[8,3],[[8,5],[4,4]]],[0,[0,3]]]
[[9,[3,[6,7]]],[[7,0],[[9,2],7]]]
[[[3,7],[[3,6],9]],7]
[[2,[2,[5,7]]],[[[6,4],5],[4,7]]]
[[[[9,0],2],[[4,4],6]],[[[3,2],[5,5]],[[5,9],7]]]
[[[[2,5],4],[8,5]],6]
[[[3,2],[[1,7],5]],[[8,1],[1,[1,2]]]]
[8,[[3,[5,4]],5]]
[[[2,[5,9]],[1,3]],[[[2,3],[8,3]],[[5,1],[8,9]]]]
[[[2,0],[[3,3],[4,7]]],[[[8,7],[7,4]],1]]
[[[[7,4],9],[3,[4,1]]],[[[8,4],5],7]]
[[[[0,2],9],3],[9,[5,3]]]
[3,4]
[[[1,[0,2]],[[9,9],[8,2]]],6]
[[[[2,9],[3,5]],9],[[9,3],[3,[6,7]]]]
[[0,[[4,6],4]],[2,[5,2]]]
[9,[[9,[6,8]],8]]
[3,[[[1,2],[0,9]],[[4,9],1]]]
[[[[8,7],[1,7]],[[2,6],[8,5]]],[3,[[8,0],[6,9]]]]
[[8,[[4,9],7]],[3,[9,4]]]
[[0,[[3,2],[2,2]]],0]
[[[2,7],[[5,7],4]],[[[6,0],[2,1]],[[4,1],[1,6]]]]
[[[[9,6],[0,3]],[[0,6],[0,4]]],[[[3,7],[6,7]],7]]
[[[[1,1],6],[[5,6],4]],[[5,[0,7]],1]]
[[[3,9],[[7,3],[1,5]]],[[[1,2],3],[0,[5,6]]]]
[[[[4,4],[0,5]],6],[[7,[2,0]],6]]
[[[[2,2],6],9],[[[9,1],2],[[8,6],8]]]
[[[[5,0],8],[[5,7],7]],[6,[5,3]]]
[[[[8,2],[8,4]],1],[[1,[7,3]],8]]
[[[[3,2],2],[[4,9],[5,4]]],[[[9,2],4],[5,[6,0]]]]
[[1,[[0,6],0]],[[[1,5],2],[[6,0],[3,7]]]]
[4,[7,[6,[3,3]]]]
[[[0,[2,5]],2],5]
[[[0,[5,7]],9],[[[2,3],[3,4]],[[0,4],9]]]
[[3,1],[[[4,1],9],[[0,5],[8,6]]]]
[[9,[2,0]],[[0,[1,7]],[9,[6,4]]]]
[[[[6,5],5],5],[5,8]]
[[[[2,8],[1,3]],[[5,4],2]],[[[0,8],[5,1]],[9,[5,6]]]]
[[[[6,9],7],[9,7]],2]
[[[[1,7],8],[8,7]],[[[3,5],4],8]]
[[[[1,8],[1,0]],0],[[7,1],5]]
[[[9,[6,8]],3],[[5,1],[4,[8,2]]]]
[[[0,[2,1]],1],[3,[9,[5,5]]]]
[[2,5],[2,5]]
[[[[1,1],[8,3]],[[1,9],[4,9]]],[[5,[4,8]],[[5,0],0]]]
[[[0,7],[[3,4],1]],[[[1,2],[2,9]],[[2,0],9]]]
[3,2]
[[[9,[8,2]],[7,3]],7]
[[[[6,9],9],[3,2]],0]
[[3,[[6,1],8]],6]
[[[[5,9],9],[[4,4],7]],[7,5]]
[1,[[2,8],0]]
[[2,[0,6]],[[[3,3],[0,4]],8]]
[[[[4,8],9],[0,[3,0]]],[[0,[3,1]],[8,[7,4]]]]
[[[6,[8,0]],[0,[8,9]]],[3,8]]
[[[[0,8],[9,4]],[1,[2,0]]],1]
[[7,6],[[[0,2],9],3]]
[[[[1,0],3],2],1]
[[[[1,2],8],5],7]
[0,[[3,0],7]]
[[7,[[0,9],[8,4]]],[[2,0],[[2,8],1]]]
[[[1,8],[[8,1],1]],[3,[8,9]]]
[4,[[3,7],[[5,2],9]]]
[[[[3,8],[2,9]],[3,9]],[[[3,7],[6,9]],[[1,7],2]]]
[9,[[[3,7],9],[[4,9],[8,6]]]]
[[7,[3,9]],[0,7]]
[[[1,6],0],[[7,[8,1]],[6,3]]]
[[[[3,9],3],[[2,6],[8,0]]],[[3,3],9]]
[[[1,2],[1,6]],[[1,[4,2]],0]]
[[[0,[3,0]],2],[[7,[9,4]],[6,8]]]
[6,[[[3,1],1],5]]
[[[3,4],[[5,9],[1,1]]],[[2,[0,1]],3]]
[[2,[[1,5],7]],[0,2]]
[[1,[[6,7],7]],4]
[6,[5,[[3,2],[6,8]]]]
[[[3,9],[[4,0],6]],[8,[3,[5,2]]]]
[[5,[[7,3],[2,2]]],[[7,7],7]]
[[[1,2],[[2,4],[6,1]]],[[0,[4,2]],[[5,7],[2,3]]]]
[[[8,7],8],[[7,[3,6]],[[1,0],4]]]

1054
2021/input/2021/day19.txt Normal file

File diff suppressed because it is too large Load Diff

1000
2021/input/2021/day2.txt Normal file

File diff suppressed because it is too large Load Diff

102
2021/input/2021/day20.txt Normal file
View File

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

View File

@@ -0,0 +1,2 @@
Player 1 starting position: 4
Player 2 starting position: 5

420
2021/input/2021/day22.txt Normal file
View File

@@ -0,0 +1,420 @@
on x=-46..2,y=-26..20,z=-39..5
on x=0..44,y=-44..0,z=-19..32
on x=-44..10,y=-20..28,z=4..48
on x=-12..39,y=-35..9,z=-12..36
on x=-20..31,y=-15..36,z=-44..2
on x=-18..36,y=-43..8,z=-12..41
on x=-24..27,y=-5..39,z=-30..24
on x=-40..4,y=-20..28,z=-33..14
on x=-16..30,y=-16..31,z=-12..32
on x=-3..48,y=-27..18,z=-5..39
off x=-37..-22,y=24..41,z=20..38
on x=-33..16,y=2..49,z=-46..4
off x=-9..2,y=29..41,z=-45..-32
on x=-7..44,y=-27..22,z=-40..6
off x=-43..-30,y=17..27,z=-43..-34
on x=-13..35,y=-19..25,z=-45..2
off x=31..45,y=36..49,z=12..28
on x=-16..33,y=-20..27,z=-34..16
off x=-43..-30,y=-1..17,z=2..13
on x=-7..47,y=-8..39,z=-2..44
on x=-51481..-16686,y=-55882..-41735,z=31858..57273
on x=62605..83371,y=-20326..7404,z=721..31101
on x=52622..66892,y=-53993..-42390,z=-32377..-15062
on x=32723..65065,y=-77593..-55363,z=-14922..15024
on x=-19522..-12277,y=-93093..-59799,z=23811..37917
on x=71595..92156,y=-44022..-19835,z=16005..34327
on x=-3586..34080,y=2703..21691,z=-92268..-61619
on x=-15386..715,y=73535..97744,z=-8553..16939
on x=-36770..-25752,y=71882..77753,z=-22483..5934
on x=-87151..-59512,y=-52304..-38677,z=-6844..14195
on x=-49843..-11520,y=-59097..-36023,z=-68112..-44642
on x=-54750..-35235,y=-65545..-48408,z=8090..44796
on x=-94375..-72818,y=9788..29493,z=-9581..832
on x=7678..15728,y=-72950..-37506,z=43639..74189
on x=-2150..1370,y=-47547..-22907,z=67903..86640
on x=30996..54239,y=58993..70521,z=10200..33219
on x=11010..19912,y=-82111..-52326,z=-59754..-28912
on x=21482..32440,y=-86476..-62698,z=14238..24595
on x=75846..79807,y=-34167..-20170,z=-5351..13100
on x=-57020..-37686,y=43544..67110,z=-37496..-30899
on x=14662..49584,y=-58025..-40735,z=-47292..-41465
on x=-63346..-55137,y=21250..38290,z=33568..51615
on x=-85269..-67041,y=-25194..571,z=-52696..-14325
on x=-54438..-31138,y=-25222..3408,z=-74478..-51576
on x=-55260..-36337,y=-36146..-21397,z=52332..57160
on x=-65984..-51756,y=-1513..8161,z=46328..64968
on x=28910..41579,y=-63016..-52977,z=-61128..-33613
on x=-46241..-27998,y=52847..77588,z=6053..16826
on x=-58382..-31024,y=-25378..11770,z=62336..77861
on x=14836..43351,y=43097..66395,z=26797..52340
on x=-2107..15942,y=-94637..-77185,z=-12264..-1486
on x=52176..62331,y=-18190..8633,z=40476..60619
on x=57517..70517,y=-13924..4531,z=46436..67802
on x=-21645..-1991,y=-50529..-11513,z=59680..91420
on x=-60101..-36307,y=11413..32936,z=-79198..-42467
on x=-27245..-11982,y=12680..44262,z=61571..82539
on x=62043..80570,y=-16742..15490,z=41267..54928
on x=-48117..-37581,y=34828..44610,z=-59598..-49709
on x=59522..87726,y=-16741..-1638,z=-37838..-7715
on x=-40860..-21613,y=-63238..-50545,z=38865..68651
on x=-53664..-45002,y=43993..64127,z=-50526..-32706
on x=-71250..-45260,y=-45511..-32954,z=23030..44098
on x=-50714..-25029,y=10683..33392,z=58357..85044
on x=40647..68356,y=40530..46549,z=21996..38584
on x=-63640..-36211,y=46146..49642,z=-56306..-41971
on x=21790..44008,y=-41519..-38626,z=46575..60879
on x=29993..40615,y=-74802..-65958,z=-10835..3294
on x=63509..72412,y=33988..60123,z=17699..27626
on x=-75402..-51635,y=-41551..-19817,z=-28290..-15067
on x=-24611..-7664,y=-76920..-49198,z=-69901..-36628
on x=-55000..-37217,y=-65084..-44457,z=33862..49998
on x=-83578..-56334,y=3079..36144,z=30213..52349
on x=-78623..-56475,y=45055..61546,z=-7798..15403
on x=31042..53339,y=-48138..-27455,z=-74296..-40132
on x=-16338..3820,y=-85143..-57755,z=-35857..-14502
on x=1..30237,y=63222..92071,z=14406..27979
on x=-50768..-29497,y=-62276..-42537,z=31270..66285
on x=14750..33888,y=25707..41545,z=60136..71374
on x=-73804..-51260,y=34623..68995,z=11793..27887
on x=-22099..3107,y=29817..55030,z=-86473..-71182
on x=44846..63690,y=-39204..-30200,z=-70048..-31226
on x=12735..25519,y=-50839..-27301,z=-85035..-52999
on x=-79843..-67300,y=6320..19153,z=-16078..5129
on x=-25488..3381,y=-81495..-59824,z=-51236..-39103
on x=29516..52668,y=-91122..-64377,z=-7299..8614
on x=-45309..-34530,y=59207..85364,z=-5722..17346
on x=-75869..-48145,y=-36278..-31560,z=-48241..-14556
on x=5416..33979,y=71734..85654,z=-6354..17686
on x=-38328..-6825,y=33508..60073,z=-73314..-49127
on x=-16455..5840,y=-90011..-56004,z=12046..34429
on x=19942..40435,y=-38063..-14227,z=-72406..-60179
on x=-71208..-36468,y=-51769..-39093,z=-39553..-32066
on x=-30611..-15238,y=-74996..-51621,z=41626..60792
on x=-26266..-6821,y=-76803..-54508,z=26326..49720
on x=5554..23770,y=60181..92306,z=-3903..22337
on x=35188..60913,y=405..13616,z=-68688..-53839
on x=-84198..-52574,y=-51383..-21298,z=959..28430
on x=-32433..-12722,y=-58750..-50875,z=33399..60295
on x=-42283..-20916,y=60934..71844,z=-48024..-17122
on x=45510..69038,y=-22876..-7766,z=41312..55989
on x=4077..26087,y=-87438..-67786,z=-6454..9574
on x=60630..91396,y=2047..28989,z=8771..31412
on x=-14685..3138,y=34908..62560,z=-66694..-42144
on x=44452..66566,y=-63825..-31278,z=-33877..-24172
on x=36589..53960,y=43341..55297,z=16299..30540
on x=-50464..-33544,y=745..34345,z=-72288..-52398
on x=21307..54983,y=-62869..-43283,z=41406..72552
on x=44587..71433,y=1841..17317,z=-57698..-42925
on x=58150..68363,y=28852..55677,z=17960..29455
on x=-7196..19282,y=-89129..-71321,z=13723..41169
on x=-68501..-46903,y=-26290..-15637,z=35391..42746
on x=3892..29864,y=64133..84173,z=-8782..5299
on x=-43516..-30450,y=26793..49391,z=53089..61207
on x=-53171..-30883,y=-48101..-43726,z=44797..67740
on x=68286..92818,y=-9936..15488,z=-6245..6271
on x=-69288..-35805,y=-18686..12501,z=-63926..-46763
on x=-13676..10358,y=29729..48962,z=-82290..-61499
on x=-91342..-58913,y=5804..18438,z=-10738..20089
on x=-2086..15635,y=62442..80850,z=11045..35648
on x=-75732..-51506,y=-5835..28683,z=-57038..-22560
on x=33708..52638,y=40215..48167,z=-64930..-42437
on x=42559..66539,y=-46203..-29630,z=38529..49019
on x=-49526..-43357,y=-61139..-43371,z=-59437..-20443
on x=8103..28088,y=66204..85143,z=-25951..-13527
on x=-72345..-62556,y=-63706..-38173,z=-17152..-1145
on x=54774..91997,y=-37670..-12831,z=-30161..-17865
on x=6148..25487,y=46052..71759,z=33247..65381
on x=-57328..-49224,y=26458..36097,z=45759..52150
on x=-39304..-28724,y=-39127..-23995,z=50978..73051
on x=-64985..-61846,y=31392..53299,z=25687..50050
on x=63677..86665,y=21170..35031,z=-17997..-9002
on x=-2035..9063,y=-91127..-59256,z=-41298..-26586
on x=-42966..-13481,y=-63752..-52787,z=39934..42013
on x=-4052..16276,y=4300..33419,z=-97023..-69495
on x=28754..55492,y=-63861..-30281,z=-57610..-42673
on x=-75541..-66845,y=-16327..9136,z=-47999..-37146
on x=-95243..-67165,y=8035..18049,z=-8895..24816
on x=-67563..-50842,y=-47960..-21085,z=-60573..-40893
on x=-41648..-12477,y=-20284..2911,z=-81827..-69369
on x=-28144..-17284,y=-34620..-6183,z=-89244..-54720
on x=65922..92404,y=-1466..6914,z=16157..39291
on x=14668..24690,y=-77921..-61312,z=-30488..-1115
on x=36923..56302,y=46079..74765,z=-15871..4979
on x=-46591..-23525,y=-76935..-44182,z=-43573..-20271
on x=29721..45936,y=6887..30073,z=59075..67521
on x=-890..30663,y=23754..47276,z=-82425..-63230
on x=4752..19784,y=-83727..-61899,z=33506..54760
on x=-94526..-71296,y=-14265..-4610,z=11418..33014
on x=58300..97221,y=-16175..4231,z=-21919..-2358
on x=-57482..-45486,y=-67406..-47228,z=20248..37478
on x=31402..48989,y=-62481..-50137,z=22060..47161
on x=40599..50616,y=10759..15911,z=46121..76734
on x=48057..61128,y=35427..62674,z=-21549..-9614
on x=-28135..-20962,y=59633..89312,z=-13540..5340
on x=47549..71482,y=17382..53520,z=17716..45082
on x=78070..81154,y=-13655..13343,z=-168..16596
on x=20673..45758,y=65526..76695,z=-13497..-36
on x=-4786..2818,y=-4837..5549,z=-93451..-76191
on x=14302..49076,y=61818..81437,z=-14176..9531
on x=-68602..-53393,y=16455..38152,z=25132..43913
on x=-24130..-13936,y=-7644..-4498,z=-85828..-59036
on x=-11717..16687,y=10353..30087,z=-80942..-58069
on x=12682..32617,y=58507..76138,z=20849..32759
on x=49088..65243,y=53393..74520,z=-14943..321
on x=-63756..-46629,y=-69037..-41666,z=-15234..-9712
on x=44240..46104,y=1468..21751,z=46542..79291
on x=-80700..-60977,y=24543..33596,z=-6372..11056
on x=-72072..-64358,y=-6985..13991,z=-65594..-35346
on x=-54425..-32669,y=-51345..-34855,z=29309..52921
on x=57189..87162,y=14470..19132,z=-51139..-22474
on x=76017..80222,y=-8175..18033,z=4083..27696
on x=-42368..-31460,y=-50798..-22007,z=-66532..-47444
on x=9223..15360,y=-54293..-43392,z=43665..64825
on x=-50450..-28738,y=-67485..-46021,z=25963..50292
on x=49773..57601,y=40208..61258,z=10697..36254
on x=-87157..-62119,y=-46554..-23602,z=-33740..-21462
on x=24144..48485,y=30406..55581,z=-63251..-41224
on x=-57059..-28465,y=36514..59020,z=-62118..-39872
on x=51418..73395,y=-33294..-7934,z=-55359..-46837
on x=35051..53350,y=48381..69938,z=30992..50675
on x=-49838..-13680,y=52337..71756,z=19703..47005
on x=-37895..-13199,y=17817..26885,z=-85792..-66246
on x=25443..49007,y=55523..83334,z=-38543..-8471
on x=-83264..-53691,y=-50838..-28415,z=-45433..-11937
on x=18129..44224,y=56025..71419,z=25496..28014
on x=64401..91096,y=-9626..9767,z=-19328..-16234
on x=40564..60820,y=21806..27545,z=-63583..-55689
on x=59287..82435,y=-49803..-36598,z=-19736..10678
on x=-61406..-31848,y=29090..48153,z=49953..68273
on x=-80129..-63495,y=32758..49898,z=15420..28891
on x=-71918..-59088,y=-8042..4070,z=-61979..-32744
on x=18507..32332,y=37492..69230,z=-61212..-48361
on x=18232..24748,y=-47573..-19392,z=-77084..-69812
on x=3538..29122,y=49351..68476,z=-77426..-58306
on x=14899..28875,y=33798..52962,z=-74740..-47031
on x=-33805..-9226,y=-4797..32978,z=-87103..-57644
on x=64283..84636,y=22189..47622,z=952..13372
on x=48891..68906,y=11825..36343,z=34507..53080
on x=8785..32809,y=-61933..-45683,z=42536..64070
on x=-23386..12584,y=60365..94330,z=-35407..-19640
on x=-69295..-63793,y=39194..55998,z=-29323..2775
on x=-69311..-40624,y=-11655..12445,z=52893..65442
on x=63480..66888,y=13195..36768,z=-40754..-23113
on x=-71702..-44882,y=-34923..3115,z=36891..68959
on x=1227..20599,y=3304..38907,z=-87371..-69194
on x=-38051..-5608,y=66679..76678,z=-22327..-17200
on x=-71086..-50108,y=-43265..-21453,z=45617..65108
on x=-75499..-48938,y=-22961..2638,z=-62154..-39253
on x=-58844..-35498,y=-73497..-60885,z=-3349..4528
on x=-80442..-65527,y=-51151..-25462,z=14193..28272
on x=-36446..-15525,y=2899..19438,z=54499..93589
on x=21122..41146,y=-34781..-12126,z=-81333..-47863
on x=40057..68736,y=12318..42116,z=-62457..-51443
on x=14076..29019,y=44823..82163,z=29271..59964
on x=-49251..-25009,y=47681..66203,z=-41367..-27670
on x=-62329..-39224,y=-34111..-4674,z=-65314..-57930
on x=-61408..-31233,y=22748..44986,z=41804..72595
on x=-21267..231,y=-85144..-60581,z=-14979..-6323
on x=-74958..-66383,y=-16735..2794,z=34735..59977
on x=-23282..-12409,y=69175..83534,z=313..21732
off x=59267..85411,y=514..23328,z=-4846..14301
on x=-17178..9607,y=-64979..-33229,z=57298..68101
on x=-7419..15896,y=-89840..-63418,z=-31002..-8653
off x=-73365..-57136,y=7908..35149,z=-59465..-32345
on x=63815..89172,y=6116..28592,z=11336..49089
on x=13237..36417,y=-44604..-18476,z=58867..71392
on x=-31835..-2018,y=48122..51530,z=-79384..-51387
on x=-93617..-71409,y=-6592..18534,z=-3366..22689
off x=29296..37825,y=29193..53548,z=-76978..-56558
on x=10940..21199,y=-70736..-49011,z=23206..53098
off x=46366..51784,y=-73666..-55961,z=-12714..5969
on x=-54335..-22852,y=-7983..25369,z=-79636..-67406
off x=-24260..2762,y=-64478..-41674,z=-64474..-45494
on x=22187..41667,y=15612..28847,z=58068..87450
on x=63150..83396,y=1346..33053,z=27298..45814
off x=59837..81917,y=-17191..8875,z=5474..24724
off x=19093..34648,y=-93372..-66153,z=-2175..27526
off x=30666..50683,y=52749..78100,z=-17491..10648
on x=26870..45665,y=56112..77327,z=-43808..-31865
off x=11864..18598,y=-1684..25669,z=-97875..-71735
on x=53157..75832,y=-29574..-16764,z=12318..43107
on x=43719..77079,y=-55045..-20872,z=15413..38119
off x=14623..37763,y=-89983..-54806,z=13234..35206
off x=-20732..-6457,y=4017..28816,z=71076..89286
on x=-20590..-14094,y=50358..65175,z=47899..66858
on x=62320..69077,y=23748..44841,z=-7970..22293
off x=21884..39495,y=67007..78871,z=-6077..14897
off x=62186..75230,y=-50181..-16289,z=-14388..7026
off x=-38405..-22937,y=-5429..28417,z=55944..88446
on x=662..26305,y=-87554..-58836,z=-17299..2266
on x=72718..77163,y=-1163..18561,z=-44259..-28618
off x=22260..41297,y=-44311..-19228,z=47468..84313
off x=-40602..-18738,y=-34574..-133,z=64944..85128
on x=-29694..-18496,y=54923..65374,z=38879..55584
off x=72863..81078,y=-14522..-3236,z=-33189..-20138
off x=-42230..-18771,y=69691..87669,z=14085..23774
off x=-9126..9929,y=68147..99240,z=-12694..-3519
off x=-26468..-7104,y=64299..76065,z=-36099..-15599
on x=67973..84722,y=-21303..7452,z=-18666..2678
on x=4102..21407,y=15532..19634,z=58771..86790
on x=37549..65086,y=-7487..-2758,z=55748..74491
on x=-14811..4584,y=-74652..-68275,z=-38615..-8763
off x=37106..50803,y=-53386..-44103,z=-58613..-40526
off x=-74450..-40998,y=43771..58392,z=1444..19278
on x=-50536..-28522,y=310..5308,z=58703..88882
on x=-20939..3950,y=-19820..-18182,z=-93492..-57274
off x=-73988..-70744,y=-53683..-27500,z=2877..9737
on x=-7526..22863,y=-8072..17539,z=73403..87835
off x=-48736..-25834,y=-83795..-55637,z=-14055..-1592
on x=46004..70445,y=11832..29476,z=43772..50920
off x=62244..84049,y=13880..25447,z=33699..42878
off x=-65300..-54528,y=47126..50687,z=7884..28591
on x=-55956..-47412,y=-68950..-31938,z=-33567..-21955
off x=27523..54204,y=53311..66537,z=-41809..-5196
on x=-95373..-75620,y=-27024..1838,z=3422..7457
off x=-41424..-13493,y=-93359..-55448,z=-26642..-13733
off x=45093..70424,y=51183..64547,z=-28549..-12261
off x=32082..52590,y=-68034..-42190,z=24265..40002
off x=-83441..-70495,y=2611..23905,z=-3669..20088
off x=-5850..22395,y=11248..36413,z=-78880..-56272
on x=78982..83822,y=-14121..143,z=-15875..5994
off x=39610..65471,y=39412..61214,z=17938..53604
on x=-73170..-48249,y=-48894..-33070,z=26483..60838
on x=-68144..-52978,y=-23980..-6621,z=-59936..-34090
on x=41115..53204,y=26168..46031,z=-63732..-34602
off x=-47255..-20253,y=5004..35879,z=49163..83111
off x=-63225..-49222,y=-62533..-36601,z=-935..13732
off x=-53817..-39048,y=-81526..-62330,z=-25691..-2500
off x=-76260..-62299,y=-29061..-19304,z=39220..48501
off x=-80241..-49003,y=-52126..-30868,z=-9247..6617
off x=6227..11948,y=-32268..-17660,z=-85825..-59021
on x=-36533..-26269,y=-79451..-60932,z=1614..7881
on x=589..25506,y=-12202..3560,z=-85890..-74851
on x=5360..19575,y=-62141..-51745,z=45034..63905
off x=-39349..-23146,y=23975..44390,z=48709..77537
on x=28342..46781,y=-29976..-8233,z=57734..69595
off x=-77303..-50182,y=8314..15684,z=-60271..-36934
on x=15565..23346,y=-24515..5163,z=-77856..-68954
on x=-38928..-18718,y=-26186..-6428,z=63840..76872
off x=9997..35709,y=-60625..-56365,z=-68727..-47677
on x=-6312..17890,y=-10921..5064,z=-91584..-67839
off x=12562..23601,y=-59006..-25156,z=-67383..-62614
off x=56511..85396,y=-9472..21355,z=-49007..-13930
on x=48654..68194,y=2363..22687,z=-54149..-39844
on x=-70180..-49056,y=-43968..-29640,z=21331..49497
on x=375..26280,y=53582..64641,z=45975..73486
off x=-50286..-39551,y=-69893..-49626,z=18452..52094
off x=-55882..-33331,y=344..18448,z=-80801..-51551
off x=57268..84471,y=-48138..-39865,z=-23525..6531
off x=-5837..2735,y=-73830..-52479,z=41854..58096
on x=-27554..-4489,y=53367..83205,z=31562..49332
off x=-20742..5467,y=-65244..-27510,z=53341..76842
off x=17914..42871,y=-53623..-33086,z=-77085..-47173
off x=36492..49968,y=35632..41326,z=-74714..-40178
off x=12446..45639,y=61743..75034,z=-40513..-27030
off x=16145..43992,y=-26882..-8326,z=-82954..-59935
on x=-23775..-7690,y=45368..50716,z=-64252..-49534
off x=-78791..-60343,y=11003..36392,z=-58207..-42229
on x=50675..70130,y=-21834..11787,z=34188..56587
on x=-34986..-11593,y=71125..86822,z=-11765..10487
off x=26121..54204,y=57376..70480,z=-44536..-14084
off x=47869..65894,y=33992..53419,z=-56863..-28538
off x=-24334..-8612,y=28640..61652,z=-78408..-43374
on x=27154..47449,y=43628..62103,z=-48166..-37361
on x=15338..32128,y=66233..90008,z=15361..36731
on x=-48061..-32730,y=7101..33292,z=51441..75575
off x=29688..55006,y=53948..61368,z=31296..38879
off x=59479..82841,y=27639..46701,z=-27632..-16641
on x=33822..55847,y=-60451..-48526,z=19976..54898
on x=-46685..-18938,y=-76878..-56088,z=23616..39907
off x=-74144..-59325,y=11439..22058,z=-39530..-17804
on x=60278..85196,y=-53386..-26378,z=-7422..6296
on x=11602..38478,y=47634..59849,z=-60457..-41436
on x=-67981..-51375,y=-43182..-28399,z=-30170..-5548
off x=-39484..-26626,y=46563..57448,z=-70491..-43484
on x=-11575..6240,y=-44470..-23882,z=-80590..-52319
off x=34368..38954,y=-77664..-45070,z=23154..37589
on x=23476..25973,y=-81946..-53549,z=19755..36372
on x=-70072..-56024,y=-42751..-25176,z=4968..16718
on x=44401..55480,y=-10001..5439,z=60788..71332
on x=-80447..-65355,y=24494..41918,z=-48047..-24893
on x=-25175..-5264,y=59599..83851,z=-43682..-19535
off x=-16008..-9052,y=68012..88912,z=-30931..-23360
on x=3262..31382,y=-59562..-48713,z=-65187..-50358
on x=-38630..-14647,y=-67513..-61283,z=21962..51871
off x=-37398..-18396,y=-36946..-24449,z=67584..85395
on x=-83796..-70334,y=-1617..3346,z=-42353..-5422
on x=71118..72869,y=-13101..1991,z=30833..48589
off x=19182..36667,y=-84948..-53662,z=-15128..-6251
on x=-32891..-12512,y=46790..64941,z=-37805..-31758
off x=-87853..-57958,y=-9105..10250,z=-27666..-5705
on x=-55159..-15768,y=-23929..-9785,z=49353..69701
off x=58381..63179,y=37782..69395,z=-5063..21127
on x=29347..54026,y=-84030..-63792,z=20530..32897
on x=1052..19601,y=-14750..-4884,z=70402..91679
off x=-43193..-30770,y=63615..86118,z=-19288..-5103
on x=59886..71212,y=-50156..-18781,z=-25959..4904
on x=-47400..-33917,y=45116..46183,z=-52576..-42214
off x=-2916..8013,y=72215..79301,z=12660..39986
on x=-47600..-29671,y=-66262..-47736,z=-250..18288
off x=-76766..-67021,y=23902..56855,z=-24188..-10948
on x=40863..55547,y=-41154..-4752,z=-60017..-51932
on x=19691..33799,y=-91077..-61569,z=-17018..7955
on x=-2214..28174,y=-39590..-31800,z=59281..85857
on x=40206..73039,y=45740..74950,z=-32389..-7431
on x=-60834..-50842,y=-68433..-41429,z=22771..27775
off x=31115..64073,y=-66256..-40204,z=-44062..-24526
on x=-10832..6359,y=-85458..-70278,z=-31345..-13315
off x=26581..36176,y=66579..67779,z=-35420..-10427
on x=66912..86434,y=-10806..2524,z=30276..35350
off x=60734..71718,y=-26519..-13963,z=32357..52134
on x=64029..94207,y=-21424..4543,z=-19917..-5796
off x=-22578..9205,y=26649..48657,z=-69531..-60261
off x=36844..66645,y=34250..50170,z=31072..49267
on x=-9961..-5497,y=7380..37072,z=-89348..-57961
on x=18102..50680,y=-76562..-65621,z=4542..24597
on x=-63529..-54599,y=-53394..-47786,z=21888..25725
off x=63654..94850,y=965..22382,z=-31743..-2000
on x=74998..76278,y=-37896..-10505,z=-9186..22612
off x=-30811..2911,y=-89485..-75160,z=-36405..-3483
off x=51745..78582,y=25188..33294,z=26010..58376
off x=15024..35252,y=-43146..-33304,z=-73102..-57750
on x=2426..9775,y=54690..83625,z=-41065..-25812
off x=-24228..-570,y=-52801..-30297,z=49276..66451
off x=-74129..-54073,y=-56542..-35923,z=-32562..-468
off x=-2928..15901,y=15260..33101,z=67801..88745
off x=-53099..-47112,y=-19233..13470,z=52727..69682
off x=35876..62082,y=-29873..3214,z=64189..67241
off x=-3064..17661,y=65230..82048,z=-410..28371
on x=14630..34564,y=-4463..16268,z=-96585..-71246
on x=-60251..-39251,y=-6775..3343,z=37689..65303
off x=50322..66243,y=19278..44771,z=41067..64697
off x=36020..61904,y=-27183..-9736,z=46137..73036
on x=61922..69366,y=-51710..-34152,z=21534..42960
on x=-48310..-33496,y=36461..61490,z=42916..57166
off x=-14180..12358,y=67333..80981,z=-40807..-23314
off x=-806..32676,y=-88882..-71765,z=10596..21784
on x=4361..34509,y=73189..90685,z=2499..14138
off x=-87784..-75559,y=-23875..-9307,z=-7239..13845
on x=-68172..-53511,y=35832..49496,z=33932..46400
on x=-55713..-37433,y=-5286..18352,z=55977..63293
on x=-17643..17283,y=-35303..-16046,z=68866..82087
off x=25050..58536,y=-75214..-40996,z=-53573..-16621
off x=14898..28167,y=-85300..-58742,z=-21836..-5732
off x=-87322..-55171,y=-35094..-10807,z=9939..27679
on x=-56866..-31891,y=-52393..-39065,z=51551..54781
on x=1566..33534,y=54640..59730,z=51744..60395
on x=15272..24542,y=64983..91848,z=3089..8627
on x=65424..83864,y=29222..36126,z=-12872..15695
off x=-2899..17557,y=-87982..-63662,z=1631..29537
off x=-26849..-9477,y=53092..71495,z=-64534..-33903
on x=-8981..22557,y=22399..30246,z=-76499..-58300
off x=-72834..-48859,y=-18764..9128,z=35760..62856
off x=-24250..-15338,y=31706..46920,z=55005..82901
off x=37368..45012,y=-40763..-35016,z=-60587..-38956
on x=9616..34618,y=-61089..-34252,z=50095..76726
off x=-14337..4309,y=-63805..-49426,z=-75783..-53417
on x=-31091..2449,y=55254..83398,z=-55349..-29593
on x=66679..79368,y=-43938..-18102,z=1633..26650
on x=-32143..-25109,y=62219..88867,z=1027..29516

View File

@@ -0,0 +1,5 @@
#############
#...........#
###D#A#C#D###
#C#A#B#B#
#########

1000
2021/input/2021/day3.txt Normal file

File diff suppressed because it is too large Load Diff

601
2021/input/2021/day4.txt Normal file
View File

@@ -0,0 +1,601 @@
72,99,88,8,59,61,96,92,2,70,1,32,18,10,95,33,20,31,66,43,26,24,91,44,11,15,48,90,27,29,14,68,3,50,69,74,54,4,16,55,64,12,73,80,58,83,6,87,30,41,25,39,93,60,9,81,63,75,46,19,78,51,21,28,94,7,17,42,53,13,97,98,34,76,89,23,86,52,79,85,67,84,47,22,37,65,71,49,82,40,77,36,62,0,56,45,57,38,35,5
91 60 70 64 83
35 41 79 55 31
7 58 25 3 47
2 23 69 59 21
11 22 8 87 90
77 95 19 21 76
93 92 62 35 3
4 29 7 41 45
80 50 83 61 64
39 32 91 56 48
47 11 39 58 97
63 51 40 74 71
12 17 68 81 44
64 85 20 84 80
0 77 5 18 50
44 82 32 1 57
98 88 33 83 85
25 61 63 99 37
0 74 7 20 39
71 72 22 80 28
78 97 0 48 41
56 51 62 58 90
8 44 98 46 1
38 40 91 20 55
88 2 32 86 14
84 50 16 45 40
9 39 60 34 46
57 20 12 3 36
58 17 72 48 83
73 85 49 67 66
4 30 73 83 57
74 23 49 19 42
72 65 8 99 13
25 6 82 53 68
20 86 46 48 50
52 29 61 16 75
36 19 2 82 9
34 90 89 43 14
69 66 20 21 11
31 53 46 18 23
37 76 34 79 99
43 5 42 91 71
47 54 19 82 81
95 78 65 60 24
32 94 92 27 66
68 61 80 90 53
33 17 52 0 23
30 71 5 85 11
27 39 41 6 9
58 98 7 74 89
31 5 55 67 51
54 86 40 25 92
91 62 9 94 7
39 0 44 52 28
12 17 26 46 32
94 80 83 88 77
65 71 31 86 0
98 55 18 92 72
6 12 30 25 34
67 53 14 20 47
81 74 14 47 1
83 82 4 89 8
43 93 63 21 44
92 61 25 77 97
12 72 35 78 52
26 39 13 37 46
87 6 58 47 19
24 35 45 95 52
5 27 42 96 0
23 64 8 29 83
53 58 18 96 93
57 90 35 88 68
91 89 7 80 47
59 86 81 24 31
43 8 66 17 94
0 97 91 67 90
93 20 36 4 42
43 64 28 94 34
31 2 7 54 71
18 35 76 86 16
55 63 26 47 0
2 23 54 25 90
36 13 85 31 15
59 51 18 88 62
44 69 9 81 58
26 97 98 42 27
3 53 91 89 93
87 57 12 18 5
29 99 86 47 64
6 28 92 79 67
4 35 45 79 16
33 95 99 80 9
60 78 57 51 50
27 5 48 21 46
19 70 32 58 18
94 82 61 66 31
14 56 76 37 28
42 81 50 10 40
2 98 47 29 62
69 90 46 44 18
87 3 8 50 17
15 90 54 45 21
6 28 43 51 32
97 84 69 30 38
98 44 88 55 83
34 19 27 43 92
81 62 52 32 39
50 29 83 25 82
60 55 49 41 97
75 94 22 69 66
59 39 96 87 65
33 18 4 71 15
22 27 92 8 29
19 5 32 85 45
91 79 35 9 3
41 53 51 68 85
72 71 94 82 81
60 38 13 16 7
49 80 10 0 54
20 39 59 64 99
37 21 90 40 73
85 75 16 34 99
84 15 25 18 27
77 32 0 76 36
13 50 68 91 12
24 26 0 14 12
89 4 15 95 73
54 2 55 84 42
30 50 81 60 87
37 94 71 91 53
52 1 81 44 34
27 60 36 19 69
98 11 49 67 56
77 72 40 48 66
84 9 37 32 51
58 15 7 36 55
94 49 69 89 87
79 70 30 77 19
68 31 56 41 53
47 85 74 54 46
64 87 23 66 0
29 98 72 82 80
70 45 46 30 37
53 54 33 86 76
6 75 71 68 2
12 31 43 80 41
37 15 13 2 3
86 61 9 17 59
55 68 72 8 1
96 26 44 73 47
67 39 95 84 10
5 88 13 81 99
68 15 98 6 17
47 85 74 32 97
58 8 16 56 42
82 31 42 84 17
25 28 2 6 12
78 57 16 97 18
87 64 54 30 65
3 77 29 49 81
24 1 43 89 46
29 78 57 14 85
9 58 53 83 35
96 42 62 68 74
67 2 39 37 51
72 26 46 52 3
91 27 41 32 53
25 36 7 63 22
56 38 93 65 9
95 19 77 64 44
21 71 13 99 39
47 17 80 85 64
5 18 48 27 81
82 23 45 57 12
83 55 26 31 32
57 13 86 69 65
42 76 35 18 39
17 91 95 43 6
55 97 22 54 14
56 0 5 60 92
87 12 46 42 35
44 6 95 30 67
51 21 68 37 59
77 65 50 69 63
33 56 24 57 28
82 87 42 99 39
38 55 74 28 6
77 66 9 80 10
47 90 32 3 98
92 52 5 94 51
16 1 87 57 66
41 70 58 31 5
71 88 17 42 76
81 40 25 89 63
92 4 61 77 64
70 28 56 51 66
44 60 25 0 45
91 78 81 95 88
75 43 57 67 32
58 27 20 82 22
16 98 82 79 90
96 4 80 69 19
9 28 33 40 94
2 99 14 73 43
76 68 74 42 30
29 42 94 45 2
25 81 46 54 26
75 99 51 58 23
76 72 71 64 63
66 70 92 44 13
2 71 39 49 95
19 84 1 7 96
9 6 60 93 78
38 91 55 36 41
64 3 10 20 74
79 80 15 69 89
36 76 83 7 72
87 34 48 0 93
5 84 77 20 75
46 27 11 55 3
82 34 4 14 74
40 39 7 6 95
11 51 78 80 29
97 81 38 9 71
22 62 19 72 68
54 70 90 43 98
12 27 57 96 62
32 76 0 86 42
88 68 81 91 50
10 94 18 71 2
90 41 29 53 58
59 62 14 85 66
25 82 68 44 93
73 32 76 67 18
94 71 83 34 37
6 72 69 33 90
87 60 66 85 16
59 80 86 47 89
32 98 17 29 5
48 27 18 57 81
10 22 98 86 82
8 66 71 14 93
87 79 40 78 49
84 63 17 54 94
35 39 47 1 96
58 60 52 6 86
41 20 66 59 2
92 79 88 40 71
96 9 25 36 17
91 32 43 38 8
74 3 64 66 68
69 37 22 76 33
17 67 29 32 27
63 49 46 21 60
35 73 9 52 50
0 91 8 26 9
3 98 79 97 7
37 61 1 60 47
86 17 11 70 15
66 53 2 90 54
68 42 0 78 16
83 88 21 87 12
50 2 29 14 63
72 90 81 71 91
54 79 94 10 4
28 63 97 31 4
50 52 43 24 16
36 77 0 9 75
83 94 69 68 27
93 82 42 56 34
24 52 66 51 82
50 30 34 93 67
56 70 53 13 78
4 84 88 57 81
80 74 5 95 98
56 64 53 52 72
51 48 50 60 49
8 46 84 95 43
91 21 7 88 33
94 57 80 25 54
70 57 62 20 18
86 45 41 76 32
87 35 52 5 2
16 77 25 39 22
38 10 6 29 98
89 54 57 80 65
0 38 94 15 6
85 76 16 83 59
92 5 53 14 95
47 35 73 98 34
64 24 90 71 69
55 35 20 98 41
94 70 10 73 16
65 84 60 7 72
83 2 22 78 99
31 81 74 56 98
13 97 95 49 67
9 47 42 99 60
38 22 65 58 21
82 45 2 28 68
90 88 28 85 51
23 93 13 55 50
63 22 3 30 39
5 71 82 95 81
57 76 12 92 56
78 12 28 6 73
59 24 43 29 31
30 34 75 52 48
62 57 23 74 50
91 92 5 95 38
95 88 13 22 10
16 4 19 37 91
50 52 60 46 77
45 55 49 41 26
21 7 67 48 18
51 79 44 16 71
6 13 12 41 97
50 25 19 63 4
98 0 23 77 31
27 57 52 99 3
86 95 7 54 84
50 33 48 16 9
82 32 38 6 34
43 80 27 37 11
89 70 41 22 45
24 3 47 68 35
85 76 8 29 4
2 10 5 28 73
92 89 50 25 56
99 57 79 19 37
0 46 72 5 20
62 28 24 53 44
84 25 63 34 9
75 1 65 59 10
95 29 97 77 45
87 90 1 17 67
57 73 35 10 30
65 14 46 60 6
70 66 56 69 92
3 27 21 64 88
20 58 53 29 66
27 6 67 89 33
88 60 79 69 97
90 3 47 68 25
48 59 42 98 39
65 90 45 97 87
75 98 7 58 42
51 4 95 88 47
94 6 11 53 63
49 80 2 48 68
3 77 42 97 82
70 58 81 18 47
78 96 62 39 56
22 87 71 31 94
34 48 57 38 88
70 36 65 33 45
71 0 59 44 1
42 37 7 5 9
11 12 91 43 27
60 21 57 61 99
76 75 56 49 2
36 57 39 64 77
95 19 35 43 97
82 34 50 44 55
45 74 15 66 29
0 75 1 78 79
13 37 48 27 14
90 50 26 92 67
89 62 87 69 33
29 47 4 2 12
74 42 24 86 61
92 66 3 65 75
7 1 77 63 64
39 91 87 28 5
30 35 41 73 96
0 81 41 15 66
62 19 86 31 40
23 94 98 82 24
61 99 1 5 60
80 64 91 33 47
16 61 56 77 57
28 59 71 45 92
53 20 35 66 73
99 3 86 31 74
94 69 84 96 90
71 56 23 76 42
90 44 58 27 15
46 18 86 63 24
69 49 82 38 43
33 51 60 66 39
75 78 38 25 76
67 3 83 90 10
40 89 47 23 88
34 21 46 16 33
9 79 50 0 26
81 75 80 23 41
62 4 76 1 63
56 39 57 28 61
20 6 79 92 84
88 3 90 16 12
87 78 3 34 63
98 21 24 9 99
62 29 57 65 27
47 52 67 76 71
11 17 93 23 82
53 68 70 38 56
62 54 25 43 35
9 3 13 15 75
59 27 26 33 83
93 40 11 64 76
27 83 26 48 77
51 20 65 18 35
80 30 60 44 89
84 82 62 91 63
12 97 11 19 34
31 28 92 48 34
9 93 61 71 60
52 18 97 81 62
80 64 57 22 30
11 88 74 29 56
57 34 90 46 73
31 0 70 66 82
45 12 40 19 87
91 24 59 83 14
80 21 13 86 89
9 8 64 48 30
6 62 28 99 41
79 45 83 7 55
15 14 54 88 12
90 74 97 96 50
50 73 58 26 12
96 98 56 34 7
51 92 14 89 16
41 70 80 55 13
37 47 2 64 99
98 9 70 17 18
39 15 88 16 47
80 41 8 51 21
54 42 31 10 59
37 92 33 62 68
60 72 51 63 29
83 39 41 24 14
34 5 94 90 56
75 80 67 17 20
47 11 58 93 42
97 7 27 42 67
12 30 91 45 52
62 50 87 92 71
99 84 33 6 46
29 55 86 47 60
25 49 55 98 22
66 9 61 59 90
45 74 77 88 5
6 76 0 36 93
23 70 33 95 2
53 92 27 86 55
66 52 26 58 38
2 78 69 62 65
30 5 1 25 99
76 43 4 13 8
18 72 51 48 39
62 19 28 44 82
54 22 38 55 83
86 93 42 9 32
11 89 27 34 68
85 99 35 88 76
10 25 33 83 70
54 81 77 73 66
4 74 96 41 86
49 3 68 65 39
71 0 70 14 31
28 23 17 43 75
13 40 38 87 97
63 93 92 89 27
58 76 24 53 54
55 58 11 38 16
98 86 13 12 8
22 10 77 61 90
37 76 2 62 45
44 30 52 70 82
89 55 12 90 63
40 88 91 22 74
8 0 25 6 79
53 23 87 77 20
11 38 78 43 94
21 14 37 8 16
29 73 67 91 56
5 90 12 92 59
64 1 42 72 94
98 86 18 69 49
79 71 82 1 77
96 39 24 60 81
49 16 12 63 14
0 32 78 37 8
92 33 15 99 65
54 11 40 55 33
58 47 4 83 94
46 96 16 28 5
0 62 95 71 39
93 59 7 75 64

500
2021/input/2021/day5.txt Normal file
View File

@@ -0,0 +1,500 @@
217,490 -> 217,764
44,270 -> 373,599
440,139 -> 440,303
161,663 -> 345,663
848,963 -> 908,963
299,207 -> 162,70
77,346 -> 77,686
693,743 -> 693,127
96,459 -> 96,779
864,39 -> 233,670
58,79 -> 203,79
158,596 -> 463,291
633,293 -> 136,293
656,474 -> 656,72
148,754 -> 947,754
535,780 -> 535,460
821,701 -> 821,796
592,200 -> 592,610
620,786 -> 722,786
632,731 -> 536,731
825,640 -> 195,10
956,547 -> 956,387
25,32 -> 981,988
870,613 -> 870,16
369,780 -> 369,362
348,924 -> 243,924
28,114 -> 540,114
702,690 -> 702,335
836,442 -> 184,442
602,11 -> 602,651
76,988 -> 608,988
15,922 -> 951,922
363,18 -> 296,18
130,580 -> 516,580
799,335 -> 858,335
571,842 -> 571,800
684,654 -> 684,971
815,674 -> 66,674
575,612 -> 575,919
652,126 -> 822,296
391,493 -> 730,493
810,479 -> 810,807
397,420 -> 780,37
187,740 -> 869,740
175,626 -> 175,169
773,901 -> 773,44
45,130 -> 45,17
226,253 -> 252,279
481,928 -> 481,521
121,506 -> 121,50
306,386 -> 653,733
115,635 -> 208,542
619,67 -> 212,67
82,79 -> 972,969
15,20 -> 15,933
606,136 -> 500,136
791,250 -> 791,316
128,931 -> 781,278
11,365 -> 11,226
705,326 -> 57,326
778,632 -> 173,27
121,624 -> 121,737
30,815 -> 909,815
18,114 -> 869,965
554,741 -> 554,771
284,826 -> 945,826
386,654 -> 295,654
235,848 -> 418,848
536,59 -> 497,59
156,922 -> 29,922
57,718 -> 174,718
964,774 -> 964,426
729,950 -> 729,254
896,117 -> 152,861
603,919 -> 603,776
176,472 -> 573,472
25,970 -> 939,56
478,482 -> 38,482
155,936 -> 956,135
351,621 -> 133,403
513,323 -> 103,323
679,167 -> 679,983
910,456 -> 241,456
16,266 -> 16,829
338,791 -> 973,156
564,73 -> 564,676
196,800 -> 339,800
15,776 -> 973,776
719,134 -> 719,775
730,692 -> 272,692
247,770 -> 244,770
853,720 -> 940,720
685,379 -> 873,379
944,647 -> 944,206
67,974 -> 967,74
828,194 -> 355,194
596,522 -> 596,169
677,970 -> 638,970
587,427 -> 587,354
804,488 -> 469,153
355,653 -> 787,221
798,873 -> 133,873
565,798 -> 534,829
239,273 -> 20,273
942,138 -> 398,138
499,743 -> 958,284
913,466 -> 514,466
504,705 -> 504,983
455,863 -> 451,863
638,255 -> 425,255
338,724 -> 338,457
147,880 -> 928,99
11,955 -> 806,160
566,961 -> 231,961
870,560 -> 611,560
714,925 -> 859,925
484,946 -> 905,946
112,394 -> 266,394
191,728 -> 191,635
983,806 -> 217,40
575,286 -> 730,286
366,323 -> 366,211
383,990 -> 834,990
834,976 -> 26,168
819,492 -> 819,648
257,522 -> 257,199
756,176 -> 244,176
165,199 -> 569,199
896,943 -> 18,65
986,642 -> 354,10
864,381 -> 349,381
177,982 -> 977,182
458,254 -> 458,920
550,322 -> 550,297
956,748 -> 270,62
412,305 -> 292,305
201,571 -> 375,571
608,139 -> 608,330
646,718 -> 432,504
449,325 -> 449,115
315,971 -> 955,331
248,143 -> 477,143
956,858 -> 111,13
776,608 -> 739,608
44,842 -> 548,842
590,487 -> 590,792
978,127 -> 978,748
620,948 -> 852,948
67,403 -> 67,122
340,256 -> 346,256
803,58 -> 474,387
876,448 -> 876,55
78,288 -> 565,288
235,80 -> 480,80
949,880 -> 949,666
529,734 -> 529,332
780,973 -> 780,824
900,279 -> 698,279
290,438 -> 34,694
766,569 -> 766,443
729,690 -> 729,137
72,938 -> 72,893
960,563 -> 960,322
669,293 -> 578,293
396,388 -> 984,388
675,694 -> 211,230
152,743 -> 63,743
203,660 -> 391,660
582,806 -> 906,806
698,837 -> 698,483
869,320 -> 595,594
283,817 -> 283,861
919,926 -> 919,235
16,64 -> 930,978
980,25 -> 16,989
181,890 -> 952,119
877,731 -> 877,364
130,55 -> 130,111
30,298 -> 590,858
134,933 -> 134,41
711,853 -> 711,196
123,206 -> 841,924
130,585 -> 130,394
161,952 -> 531,952
455,830 -> 455,919
612,817 -> 30,817
461,474 -> 106,119
511,100 -> 581,30
263,550 -> 263,814
976,973 -> 14,11
749,876 -> 380,876
731,226 -> 731,659
630,682 -> 570,622
914,780 -> 311,780
975,274 -> 87,274
328,957 -> 724,957
357,950 -> 357,659
466,580 -> 466,726
854,425 -> 854,559
39,106 -> 39,82
675,711 -> 956,711
204,117 -> 672,585
867,101 -> 49,919
849,88 -> 784,88
394,249 -> 394,730
865,188 -> 125,928
316,918 -> 722,918
781,336 -> 781,551
821,826 -> 258,826
597,273 -> 597,653
726,266 -> 90,902
701,701 -> 941,701
105,401 -> 949,401
890,486 -> 890,205
651,409 -> 651,408
450,88 -> 51,88
29,478 -> 29,667
676,293 -> 676,77
380,773 -> 962,773
253,836 -> 429,836
833,706 -> 123,706
689,167 -> 665,143
375,540 -> 375,346
867,222 -> 746,343
99,832 -> 370,561
133,349 -> 133,815
950,981 -> 12,43
195,466 -> 644,466
84,876 -> 84,720
128,237 -> 34,331
872,947 -> 960,947
641,220 -> 641,472
489,950 -> 489,441
508,513 -> 721,300
394,137 -> 332,137
456,672 -> 625,503
65,463 -> 540,463
207,745 -> 529,423
948,888 -> 891,831
39,642 -> 165,642
20,228 -> 20,386
706,50 -> 57,699
66,736 -> 66,840
944,450 -> 915,479
697,988 -> 697,862
987,969 -> 57,39
64,813 -> 64,468
814,85 -> 469,85
667,749 -> 154,236
755,337 -> 755,50
536,185 -> 536,217
732,48 -> 529,48
33,578 -> 430,578
511,658 -> 669,658
294,352 -> 353,352
109,937 -> 820,226
465,346 -> 465,114
878,965 -> 34,121
259,933 -> 576,933
240,750 -> 240,296
567,633 -> 899,965
29,609 -> 169,469
962,532 -> 962,921
443,875 -> 395,875
831,584 -> 510,263
859,35 -> 84,810
829,285 -> 829,463
486,661 -> 883,661
371,672 -> 959,84
722,532 -> 722,241
49,216 -> 468,216
308,343 -> 308,277
183,626 -> 264,545
748,611 -> 356,611
67,85 -> 925,943
726,972 -> 726,272
841,222 -> 841,867
597,250 -> 813,250
20,631 -> 555,631
803,846 -> 589,632
276,654 -> 222,708
400,952 -> 672,952
939,173 -> 534,173
638,316 -> 638,935
578,120 -> 578,101
54,457 -> 723,457
904,713 -> 904,721
902,180 -> 99,983
590,426 -> 174,10
740,975 -> 309,975
84,242 -> 803,961
28,667 -> 362,333
73,703 -> 73,354
902,26 -> 902,365
602,455 -> 578,431
339,686 -> 339,846
764,444 -> 311,444
780,535 -> 862,453
333,127 -> 911,127
451,296 -> 451,832
849,681 -> 849,580
309,672 -> 309,913
339,411 -> 147,411
907,478 -> 974,545
444,753 -> 855,342
642,285 -> 683,244
307,633 -> 751,633
292,128 -> 767,603
969,92 -> 647,414
80,120 -> 942,982
886,810 -> 740,810
205,846 -> 168,846
878,230 -> 72,230
186,822 -> 628,822
472,66 -> 472,609
251,753 -> 129,753
575,959 -> 102,959
582,194 -> 858,194
43,986 -> 43,589
355,402 -> 751,402
982,292 -> 86,292
329,966 -> 329,379
475,291 -> 475,924
625,70 -> 625,350
358,467 -> 981,467
319,700 -> 736,283
657,247 -> 654,247
450,803 -> 450,497
812,15 -> 812,425
649,160 -> 377,160
684,491 -> 690,491
925,429 -> 772,429
138,91 -> 883,91
602,121 -> 774,293
700,531 -> 451,531
250,216 -> 800,766
550,784 -> 289,784
53,759 -> 228,759
678,310 -> 645,343
147,70 -> 171,46
130,653 -> 130,103
292,640 -> 731,640
797,762 -> 618,762
154,75 -> 964,885
222,523 -> 557,523
989,103 -> 989,964
335,61 -> 422,61
782,954 -> 160,332
82,929 -> 82,528
732,540 -> 635,637
950,362 -> 798,362
415,566 -> 916,566
588,446 -> 743,291
495,46 -> 495,435
913,561 -> 303,561
788,902 -> 788,698
81,783 -> 715,149
867,990 -> 867,558
145,919 -> 145,725
850,861 -> 727,861
535,129 -> 535,496
922,772 -> 922,917
882,559 -> 672,349
496,80 -> 496,948
915,244 -> 516,643
633,461 -> 748,461
899,341 -> 677,341
66,981 -> 878,169
68,24 -> 984,940
12,880 -> 23,869
779,514 -> 779,752
878,641 -> 949,641
264,919 -> 229,919
213,281 -> 213,196
538,149 -> 538,278
184,478 -> 364,298
301,136 -> 923,758
559,266 -> 559,986
384,37 -> 384,558
815,529 -> 800,514
33,80 -> 624,80
561,261 -> 215,607
169,944 -> 169,921
673,42 -> 164,42
820,977 -> 424,581
816,29 -> 802,29
374,924 -> 121,671
962,555 -> 426,19
982,199 -> 860,77
334,62 -> 359,62
960,785 -> 260,85
681,280 -> 860,280
184,925 -> 184,30
332,398 -> 858,924
405,270 -> 218,270
261,846 -> 29,614
591,941 -> 591,716
313,502 -> 313,637
930,259 -> 779,259
432,15 -> 566,149
51,182 -> 223,182
603,536 -> 603,281
139,703 -> 825,17
965,22 -> 55,932
389,608 -> 771,608
209,617 -> 923,617
769,672 -> 769,236
163,717 -> 638,717
801,604 -> 136,604
974,881 -> 110,17
187,226 -> 929,968
430,949 -> 473,949
899,279 -> 899,224
964,806 -> 964,876
635,190 -> 349,190
142,656 -> 142,216
740,814 -> 35,109
588,956 -> 534,956
107,968 -> 707,968
787,639 -> 787,50
964,491 -> 964,148
30,70 -> 30,323
30,905 -> 806,129
592,419 -> 91,419
73,87 -> 973,987
540,683 -> 540,139
422,107 -> 422,90
935,74 -> 935,590
728,566 -> 188,26
839,313 -> 839,620
723,898 -> 723,719
679,814 -> 679,617
203,633 -> 417,633
36,812 -> 546,302
112,316 -> 598,802
798,773 -> 989,964
914,69 -> 520,69
213,556 -> 213,19
795,516 -> 795,220
348,803 -> 664,803
910,861 -> 238,189
633,691 -> 594,691
96,166 -> 96,60
278,848 -> 854,272
64,370 -> 64,815
386,196 -> 386,222
888,330 -> 888,834
166,482 -> 37,482
594,283 -> 594,865
515,267 -> 515,448
707,279 -> 239,747
302,745 -> 302,268
210,830 -> 885,155
592,180 -> 592,324
245,154 -> 245,613
607,954 -> 545,954
854,951 -> 19,116
77,878 -> 963,878
759,585 -> 759,892
750,918 -> 750,130
62,716 -> 329,983
785,880 -> 785,590
318,794 -> 318,599
403,547 -> 719,863
742,803 -> 742,937
680,579 -> 680,425
268,404 -> 826,962
425,959 -> 710,959
406,823 -> 976,253
359,361 -> 165,361
276,861 -> 657,480
74,260 -> 743,929
194,129 -> 194,651
879,835 -> 65,21
16,977 -> 980,13
538,525 -> 624,439
985,789 -> 985,510
699,850 -> 560,711
301,48 -> 477,224
28,938 -> 905,61
844,530 -> 793,530
286,325 -> 936,975
368,122 -> 677,431
924,153 -> 924,774
783,498 -> 783,148
250,392 -> 578,392
465,345 -> 573,345
860,763 -> 860,40
373,226 -> 599,226
169,562 -> 169,292
408,123 -> 569,123
510,396 -> 733,396
199,20 -> 199,770
892,631 -> 237,631
671,863 -> 705,863
141,530 -> 141,630
467,159 -> 367,159
729,501 -> 255,975
578,871 -> 578,225
821,363 -> 821,820

1
2021/input/2021/day6.txt Normal file
View File

@@ -0,0 +1 @@
1,1,1,3,3,2,1,1,1,1,1,4,4,1,4,1,4,1,1,4,1,1,1,3,3,2,3,1,2,1,1,1,1,1,1,1,3,4,1,1,4,3,1,2,3,1,1,1,5,2,1,1,1,1,2,1,2,5,2,2,1,1,1,3,1,1,1,4,1,1,1,1,1,3,3,2,1,1,3,1,4,1,2,1,5,1,4,2,1,1,5,1,1,1,1,4,3,1,3,2,1,4,1,1,2,1,4,4,5,1,3,1,1,1,1,2,1,4,4,1,1,1,3,1,5,1,1,1,1,1,3,2,5,1,5,4,1,4,1,3,5,1,2,5,4,3,3,2,4,1,5,1,1,2,4,1,1,1,1,2,4,1,2,5,1,4,1,4,2,5,4,1,1,2,2,4,1,5,1,4,3,3,2,3,1,2,3,1,4,1,1,1,3,5,1,1,1,3,5,1,1,4,1,4,4,1,3,1,1,1,2,3,3,2,5,1,2,1,1,2,2,1,3,4,1,3,5,1,3,4,3,5,1,1,5,1,3,3,2,1,5,1,1,3,1,1,3,1,2,1,3,2,5,1,3,1,1,3,5,1,1,1,1,2,1,2,4,4,4,2,2,3,1,5,1,2,1,3,3,3,4,1,1,5,1,3,2,4,1,5,5,1,4,4,1,4,4,1,1,2

1
2021/input/2021/day7.txt Normal file
View File

@@ -0,0 +1 @@
1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,160,1267,277,1068,422,1235,790,1391,45,252,513,1029,414,216,409,1373,1419,1176,757,64,748,835,20,436,147,347,1264,1532,240,272,430,7,85,51,12,107,1277,779,867,260,802,361,89,754,206,80,25,559,220,657,178,186,2,31,825,290,144,379,0,1682,1166,1241,180,102,464,444,122,718,25,100,1050,1358,604,546,1157,130,59,127,1351,238,97,75,821,265,23,786,116,115,93,730,1340,777,1114,263,352,115,5,69,1041,101,1222,203,1273,217,28,976,425,480,7,124,45,192,860,312,1107,1040,137,306,523,692,590,562,789,383,145,86,297,791,240,697,22,230,834,963,837,1164,1758,487,414,86,1026,1034,478,613,1,769,85,980,935,1455,16,204,170,380,324,14,699,220,50,451,738,52,437,963,718,178,508,711,1739,936,1515,246,908,126,602,295,591,22,484,752,1,1442,167,132,52,613,1172,353,36,56,468,123,393,765,1456,218,269,6,20,649,727,454,86,640,1113,836,124,405,571,882,107,75,730,346,94,35,626,1174,299,392,1449,502,854,500,128,852,248,645,159,774,155,884,1336,285,426,0,269,466,1483,93,13,17,255,295,530,694,1178,968,612,224,160,32,1154,194,494,24,845,43,274,344,301,486,43,351,581,929,168,1629,163,206,98,1242,1242,1706,1777,721,293,1621,132,199,12,66,247,1244,333,445,154,795,70,424,11,826,835,250,288,408,516,822,411,69,636,521,152,67,401,531,186,933,515,780,490,201,369,111,266,952,400,677,372,548,1325,1111,17,543,1293,20,507,74,116,656,644,872,35,80,1273,279,475,1585,1446,651,1338,285,284,23,1130,237,843,121,53,81,573,5,956,276,553,1084,544,731,35,16,53,34,405,1337,665,303,10,108,1132,233,3,834,415,161,409,1055,202,707,296,341,57,521,548,15,137,359,57,388,282,267,293,1450,28,424,819,941,1388,474,687,87,271,1462,522,33,26,841,345,104,150,573,481,297,1075,489,420,424,340,504,685,105,898,870,206,129,516,492,42,216,1829,1317,10,60,54,255,103,457,257,101,93,981,412,67,519,574,169,799,381,1509,60,409,51,151,464,1676,916,18,30,772,1566,1283,359,1260,10,405,750,160,181,541,358,213,300,1073,328,399,214,119,478,889,65,56,1077,1427,52,359,90,42,1248,336,51,1396,509,237,785,440,806,339,99,354,640,272,665,772,135,91,11,175,128,482,1244,1243,629,137,140,1003,626,433,391,731,1180,671,169,710,1561,385,1281,272,236,318,207,1323,16,233,9,720,295,34,183,362,987,1016,366,760,1244,878,600,275,1209,41,792,951,85,636,125,217,342,184,581,1300,66,165,804,285,756,96,278,598,163,655,138,869,537,141,1364,897,406,617,65,444,244,494,172,119,358,1183,310,226,98,550,634,948,985,247,1499,729,165,371,939,299,761,477,1480,840,3,319,675,492,564,3,3,80,182,69,460,341,789,742,46,1309,360,48,296,363,946,214,252,54,147,435,85,276,1072,23,71,755,572,268,1362,619,639,365,623,1560,322,535,997,1021,317,663,82,314,857,16,194,363,24,240,1596,1123,242,816,116,645,64,38,589,428,147,632,457,555,908,921,202,182,403,551,358,483,1195,1213,28,1156,725,320,16,74,931,103,145,146,1206,433,1052,158,531,699,675,379,393,475,384,1041,141,1248,521,136,326,199,725,200,465,796,724,672,569,70,663,15,150,131,1261,17,1211,66,175,608,17,81,551,627,1469,1032,342,2,972,184,798,960,22,55,462,1,151,91,119,76,1062,96,1424,567,366,831,633,205,691,50,1314,732,558,167,1624,5,147,47,110,250,935,177,445,79,306,653,47,75,626,173,104,354,573,523,46,46,757,541,431,1129,787,502,1328,1093,82,872,1876,1386,136,504,273,194,297,0,163,1025,996,354,1457,1127,52,45,1364,1128,457,1576,282,573,1648,16,28,582,768,92,92,817,1515,297,349,97,1523,634,923,76,1174,552,347,750,326,221,149,0,188,791,251,113,1,71,92,393,103,618,335,97,236,418,256,764,435,411,941,74,423,443,27,427,178,262,181,362,156,572,324,684,796,249,288,413,132,29,444,766,1135,1235,208,231,620,1481,228,174,133,918,1825,618,663,22,124,119,52,159,1318,1724,338,243,206,127,436,163,297,617,141,59,65,20,164,11,126,363,150,726,217,1282,1708,118,1055,60,603,852,170,1097,58,213,495,566,673,1607,994,539,1655

200
2021/input/2021/day8.txt Normal file
View File

@@ -0,0 +1,200 @@
bgafcde gfcd agc ebdgac adfceb bafeg efgca cgdfae cg ecadf | fabgced gc agc cdfg
gbdacfe gcabfd cdb dcfba bfacg cgad fadeb feabcg cd gcbfed | bdagcef dcb cdag gbfca
dgcbafe dbfca fbaed be cedb gefad dcfeab facdgb eba gbface | eb gadfcbe cfbad gfbeca
ebc cb aedbf agcef badecg gaebfc bcgf adbcfge ceabf daecgf | cb bce efdab ecbaf
fedbc cebad gfcbd fec gcdfab ecbfga dacgbfe gfed fe gefbdc | bfecag cef egdf fgde
bafedc baefg dbfga daegcb gae egbcfa eg cefab fgce decbafg | abdgf cgfe cedgba befga
dcba fagbed cgbfed dgfbeac da dag acbgde fcaeg becgd acgde | agd bacd dga gbecad
ec aebgcfd fecd bagfec efagd edfgab cgdfea dgcab ecdga eac | ce ec ce gbacefd
aegdbfc fe dacbf aefbgd aecgb cdfe ebadcf ecbfa cbfdga aef | dfce fe fcde afebdgc
bgaf gcbad cagdfb gb dfbeca degfcb bfadc cfgeadb bdg agcde | fdegacb acbefgd bdg gafb
gdecba dcae ec dbfeag bgead dgbce gec cgefab dcbgefa cdbfg | afdbgce agbfde abcgefd ec
gacbefd fgbedc egafdc adf fcbae afedb ad bfeadg adbg dfgeb | ad degcfa ad dfbge
fadebc baef eadfcg ebgdc eda cfgabd afbdc ea edcab cdgbefa | aefb ead ea ebaf
badgecf caefd aebfdc fecbdg fadcg fed de ebad abgecf bceaf | ed gcfebd aebd gfdca
bcdae aefcbg fgdea bf cdabegf adcebf fcbd fbead afb begadc | gbcafe faegbc fba eabdc
bfcdeg ecd eabgc adeg ed dbaec bcfad ecabfg dbgcfea dbacge | de bdfcaeg ecgfbd bcdea
deacf bf eagfdb gfecadb facbeg bfa cbdage abfce fbcg gecab | aebcf ecfagb abegfd bgeac
eag dgbecf gdfae caed dfebgca ea ebcgfa dfbag gecfda dgcfe | ae ea deac fcdega
edbga egdabc cgfdbe gabfe efcdgab gbdefa fb abdf fbg gecfa | cgaebd cbgdea acgfe begdca
cgfedb egbdc agcfd cdagb eabgdf ab abce adb agcebfd dabegc | ba bda abd deagfb
fc agfbce fdebg dgafeb ebfdc cbf cfedgba fdcg gcefdb eacdb | gbfaec fgcbed gbceafd bedagf
bdcgefa acdfbe ed gbcea cfgbad ecbda edfcag afcbd ead bdef | dfbe de dea dea
gfbeca gcefdb fegacd cgbda fbde ed bgedc begcf agdcefb ced | gbacd ced dec bcegfd
dgbacf gfabec agd egdaf badcegf ad ecgaf defgb cade dfegca | cdae dga bgcaef ad
dcf cfadb bcagd afebd fbgdec egfcbda fcea gfeabd fc ebdfac | gabdc ebfad aefc eacbdf
cfgdba fcdab cgfbade adeb afdebc egcfdb de aedfc cfage edf | ed eadb dgebcf cefdabg
bcae befga dgebfc fbagce cbefg agb fcedgab ba bdgacf dgfae | beca dcaegbf gab geafb
dgafbec fedba cbega aebfdc eabfdg bdgfce edc fdac cd adceb | abedf dfeabg dc gdbefc
adegfbc gbedcf cfabd gacedb abcfe fdbacg dgabc df dfga bfd | fdag dbf dafg fd
dfbcag ebfcad ed agecdb bfacd egbfa badfe afbcegd aed cdef | afebd ecdf cfed eadfbgc
fca dbcaf ebdcf fadbg cdbefa adec ac dacbgfe fbcdge cgefba | ac edca edac ca
agdfce cedbfag agc dcbaeg gc bcdga bgdfa cfaebd ebdac cbge | ceadb becg ebadc gc
aefbc aecdg efgcad cdebag bcg agfdbc bceag bdge bg fecdgab | bgecda bcdaeg gb caebf
cfgebd acedf ag gbad gcfbad acg bgecfa bdfcg gbadecf cdfga | dgba dgcbf gac bgfdc
cdgbafe cdgbe gd agde bcaged dfebc geacb cdg bgeacf gbdcfa | efgcba edag gecfdba cgd
bcg bcaf cegdaf dfacg dgacb fgcebda bgdcaf efbcgd bc gadbe | gcb bcg caebdfg cfab
eg cdgfae aecfd fgbaedc gbdfc facdeb cfegd ceag efg efdgab | fge acefbgd egf efg
fcdg gefda cf edabc cedgfa cfa acefd cfebadg gdbafe bgecfa | fc fca cfabged fca
ed bcadegf egdfb fgcdb edbafg facbeg abegf deba fadgec dge | eadb ged eadb adfegb
bgedc cf cefadg ecbgdf gbfae cbdf fcg ecbgad abfgced becfg | bdcf dbceg fgcbde cdbeg
cg gcaf defcag cdefg gdafe dgfabe gec dabegfc bcegad ebdcf | feadg degcf gcaf dcgefa
fdeac gdcebf daecbg bgfec fdeagbc gca gecfa aefcbg fbag ag | ga decfagb ag agfb
bc fbdc bagecdf gfdcab acdgb dcaeg dbgfa cgbaef ebgfda gbc | bdfc cb cfbd fbcd
efagc bafegd abecg eab eb fgbeca gbedcfa bfec fcgade cgbad | abfgdce degacf fcaebg cdabfeg
egbfcd afde ecgab fac fa edabcf cbdagfe afbec cfabgd fdebc | deaf feda cgbdfa fa
gbafd defca ebcf eb cefbad dcebag dcgfae edfab deb bgedcfa | be deb gdbafce be
afdgceb cf gbdeaf acdbfe abcef acf deafb fedgac cdbf cgeba | fac cfdb bdfcae fdcb
cfdba ca afbgd eabc cda afbcdeg cfedb ecfgbd efcgad bcfeda | bfgad abec abce caeb
cfebad debfacg acgfeb cab fedcb afcdb cdae febcdg ac dgbaf | bac ca faecbgd cgbfae
eg dfcegb dge abedcgf facdg bafdgc degacf dafeg agec adebf | egd fegda fedbcag eagdf
age gcbad feacb cgbdfae ge gfbe agebc fcadeg cbafde cgebaf | fagecdb bfeg baecg fceabd
bfcdge fgcbead ebdgac ba dagbfe gab dabc bcegd gface cebga | cbda gbedc egcbafd gab
dbcegfa fadceg fcage bcage gb bdagfc abdec gbfe bgafce bcg | ebfdagc ebfg ebgf egfb
gcdefa bagf dgebf bdefc bgcafde dbefga edabg gfe gf dcgeba | fg efg agfb gebfd
fabdc gdeabf dag gbace adcgb gd eagfcb gaedbc egdfabc egdc | adgbc bcadf gd cedfabg
deagcf ce dfcaeb gfadceb bgade cde daegc cgdafb gadcf efcg | dbaecf fdecbga ce ecd
dfcbag abceg db dgcefa dabec bcegdaf cdb bdef defac cfbdea | gdafec dcb febd bdef
ead fgceabd edgcaf da fgda fgcea ecdgb cgaed fdbace cbagef | ad eafcdb bfecagd ad
ab caefg agbcef efacb gecdfba ecfagd fbdec bdecga cba fgab | eafgc abfg cdagbfe dcageb
afbcge ebafcgd dacegb cfbea afbg agc egcfa ag cgdfe bdceaf | adfbceg fagb gfba aecgbf
acg cdegbf ecfadg cgdab fcbadg cdbgfae ca agedb cbgdf facb | cdeabfg ca afbc dagfec
dca dbfae bagdcf aceg ac afdegc cegfd fcedgb cbdaegf cedfa | dac acge cedgf cfdbgae
gdcafe ega cgbfde cgba afdbe bacegd ga begdc dcebagf edgab | abgc ga bacg bdacge
begfda gdafce fg gdbf gbaced agf decagbf aebdg gabfe cebfa | fag acdbeg agcdfe dgbefca
gfcdbea fecab cbadge afgce gc fgdace fdcg cga eagdf eagbfd | efgacbd gc dgfc dacbeg
gdbefc feadg dbagef afd abde gebfd cefga bdgafc da efdacbg | cbegfda adf bade cdgfbe
aefbdgc eabcfg cgefa degbf cedfg cd cadg cde fgecad fecadb | dbfegca egcdabf gcda dc
baed bcgda abdegc decag ega dgbfaec gacbfe ae cgfde dbacgf | aebd age ea bgdecfa
abecg faegcd egfcd efcga cdaf baedgf efa fcbaedg fcgedb fa | afe af aef fa
abgfce cbedgaf fbedc eacdfb dcf fd faegcd fecba dfba gdceb | faecdg gdceb dfc gcbde
fgce fgadb egdabc edg defbg eg bfced fdbace bdfgeac gbcfde | gdcbfea deg afbedc dgcaeb
eg dgcfe efdgab bfdec aecg acbegfd bdcafg adcfg efg daefgc | fge aecg gfe ecagfdb
acdfe bedcfg abgec cfeabd aedbfcg fecdag fg fcg afecg gdaf | cdaefg fdag cgf gadcfbe
aedc gbdac cbagfe bfdcg gdbfea acb cbgaed ac eadgb gecadfb | gbfdc gbdaec fbgeadc decabg
gbc afgdb cfbdga badgef gadbce egabcdf geacf bcdf cb gabfc | fgaec fcagdeb gbcfa bc
cfgabd cfdbe eafgdc badcfeg dgfab cbag eafbdg gc dfgbc cdg | fagecd cgd afdbge cg
eadcbf fcag gc gbc gadcefb gebad febdgc egcbaf ecbag bacef | dgbfec egadcbf gcfa bcegfda
acbeg acgedb eg dgbfce cdagb cgdbaf gaed bafce cfebadg ecg | dbgac eabcf eabfdgc eagd
bgefda eacg abdcfe eabcd abegcd ebg cbedg cbfdg dgfecab eg | ecag eg ge afebcd
dgecbf bg dfcba abge gadebc edagc bcg ecdfga fbgecad bgcad | cgb gbea ebgcdf gbae
dcabg gdfbca debc aed ed fabeg afdecg gbeda caegbd agbfcde | fcbdgea cedb dea efcdagb
edbcafg cgaed gc gbdc acfebd cge gceabd abecd afegd bgafce | gc facegbd edbcaf cg
gadbce gbdaf acebgf bd abcgfd edfga cdfb gbd cfgab dgafbce | gfdab fdegbac eabcfdg bgcdae
eacgf fb cegbdf dgbfca cfb dfba agfcb cgabd ebcdgfa gedacb | acbdg dbaf ceafg bf
gebac egdacf fdceg daef af gfa dagfbc fcgbead afgce cebfgd | afg bcage gcdeabf cgfea
cdabfg fgbec gcdafe ceafgb egc ec beac febdg bdegcfa fabcg | cafegdb beca ecgbfa bace
gda feabdg ebgaf bgdfc bgfcae bfeagdc edab ad adgbf fceagd | gad ad afgbde dfaebg
bfc bgfced edbfag fcea cf afgbdce cgbda abgef fcgba aebcfg | bcf efac eacf fc
bdeag bgdcf ec ebgdfac gcbde gaec dec cafdeb afdebg cebdag | gcbfd agedb acfdbe ecd
befad gd edgbf bcgafd cebgfd abgcef gfd ecgd cgdfaeb ecfgb | cegd cdeg efadbgc egcdbaf
gfdbae bc cegbfd gadcf cdaefgb gfbed fbcgd beagcd gbc becf | gedcfba edcagb fbcgdae cfbe
ecf cbdaf bdfcaeg fagdec efba bcdfe bfecda gcedb ef cbadgf | ef fbedc dbceg edgfcab
cabde ae ecfdba cbdfe faed dabcg cfbgaed gbfcea begdcf abe | adfe aeb cabgd ae
gefcabd ecabd gebafc ag ecfgbd gacdbf dfcbg fdga cagbd acg | gebcadf gefbac dgaf dagf
bgde efcgd cebgfa dbacgf cgfeb gdc fdaec dfbceg gd fegcadb | efbcadg cgd gbdcfa facebg
gefcbd bgfdcea fg dcbag fbgcd fgeb defcag fcg becfad dfcbe | cefbda cfg fegbdc fg
bcfed bcfdge aedbfg fad decbfa facge cdba efdca ad dbfagce | eabfgd fadce begfdca gecdbaf
edfgbca dbega fdb gfecab fd ebcfda cfda feabd becfa edgbfc | df ebgad cabegfd adcf
daegbc fbacg edfg befdac efbcd edafbgc cdg bcgfd fdegcb gd | dg becdf dbeafcg gadefcb
egdacf gde ed dfebcag acgdfb cfadg agebdf cgeab gecda dfce | fedagc gabfecd eadgfbc cfgebda
dfcea afbde fdgac gefbac eabcdf ace bced ec ebagfd adgbcfe | ce fcdga baecfg cea
adebg gdfcae gb acegd abg begc bdaef bfgcda dgaefbc abgdec | bg cbafgd ecbg gba
bfacde egfadcb cb fcdea eacbf cedb dcgeaf bgadfc abc ebgfa | adfebc dceb bdcafe efdac
faegbd dgfce dcgafe fgadecb bcgd bcfge bfaec gb cdbfeg fgb | aecfb fbg fcgade dafgbec
fgacbe fc ebcadg agfdb fdbca cagbdfe cdfe abcde fcb bfacde | cabed cfde bfdac dgbaf
defabc gfcbe fea bdacfg adgecf fabce ae aebd bfecdga cdafb | fea ea bgfaced bead
dfgae dcafe dce dgebfca abfcd ecab bfcdea gcfebd gafcbd ec | bcdagf cde gbedcfa bfdace
cea gaedfb acdf ac ebacgd gefdabc befda cfbae egcfb efcabd | gcaebfd cbaef dfac ca
gebac befadgc bedcgf cgb gc eagbdc cebaf cadg bgfaed aegdb | cbg cbg cbgadef acdg
gfcdeb bfdegca beac befda bcf dcfga fbcda cb adecfb gbefda | fbc dbafc cbf cfb
cbdfeag becagf acgeb be cgbda gfcdbe efba acfeg ecb eadgcf | aebf eb bagcfe eb
febg aecbdg fedacb ecg ge fbgaedc dfgce afcgd fcbed efcdgb | aedcbg baegcfd ecg bedcf
bcfedg gdbcae febd fcbag fgbcd bd ecdgfa dbc fdcagbe gdcfe | efgbadc fcbedg abfecgd cgbedf
feagc cb dcgeabf fadbgc cgfdae fbdea feagcb bcafe cbeg bac | bgce bc cgadbf cba
efagbd dageb dcgbeaf gc acg gdecab gecd fdbca gbcfea acbgd | eagbd egfabcd gfbace gca
ae cgae dea eacgfd fadgc gfebd afdcbe dfeag acbfgd dacbgef | dgbafc cbdfgae ae ead
egb gcfe abcfdeg begfcd abcdfg dabec eg bdfcg edgcb bedagf | bdecg beg gbdcef dbeac
fcgae dfcebag aefdb geacbf cda dagbcf cd adcfe fedacg gdce | bcdafg adefb fdeba gecbfa
afegd gadfb fcgadeb gbcade gdabef cefgad dfbe bdg fagbc bd | dabegc bfgca bd dgb
dfceba faecd bd afbedgc ebad fcadb bafgc dcb efgdcb gfaedc | faedc bead egcdbaf bd
cgb bdcfeg cg gdbeca cgef gdbcfea febdg fdcgb dafgeb bacfd | cgfe cgb gc gfec
cadgfb cefdbag cg begacf dfgbea bgc adgbf bgcad fdgc eabcd | cg fgceab ebdacgf ecbdgaf
bgdefc decfg cfedga cefgb bfdcea edgfacb bgcd fegba ceb cb | cfgbe dcaefg cbgfe dbcg
gefbda acde gcbaf cd cfd bdcgfae daefg gdcbfe cgefad agdcf | gcebafd efgcda cfd aecd
gedfc cead egbfda fgcdabe de fcgea gfdbc deg cagdef gebacf | deg bfgead gdfbc gde
fbgae bfecg dbcaef gdcaeb cbfdge gbc decgbfa edbfc fdgc gc | gc gbcdef fdcg gfcbe
fc caf cadbe dgabfc gebdfa fecg fagbe cebaf acbegdf cgabfe | egcf ceagbf gcfe ebgafc
abfcd cgbfa bcgafd gadefc abfde cdf dc agfbced cbegfa gcbd | cd cfd fgeacd cdf
bdgae gfbce cbagfd gedbcaf ebcgd gbcefa dc fcde cegdfb dbc | dcegb fgdcbea deabcfg bdc
ebcagf df bgcdefa fdceba cgdf dbacgf eadbg afd abgcf gabfd | ceagdbf dagcbf fd dcfbaeg
dga cadbgef efbcgd bgdca eacd cedbga gdbec gdeabf fbacg da | dag adg edac edgcb
febcg gbadce aedbcf acbed cbgae cag gadb degbcfa ga fcgdae | bgad abdgfec acbed acg
gdcaf dcbfag gdefa abcdg bcfg cf fedgacb dbaegc fcedba afc | cf afc gcfb eafdgbc
gdcaef gcabfd bcefgda cde gcdfb gbecfd ec dfaeb cefbd egbc | egbfdc ce gbdcfa afbcgd
fdea fga fa adcgbef abfcge gbeda fagdb abedgc cgbdf bdefag | fa gaecfb beadgc cbfgd
ba gcbafd decgba bfga fbadc bda dfbeacg ecfgbd cedfa fdbgc | gfab gbdfc adb ba
bd ecdgab aedfg bde fbcae decfba cgafbe fdeab dbfc fdgceba | db dbe cdfb bdgfaec
bd gcefbd ebcd dafbgc ebfgd decgaf edcfg fbd fbaeg gafcdbe | cbeagdf cebd cedb cedb
edagf cdaefbg ead efgdb bgafed cfdag bfea dabgce dfbceg ae | gcafd feab dgfca feba
gecfda bgcdf ba abd edgabf bcdeaf gedfa fdbga baeg abegcdf | ab bad bda fgebcda
egadb bec dbefga cbafg cageb ce ebdgca dceg gdebfca cfbead | ec ebc egdc ecb
cbgfe fadcbg agde cbdge egdacb degcabf bed faebdc ed dcabg | eadg facdbe bcdeg debfac
fabe fb bgf edcgaf bgacd bcfegd fcdegab adgef afbdg gbfade | bfg dbcgfae edacbgf bf
bcdfe becgd cbafegd decag geb dgfb bfcade dgcefb bg gfbaec | bdgce gb dcbge gdfb
egcadf bfg fgbdac faedg ebaf gcedb begdf fb adfebg cafdgeb | faedbcg bafcgde bf becgd
edafgb ecbgd gcdfaeb ef gbfadc cgfade gef fdegc fgcda efca | agfecdb dcabgef ef dgcaf
cbdgea fegcad bagdc abdfgc age gebac afbcdge egbfc adeb ea | ae ega ecagbd gbacd
ecdfb edafbc fe afdcb efc degcb aedf acbgfd ecgfab fecabdg | fe dbegcaf fe cedgfba
edbfgc caeb ca cbdafg bcdge bgcdae edfga eacgd gca cgabfed | facebdg ca aedbgc ac
gfeba aegc cbfega ea bea dfgbe edfacgb fadgbc gbafc aefcdb | gbecfda bcdfag gcea afcegdb
fgcea dc egfdba cdafe gfdecb fbaedc ebdfa dacb bdafgec dec | ced bcfdaeg cefda fagcbed
dbefa defacg agd dcbfg bdfagce ga efgbdc abgc fdgab bacfdg | cbga dga gedcfab fdabcg
eacbf eac dfagbce cfga fbgea ca bfced agebdc fbedga fcbega | dabfgce gfca ebfacg gbaecf
cfagb cgfdea gdc agfcbe fdeacbg bcfdg dg badg fdgacb bcdef | cgd gfacb gd gdba
cfga gbadef decabfg cbged baefcd ca cda dbagf fdbcag dbgca | afgebdc bdgeaf gafc cfag
cgfbd cdafgb gbcead dbg afdb bgecf adfcg ecbgdfa bd gdacfe | fgacd cgdfa bdaf dbg
abf fb febd dbafg febcga gbead egdacb fedgba fbagdce gdcaf | bf fb dbceafg fba
fd dgfabe ecafdg deabcg cbefa fed dbgea bdefa bgdf dbfgeca | fde bdfg fdgb gfeabcd
fgeadb abfed dgfbcea bafgd agcfd gfb bdfaec bg dgbe cegbaf | egdb fegadbc dcgaf bg
fdabc acfbgde dg fcage cdfgab dfebag dga gdafc cdgb eafbcd | gfcad aegdcbf dag afbdc
dbfe efdag fgdcae cgbfaed bgfead acebg fb bgf egabf abfcdg | ebdf gfb ebfd fgabed
bafegd egcfadb fbc bc fcebgd becaf afbed agecf beacfd bdca | cb dbca cfb afgbcde
gbefdc bfead gfcdab gbedca fc cabegdf bedfc fdc cefg cgbde | fdbceg cgfe fc bdcaefg
fg dbfea fedagbc cageb aecfdg dfgb dbfaec gafbed begaf gaf | gfecad dgcfea dafeb gfbd
dabfg eb egacdfb bfcdga faedc gdeb fbagec aeb bgefad dfeba | bafdcg gfbda gebd be
adb dgeabc bfdg gaecfd afdgc cbdgfa bd dcgeafb dafbc bafce | bd fcagbde defagcb dbfg
fge bagcf dfaebg fgebc eg cdeg fabcedg bedcf dfcegb acfbde | egcd ecgd cebafd cgdaefb
bafdgc gecabf caegf ae beaf gfacb decgf cfedbag aec cdabeg | dcfge ae egcdafb eca
fcgba ebgaf agefd agcdfb beac gdbcfe beg bcdfgae gacfbe eb | cfebgd abecdgf ceab abcfdge
abcgfd bac feabd adcgeb fcgb bc debgcfa fbdac gceafd fagdc | fbcg gcfad afbed cfbda
afdbegc dea abegd agecbd afbgdc dgbfe cabgd afcbed ceag ae | daecbfg cdbag acge ea
ebdcg cbfg cdgebf bge adbec eabgdf baecfdg fgadce gedfc bg | dcbae fbcg beg gfbc
cfbga cefabg ebfca abeg ae bcedfga gbacfd eac bdefc dcafge | abge fedbc bacgf eac
eb aedcg dbfcge cegdbaf gfbe bed dagcbf dacebf dcfgb dbceg | gbef dbe fegb eb
cgfe ced dgeba ce cegad abedcf cdaefg cfagbd cadfg gbcedaf | ecgad gcabefd dfbcgae ce
dbagc afdc dgfaeb bcfage gbedfac cafbdg cdgeb ac cab gdafb | cab dafbcg dacf acdgfeb
dgbae bfa eafgb bafegd fgaec bcfadg fb dbfe egbadc gbecadf | cdegbfa dagfcbe fdeb fab
be aecgdf gbdacef bagfc bdef beagf beg dbefag gedfa cbgade | be eb afegb beg
cfdagb ac gcfdae cbad bfgda bcfedga begcf afc ebafdg cfbga | deagcf abdc ca cagfb
eg efdbga adbcfg ebfcga aefgd bdfga adcbgef defac gbed gae | edbg gedb bfdeag dbcgaf
bacegf gbfca cfa ceab gafeb ca gcfdb gadfec dbafge gbdfaec | caf fbgedac fca afc
fbagde cbeg afecg gdaecbf fedcga gab efacbg gb acbfg cfdba | gba ecbg agb abgcf
abfg dafcgb gcafd bdcgaef ab cba ebdcf bgdaec cfaegd fcbda | acb ecadbg cgdabe fgab
agcbd cegdba feagb fd daf gbfad bacdfg cgdfabe dcefab fgcd | df dagbc fgcd fd
gdfeabc bcd debaf cb gedfab bcefd edfgc bdceaf aecb cdgbfa | ebac beac cbea abce
cbgdef eg beg dbgfc bfgcead gbefd efcg edgbca eabfd acbfdg | gbe gbe cefg gbe
fedg begcad gdb bafdge gd egbcaf gdbaf bfacd eacgdbf eafgb | cbefag baegf gefcdab bedgac
gbce dcafgb agfdceb efdac acg agcfe aefgb befagd cegfab gc | fbedgac abdefg cga cag
gabc bceadf agfcd agd ag fcdgbea gabdef gedfc dbcfa agbfdc | gacb gad bgceadf cbgafde
afedc fabced gfcbed feb cegdbaf dbfa ebfac dacfeg fb gbace | feb afdb ebf acfde
cbed edgcf ecabdfg ceg cfbgd abgfdc gebfdc ec efbagc gedfa | ec decb ecdb gec
egd gfbeac gedcb de dabgfe dcfbg cbefdag eadc dcegba acegb | ed adgfceb gde abcged
efadcgb fbdce fagedc agebfd gbafe abedf da bgad ead ceagbf | efagb ecdbf ade aebcgfd
cgeb bfaed cbedga cbaed bc bca afgcbd dgface bgfecda decga | fgadcb bca dabfe cab
dgaec deagcf egf cdeabg abgdf gdfceab dfcbeg gfead efac ef | agebcd efdbcag aefc bgefcad
fbeac gebcaf efa fgce bgfdea dgbcfae gcbdea adcbf ef egacb | gebfacd bfadcge ef eagbc
acdbgfe adfg edfcbg efacb egacf gca dgaceb egdcf ga gefcda | fdga cfgae cga ga
dfebcg gdaebf dagcf gbaecd dcgebfa bf cfbe bgf bgdce fdbgc | cgbefd bcfe gbf ecbf
dcafeg ca acf fcdeb abcfdge facdgb bfagd dfaegb bagc dfbac | dfabgce dfaegc gbafde bacg
cgefb cbe cfab afdbeg cb faebg gcfde cefbag ebadgc afdbgec | egbdcfa cbe cafb fecagbd

100
2021/input/2021/day9.txt Normal file
View File

@@ -0,0 +1,100 @@
9976786789439313678999989767678999865435679398654323678999987654313468954569865334568916987643236789
9754395678998754599898978954567999976556789498775413478998798743203457893479973212479425698432145799
9843234589899866698786767943456789987687899987653104567897659957312368931298984596599934679549234689
8654785789789979897645459892967895698798999999873215698958349876433456892987899989989895998998965899
9865696895678989999731346799898954569999888921954524899542129986556767999976998679767699767897896789
9876789934799998997890235689799962978999767939878436789674398898668979998865797598755589656656897994
9997898956789987976531345679677899899987656899989547994989987798779893987654679459543478943348998923
8998987997999995987632456789545698789498545689999759213498986649899754597643812398656569651267899434
7999896889998754698743458997324789579597934778923978904597665431998996997532101259769778953456897645
6798765567899643987654599765437994468986724567910989895689543210127789876543312345978989764567979967
4987654378989756998765689976546792399654212389891296789798787631435678987654443656989999875678967898
2098754235678999779876797987656910987543101245789945679899976543576899998765564778999932996789458929
3989976127889987667997896798767891987654424699896832398932987656688978989896685889568899869892349310
9868997346999875454598945699898932398765536789995431987893498767899769875959786893456789654901258921
8754398757997654323579436989989693999896645892189546976789999989923459974349897932365696543212347893
6543239898996543212467949876976579899987756943478969875656898694304598763201998921234789876423456789
5432123999987954323678998765432455689299897894567899764348976543212797654512989432345998765434567892
7521012999899876549789999897621234579109998985678998654237898754344598865623976543456899876545679921
8633439878799987899897899998510123678998789976899899893156789765998789998734989954987932987678789540
9864598765689998965956798679323234569876577897916789989345678989899893239845698899898921099989898432
9998679854345999654346689598764345779765466789434598978976789998799932134956987645689542134599987656
8998798943239876543235595439895456989887345678949987956897899987679543235977898634579763289998799867
6899987654945998754123459910976567899996576789298976745679999896568954345989999548678975467896549878
5979898999899986543234567891297679999987897890197545236798998765467895456791987656799987579965434989
4656789889788998767349679999989989998799998989975432124567899865346896569942998979989998998943219898
3546798775667899898457889998967899989654349678985421013456792964236789998899879998879899987894698767
2124999654556999999578999887856789978993244569876534124567891098145698766679965987768798986999898756
4019886543445678998789498656745689869789123456998975335688989987234897655567894976543567895878986545
2129765432137999999894349743136789754698934567899996746899978976457986543456932987657678944669875436
7439876543446789987953219865347996543567897678985987968999767896569875432345891099768989323456996557
6545998655567896896432101965468987662378998989864699879987658899678987564676792943978993101245987698
9656789986878995987643229877599299831499349899943012989976545798989898665687899891099765622456798789
8967893297889689998784346987689123910976456789652127899965434567898799897798989799999865436567899893
7898989098993568999896598998891019899897887899754335789854323459998678998929978677892987545678978932
6989878999012456789998799989989129798789998979896467899765401568892489789219865566991297656789769991
5978567896434568999999988664578998654698999567987568987654312456791336678997654455789998769893456989
4564456789565689989899977553467976553487893459998679598776534587890124569898653234567899899932499879
3412367998798799976799765432149875432346892467899795439987659698989235879679765165689998989543989967
2101267899899899865789979574235996543556921235679899920398878969778956989469981012357897678999867898
3213458902942998654799988765346987965698910126896998891239989754567897892398792123968958569987658919
4323667899431299865678999875467899879899991298945987789645997643456789954999653246799542459876549201
6454798988949987978789543987598923989987789989539976567959865432347899999898754757898931345998678912
7565899567898765989999432399999212399876569878998765458967987541767979889769875768967890156999789323
8787893458999994395678940998798993569765498567897654378998998652378967678943986779756799299899996547
9898984567899989234567899895576789679854376456899989234989976543578954587892197889549898986789769756
8999765698969878987679999784445689798765212345698762134567897665689543456789098994338987654678959897
7689878789757767898991987643234778949854323456798743457789998778789642345678999543227699865789244998
6567989897643456789210299753124569534999954567987654568899899899999765467889987654103456986990123469
5478999976532345689321398921015678965987895678998865679945799998999876989996798793212568998932645567
4369898764321234789932987932124789976996799799879978795634568987899987896765979984324579679943787699
5456798765410123567893996893245899989875778986565989894325689976799898965434769876458689557899998789
6568899879321235778999875789359989898764567897454598965434798765689769996323459987568789445678999897
7679932998932446799987754568998766789832456779213457896545679874579943987899968998789893234789678965
8998921987999967899876543479899854698901234568902345679656789863467892399998799659899932145796567973
9867899896987899998765432456789783987892345689214696898767998654567999457987688943998643466965459892
8756798765695678999897551235699542356789466895438789999879979865678978969896567891239894997896569789
4348898654254768999959652357898421368996598987549899989999867979789767998765456789349989789998879675
2123998763123456789239743568987210156987679297656789878987656899897659798765345695498878678899998423
3239129864346579890126987679875431234898789198987997569876543988987545679892129989697666567789397674
5498998765457678989345999893986532456789999999798998678998732567896534569989398879986553435679298786
6987689986678799778999878912976543467895667894569989799998643488965423498878987969865432324778999897
9876579997989891566789967109898654567973456789994679987987656567893212987569976656986541013567899998
9765468998999932345698754398769767678962347999873598976598767779984329765467965545987656723459999999
7654357899989993996789965987659898889653458998762987654349898899876498654389894321299867936578987899
6543246789879879789898996986543969999784567897654998743236999999987569865234789210156978547789476789
6432135678967865678987989987542355678996788969879876574135789987598997973123579931345899658892345699
7687548789656654599876767895431234567899899356998765431013892393469986521034567892456789867901557789
9798656899545433987654456987650125678967943249659896432354989989578987432145679954667898979212678994
9898787998621012976512345798761334789458954998949999563765679878999976565358789976898997989954569313
8999998999732135997433558999873547997378999876797698754876798767989989987467898989929876896796798901
7899899986543249876547667898984756895489987945679549865677899654878990298998957599949765765689997899
6789763298854658997659879987899867896999876435678939978788998743456891999979546467899854234567895998
5678943149765867899792989976789998979899987549899598989899239654789979799868932345679972123478924987
4789432027986878998910996765678999456789898956965467899999198765689565689657896566798763244569109876
9899843456797899987899875654567892345798779767895345678988989876789434798798997678987654559789299954
9999754568998998976789654563479954467997659878943234589967979987996545899899698789899765667899987832
9998765678919987565699943242348976778976543989542199789856567699397696799943569898759876779999876521
8989876789109875454689893101567898989975432397659988998743434569298787898759699999643998896598765430
7976989893298755323456789232456789090986941098798767997632129678969899969898988998932449987439875421
6895492994398943212345795467767892191999892149899656789547298989654993456987776897891234598321987632
5999910989987653202456789578978943989898789236987646797656956996532389767996545456910123987532398943
4687899875499854578569897989989659878767679345998334689899897898675478979885432345891435798543459654
3496789986799875989689965395699899767654578959886123899989799999896567898765421256789545899866599975
2345678997898976798798754234579987654323467998765335789975639878987679999854210168998766789978789989
1456789998966987899898655123678999843212345689976547999764526567998989988975432259789987893199899899
0267899869445698999989632016789654954301386797897678998653212349999899867997546345678998992098965789
9469923954236789998679542124578979865716577896779989998632101239877645456789667456799659789987654567
8999919878997999997568993295689899876897679954567896987543212349765432347898778568892345694398767678
7887899989889999876457789989789789998998789343679964597654343598654321236789889678901299789459998789
6576789999768798765354699979998679789659893212489873298785764789965446545899998799999987999567999893
5454678988657669989212989767897578679943954401678994569876989999876557656999029891987686898978998942
6213469976543457898929876456896434578894975626899789978989899997998969797898998932396545657899997653
7534578954332598997899954345965323456789876545679679899998789896989979898967987543987432346998789767
8945789764101239876799875697894212399899998666789456789989679765879989999656798654987621499887679988
9767897653214398785789976989976201987989109877891345679765578954567898989545659765699710987674567899
9878999764323987674567897978943219896579299989943456998674458943456967878931349889799831298543456789
6989789975439876563456999867894329785498989998657569876533267932678955467893456992987542975432545699
5497569876798765442499998758965498674356678939978998975420157893489543248954567891598659864321234568
4323456988999654321378959967976987543234568921989987654321345789599432139896689932398769765434656899
5435567899998766562457949878987898656045679210191099865432467897678945546789796546459879876545767899

140
2021/src/day1.rs Normal file
View File

@@ -0,0 +1,140 @@
//! --- Day 1: Sonar Sweep ---
//! You're minding your own business on a ship at sea when the overboard alarm goes off! You rush to see if you can help. Apparently, one of the Elves tripped and accidentally sent the sleigh keys flying into the ocean!
//!
//! Before you know it, you're inside a submarine the Elves keep ready for situations like this. It's covered in Christmas lights (because of course it is), and it even has an experimental antenna that should be able to track the keys if you can boost its signal strength high enough; there's a little meter that indicates the antenna's signal strength by displaying 0-50 stars.
//!
//! Your instincts tell you that in order to save Christmas, you'll need to get all fifty stars by December 25th.
//!
//! Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!
//!
//! As the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine.
//!
//! For example, suppose you had the following report:
//!
//! 199
//! 200
//! 208
//! 210
//! 200
//! 207
//! 240
//! 269
//! 260
//! 263
//! This report indicates that, scanning outward from the submarine, the sonar sweep found depths of 199, 200, 208, 210, and so on.
//!
//! The first order of business is to figure out how quickly the depth increases, just so you know what you're dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something.
//!
//! To do this, count the number of times a depth measurement increases from the previous measurement. (There is no measurement before the first measurement.) In the example above, the changes are as follows:
//!
//! 199 (N/A - no previous measurement)
//! 200 (increased)
//! 208 (increased)
//! 210 (increased)
//! 200 (decreased)
//! 207 (increased)
//! 240 (increased)
//! 269 (increased)
//! 260 (decreased)
//! 263 (increased)
//! In this example, there are 7 measurements that are larger than the previous measurement.
//!
//! How many measurements are larger than the previous measurement?
//! --- Part Two ---
//! Considering every single measurement isn't as useful as you expected: there's just too much noise in the data.
//!
//! Instead, consider sums of a three-measurement sliding window. Again considering the above example:
//!
//! 199 A
//! 200 A B
//! 208 A B C
//! 210 B C D
//! 200 E C D
//! 207 E F D
//! 240 E F G
//! 269 F G H
//! 260 G H
//! 263 H
//! Start by comparing the first and second three-measurement windows. The measurements in the first window are marked A (199, 200, 208); their sum is 199 + 200 + 208 = 607. The second window is marked B (200, 208, 210); its sum is 618. The sum of measurements in the second window is larger than the sum of the first, so this first comparison increased.
//!
//! Your goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum. So, compare A with B, then compare B with C, then C with D, and so on. Stop when there aren't enough measurements left to create a new three-measurement sum.
//!
//! In the above example, the sum of each three-measurement window is as follows:
//!
//! A: 607 (N/A - no previous sum)
//! B: 618 (increased)
//! C: 618 (no change)
//! D: 617 (decreased)
//! E: 647 (increased)
//! F: 716 (increased)
//! G: 769 (increased)
//! H: 792 (increased)
//! In this example, there are 5 sums that are larger than the previous sum.
//!
//! Consider sums of a three-measurement sliding window. How many sums are larger than the previous sum?
use anyhow::Result;
use aoc_runner_derive::{aoc, aoc_generator};
/// Reads text file containing one integer per line, and parses them into `Vec<u32>`.
#[aoc_generator(day1)]
fn parse(input: &str) -> Result<Vec<u32>> {
input.split('\n').map(|s| Ok(s.parse()?)).collect()
}
#[aoc(day1, part1)]
fn part1(depths: &[u32]) -> Result<u32> {
Ok(depths
.windows(2)
.map(|s| if s[0] < s[1] { 1 } else { 0 })
.sum())
}
#[aoc(day1, part2)]
fn part2(depths: &[u32]) -> Result<u32> {
let sums: Vec<u32> = depths.windows(3).map(|s| s.iter().sum()).collect();
Ok(sums
.windows(2)
.map(|s| if s[0] < s[1] { 1 } else { 0 })
.sum())
}
#[test]
fn test_part1() -> Result<()> {
assert_eq!(
part1(&parse(
r#"199
200
208
210
200
207
240
269
260
263"#
)?)?,
7
);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
assert_eq!(
part2(&parse(
r#"199
200
208
210
200
207
240
269
260
263"#
)?)?,
5
);
Ok(())
}

265
2021/src/day10.rs Normal file
View File

@@ -0,0 +1,265 @@
//! --- Day 10: Syntax Scoring ---
//! You ask the submarine to determine the best route out of the deep-sea cave, but it only replies:
//!
//! Syntax error in navigation subsystem on line: all of them
//! All of them?! The damage is worse than you thought. You bring up a copy of the navigation subsystem (your puzzle input).
//!
//! The navigation subsystem syntax is made of several lines containing chunks. There are one or more chunks on each line, and chunks contain zero or more other chunks. Adjacent chunks are not separated by any delimiter; if one chunk stops, the next chunk (if any) can immediately start. Every chunk must open and close with one of four legal pairs of matching characters:
//!
//! If a chunk opens with (, it must close with ).
//! If a chunk opens with [, it must close with ].
//! If a chunk opens with {, it must close with }.
//! If a chunk opens with <, it must close with >.
//! So, () is a legal chunk that contains no other chunks, as is []. More complex but valid chunks include ([]), {()()()}, <([{}])>, [<>({}){}[([])<>]], and even (((((((((()))))))))).
//!
//! Some lines are incomplete, but others are corrupted. Find and discard the corrupted lines first.
//!
//! A corrupted line is one where a chunk closes with the wrong character - that is, where the characters it opens and closes with do not form one of the four legal pairs listed above.
//!
//! Examples of corrupted chunks include (], {()()()>, (((()))}, and <([]){()}[{}]). Such a chunk can appear anywhere within a line, and its presence causes the whole line to be considered corrupted.
//!
//! For example, consider the following navigation subsystem:
//!
//! [({(<(())[]>[[{[]{<()<>>
//! [(()[<>])]({[<{<<[]>>(
//! {([(<{}[<>[]}>{[]{[(<()>
//! (((({<>}<{<{<>}{[]{[]{}
//! [[<[([]))<([[{}[[()]]]
//! [{[{({}]{}}([{[{{{}}([]
//! {<[[]]>}<{[{[{[]{()[[[]
//! [<(<(<(<{}))><([]([]()
//! <{([([[(<>()){}]>(<<{{
//! <{([{{}}[<[[[<>{}]]]>[]]
//! Some of the lines aren't corrupted, just incomplete; you can ignore these lines for now. The remaining five lines are corrupted:
//!
//! {([(<{}[<>[]}>{[]{[(<()> - Expected ], but found } instead.
//! [[<[([]))<([[{}[[()]]] - Expected ], but found ) instead.
//! [{[{({}]{}}([{[{{{}}([] - Expected ), but found ] instead.
//! [<(<(<(<{}))><([]([]() - Expected >, but found ) instead.
//! <{([([[(<>()){}]>(<<{{ - Expected ], but found > instead.
//! Stop at the first incorrect closing character on each corrupted line.
//!
//! Did you know that syntax checkers actually have contests to see who can get the high score for syntax errors in a file? It's true! To calculate the syntax error score for a line, take the first illegal character on the line and look it up in the following table:
//!
//! ): 3 points.
//! ]: 57 points.
//! }: 1197 points.
//! >: 25137 points.
//! In the above example, an illegal ) was found twice (2*3 = 6 points), an illegal ] was found once (57 points), an illegal } was found once (1197 points), and an illegal > was found once (25137 points). So, the total syntax error score for this file is 6+57+1197+25137 = 26397 points!
//!
//! Find the first illegal character in each corrupted line of the navigation subsystem. What is the total syntax error score for those errors?
//!
//! --- Part Two ---
//! Now, discard the corrupted lines. The remaining lines are incomplete.
//!
//! Incomplete lines don't have any incorrect characters - instead, they're missing some closing characters at the end of the line. To repair the navigation subsystem, you just need to figure out the sequence of closing characters that complete all open chunks in the line.
//!
//! You can only use closing characters (), ], }, or >), and you must add them in the correct order so that only legal pairs are formed and all chunks end up closed.
//!
//! In the example above, there are five incomplete lines:
//!
//!
//! [({(<(())[]>[[{[]{<()<>> - Complete by adding }}]])})].
//! [(()[<>])]({[<{<<[]>>( - Complete by adding )}>]}).
//! (((({<>}<{<{<>}{[]{[]{} - Complete by adding }}>}>)))).
//! {<[[]]>}<{[{[{[]{()[[[] - Complete by adding ]]}}]}]}>.
//! <{([{{}}[<[[[<>{}]]]>[]] - Complete by adding ])}>.
//! Did you know that autocomplete tools also have contests? It's true! The score is determined by considering the completion string character-by-character. Start with a total score of 0. Then, for each character, multiply the total score by 5 and then increase the total score by the point value given for the character in the following table:
//!
//! ): 1 point.
//! ]: 2 points.
//! }: 3 points.
//! >: 4 points.
//! So, the last completion string above - ])}> - would be scored as follows:
//!
//! Start with a total score of 0.
//! Multiply the total score by 5 to get 0, then add the value of ] (2) to get a new total score of 2.
//! Multiply the total score by 5 to get 10, then add the value of ) (1) to get a new total score of 11.
//! Multiply the total score by 5 to get 55, then add the value of } (3) to get a new total score of 58.
//! Multiply the total score by 5 to get 290, then add the value of > (4) to get a new total score of 294.
//! The five lines' completion strings have total scores as follows:
//!
//! }}]])})] - 288957 total points.
//! )}>]}) - 5566 total points.
//! }}>}>)))) - 1480781 total points.
//! ]]}}]}]}> - 995444 total points.
//! ])}> - 294 total points.
//! Autocomplete tools are an odd bunch: the winner is found by sorting all of the scores and then taking the middle score. (There will always be an odd number of scores to consider.) In this example, the middle score is 288957 because there are the same number of scores smaller and larger than it.
//!
//! Find the completion string for each incomplete line, score the completion strings, and sort the scores. What is the middle score?
use std::collections::HashMap;
use anyhow::Result;
use aoc_runner_derive::aoc;
fn corrupt_score(b: u8) -> u64 {
match b {
b')' => 3,
b']' => 57,
b'}' => 1197,
b'>' => 25137,
_ => panic!("unknown illegal character '{}'", b),
}
}
fn corrupted(line: &str) -> Option<u8> {
let pairs: HashMap<_, _> = vec![
(b'(', b')'),
(b'{', b'}'),
(b'[', b']'),
(b'<', b'>'),
(b')', b'('),
(b'}', b'{'),
(b']', b'['),
(b'>', b'<'),
]
.into_iter()
.collect();
let mut stack = Vec::new();
for b in line.as_bytes() {
match b {
b'[' | b'(' | b'{' | b'<' => stack.push(b),
b']' | b')' | b'}' | b'>' => {
let c = pairs[stack.pop().unwrap()];
if c != *b {
return Some(*b);
}
}
_ => panic!("Unexpected delimiter '{}'", b),
}
}
None
}
fn incomplete_score(bs: &[u8]) -> u64 {
bs.iter().fold(0, |acc, b| {
acc * 5
+ match b {
b')' => 1,
b']' => 2,
b'}' => 3,
b'>' => 4,
_ => panic!("unknown illegal character '{}'", b),
}
})
}
fn incompleted(line: &str) -> Vec<u8> {
let pairs: HashMap<_, _> = vec![
(b'(', b')'),
(b'{', b'}'),
(b'[', b']'),
(b'<', b'>'),
(b')', b'('),
(b'}', b'{'),
(b']', b'['),
(b'>', b'<'),
]
.into_iter()
.collect();
let mut stack = Vec::new();
for b in line.as_bytes() {
match b {
b'[' | b'(' | b'{' | b'<' => stack.push(b),
b']' | b')' | b'}' | b'>' => {
stack.pop();
}
_ => panic!("Unexpected delimiter '{}'", b),
}
}
stack.iter().rev().map(|b| pairs[b]).collect()
}
#[aoc(day10, part1)]
fn part1(input: &str) -> Result<u64> {
Ok(input.lines().filter_map(corrupted).map(corrupt_score).sum())
}
#[aoc(day10, part2)]
fn part2(input: &str) -> Result<u64> {
let mut scores: Vec<_> = input
.lines()
.filter(|l| corrupted(l).is_none())
.filter_map(|l| {
let r = incompleted(l);
if r.is_empty() {
None
} else {
Some(r)
}
})
.map(|bs| incomplete_score(&bs))
.collect();
scores.sort_unstable();
Ok(scores[scores.len() / 2])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]
"#
.trim();
assert_eq!(part1(input)?, 26397);
Ok(())
}
#[test]
fn test_incompleted() {
assert_eq!(
incompleted("[({(<(())[]>[[{[]{<()<>>"),
b"}}]])})]".to_vec()
);
assert_eq!(incompleted("[(()[<>])]({[<{<<[]>>("), b")}>]})".to_vec());
assert_eq!(
incompleted("(((({<>}<{<{<>}{[]{[]{}"),
b"}}>}>))))".to_vec()
);
assert_eq!(
incompleted("{<[[]]>}<{[{[{[]{()[[[]"),
b"]]}}]}]}>".to_vec()
);
assert_eq!(incompleted("<{([{{}}[<[[[<>{}]]]>[]]"), b"])}>".to_vec());
}
#[test]
fn test_incomplete_score() {
assert_eq!(incomplete_score(&b"}}]])})]".to_vec()), 288957);
assert_eq!(incomplete_score(&b")}>]})".to_vec()), 5566);
assert_eq!(incomplete_score(&b"}}>}>))))".to_vec()), 1480781);
assert_eq!(incomplete_score(&b"]]}}]}]}>".to_vec()), 995444);
assert_eq!(incomplete_score(&b"])}>".to_vec()), 294);
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]
"#
.trim();
assert_eq!(part2(input)?, 288957);
Ok(())
}
}

444
2021/src/day11.rs Normal file
View File

@@ -0,0 +1,444 @@
use std::{
collections::HashSet,
convert::Infallible,
fmt::{Debug, Error, Formatter},
ops::{Index, IndexMut},
str::FromStr,
};
use anyhow::Result;
use aoc_runner_derive::aoc;
struct Image {
width: usize,
height: usize,
pixels: Vec<u8>,
flashes: usize,
}
impl Image {
fn kernel3x3<F>(&mut self, (x, y): (usize, usize), func: F)
where
F: Fn(u8) -> u8,
{
if x > 0 {
self[(x - 1, y)] = func(self[(x - 1, y)]);
if y > 0 {
self[(x - 1, y - 1)] = func(self[(x - 1, y - 1)]);
}
if y < self.height - 1 {
self[(x - 1, y + 1)] = func(self[(x - 1, y + 1)]);
}
}
if y > 0 {
self[(x, y - 1)] = func(self[(x, y - 1)]);
}
if y < self.height - 1 {
self[(x, y + 1)] = func(self[(x, y + 1)]);
}
if x < self.width - 1 {
self[(x + 1, y)] = func(self[(x + 1, y)]);
if y > 0 {
self[(x + 1, y - 1)] = func(self[(x + 1, y - 1)]);
}
if y < self.height - 1 {
self[(x + 1, y + 1)] = func(self[(x + 1, y + 1)]);
}
}
}
fn step(&mut self) {
self.pixels.iter_mut().for_each(|p| *p += 1);
let mut flashed: HashSet<(usize, usize)> = HashSet::new();
loop {
let mut flashes = 0;
// Apply the effect of a flash on neighbors
let mut need_to_flash = Vec::new();
for y in 0..self.height {
for x in 0..self.width {
if self[(x, y)] > 9 && !flashed.contains(&(x, y)) {
need_to_flash.push((x, y));
}
}
}
for (x, y) in need_to_flash {
self.kernel3x3((x, y), |x| x + 1);
flashed.insert((x, y));
flashes += 1;
}
if flashes == 0 {
break;
}
self.flashes += flashes;
}
self.pixels.iter_mut().for_each(|p| {
if *p > 9 {
*p = 0
}
});
}
fn sync(&self) -> bool {
let sentinel = self[(0, 0)];
for p in &self.pixels {
if *p != sentinel {
return false;
}
}
true
}
}
impl PartialEq for Image {
fn eq(&self, other: &Self) -> bool {
self.width == other.width && self.height == other.height && self.pixels == other.pixels
}
}
impl Debug for Image {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f)?;
for y in 0..self.height {
for x in 0..self.width {
write!(f, "{:3}", self[(x, y)])?;
}
writeln!(f)?;
}
Ok(())
}
}
impl FromStr for Image {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rows: Vec<_> = s.lines().collect();
let width = rows[0].len();
let height = rows.len();
let pixels = rows
.iter()
.flat_map(|row| row.as_bytes().iter().map(|b| b - b'0'))
.collect();
Ok(Image {
width,
height,
pixels,
flashes: 0,
})
}
}
impl Index<(usize, usize)> for Image {
type Output = u8;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
&mut self.pixels[x + y * self.width]
}
}
#[aoc(day11, part1)]
fn part1(input: &str) -> Result<usize> {
let mut im: Image = input.parse()?;
for _ in 0..100 {
im.step();
}
if im.width > 11 {
assert!(im.flashes > 1355);
}
Ok(im.flashes)
}
#[aoc(day11, part2)]
fn part2(input: &str) -> Result<usize> {
let mut im: Image = input.parse()?;
for i in 1.. {
im.step();
if im.sync() {
return Ok(i);
}
}
unreachable!();
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
"#
.trim();
assert_eq!(part1(input)?, 1656);
Ok(())
}
#[test]
fn test_step() -> Result<()> {
let mut im: Image = r#"
11111
19991
19191
19991
11111
"#
.trim()
.parse()?;
let step1: Image = r#"
34543
40004
50005
40004
34543
"#
.trim()
.parse()?;
let step2: Image = r#"
45654
51115
61116
51115
45654
"#
.trim()
.parse()?;
im.step();
assert_eq!(im, step1);
im.step();
assert_eq!(im, step2);
Ok(())
}
#[test]
fn test_many_iterations() -> Result<()> {
let mut im: Image = r#"
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
"#
.trim()
.parse()?;
let step1: Image = r#"
6594254334
3856965822
6375667284
7252447257
7468496589
5278635756
3287952832
7993992245
5957959665
6394862637
"#
.trim()
.parse()?;
let step2: Image = r#"
8807476555
5089087054
8597889608
8485769600
8700908800
6600088989
6800005943
0000007456
9000000876
8700006848
"#
.trim()
.parse()?;
let step3: Image = r#"
0050900866
8500800575
9900000039
9700000041
9935080063
7712300000
7911250009
2211130000
0421125000
0021119000
"#
.trim()
.parse()?;
let step4: Image = r#"
2263031977
0923031697
0032221150
0041111163
0076191174
0053411122
0042361120
5532241122
1532247211
1132230211
"#
.trim()
.parse()?;
let step5: Image = r#"
4484144000
2044144000
2253333493
1152333274
1187303285
1164633233
1153472231
6643352233
2643358322
2243341322
"#
.trim()
.parse()?;
let step6: Image = r#"
5595255111
3155255222
3364444605
2263444496
2298414396
2275744344
2264583342
7754463344
3754469433
3354452433
"#
.trim()
.parse()?;
let step7: Image = r#"
6707366222
4377366333
4475555827
3496655709
3500625609
3509955566
3486694453
8865585555
4865580644
4465574644
"#
.trim()
.parse()?;
let step8: Image = r#"
7818477333
5488477444
5697666949
4608766830
4734946730
4740097688
6900007564
0000009666
8000004755
6800007755
"#
.trim()
.parse()?;
let step9: Image = r#"
9060000644
7800000976
6900000080
5840000082
5858000093
6962400000
8021250009
2221130009
9111128097
7911119976
"#
.trim()
.parse()?;
let step10: Image = r#"
0481112976
0031112009
0041112504
0081111406
0099111306
0093511233
0442361130
5532252350
0532250600
0032240000
"#
.trim()
.parse()?;
let step10_flashes = 204;
im.step();
assert_eq!(im, step1, "step1");
im.step();
assert_eq!(im, step2, "step2");
im.step();
assert_eq!(im, step3, "step3");
im.step();
assert_eq!(im, step4, "step4");
im.step();
assert_eq!(im, step5, "step5");
im.step();
assert_eq!(im, step6, "step6");
im.step();
assert_eq!(im, step7, "step7");
im.step();
assert_eq!(im, step8, "step8");
im.step();
assert_eq!(im, step9, "step9");
im.step();
assert_eq!(im, step10, "step10");
assert_eq!(im.flashes, step10_flashes, "step10 wrong flashes");
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526
"#
.trim();
assert_eq!(part2(input)?, 195);
Ok(())
}
}

140
2021/src/day12.rs Normal file
View File

@@ -0,0 +1,140 @@
use std::collections::HashMap;
use anyhow::Result;
use aoc_runner_derive::aoc;
fn search(node: &str, nodes: &HashMap<&str, Vec<&str>>, path: String, paths: &mut Vec<String>) {
if node == "end" {
paths.push(path);
return;
}
for neighbor in &nodes[node] {
// If lowercase.
if neighbor.as_bytes()[0] & 0x20 != 0 && path.contains(neighbor) {
continue;
}
search(neighbor, nodes, format!("{},{}", path, neighbor), paths);
}
}
fn paths(nodes: &HashMap<&str, Vec<&str>>) -> usize {
let mut paths = Vec::new();
search("start", nodes, "start".to_string(), &mut paths);
paths.len()
}
#[aoc(day12, part1)]
fn part1(input: &str) -> Result<usize> {
let mut nodes = HashMap::new();
input.lines().for_each(|p| {
let (n1, n2) = p.split_once('-').expect("missing dash");
nodes.entry(n1).or_insert_with(Vec::new).push(n2);
nodes.entry(n2).or_insert_with(Vec::new).push(n1);
});
Ok(paths(&nodes))
}
fn search2<'a>(
node: &str,
nodes: &HashMap<&'a str, Vec<&'a str>>,
path: &[&'a str],
paths: &mut Vec<Vec<&'a str>>,
double: &'a str,
smalls: &[&'a str],
) {
if node == "end" {
paths.push(path.to_vec());
return;
}
for neighbor in &nodes[node] {
// If lowercase.
if neighbor.as_bytes()[0] & 0x20 != 0 {
if neighbor == &double {
// Allow two passes for this small node.
if path.iter().filter(|p| p == &neighbor).count() >= 2 {
continue;
}
} else {
// Only allow one pass for this small node.
if path.contains(neighbor) {
continue;
}
}
}
let mut child_path = path.to_vec();
child_path.push(neighbor);
search2(neighbor, nodes, &child_path, paths, double, smalls);
}
}
fn paths2(nodes: &HashMap<&str, Vec<&str>>) -> usize {
let mut paths = Vec::new();
let smalls: Vec<_> = nodes
.keys()
.filter(|n| n.as_bytes()[0] & 0x20 != 0)
.filter(|&n| n != &"start" && n != &"end")
.cloned()
.collect();
for double in &smalls {
search2(
"start",
nodes,
&["start"],
&mut paths,
double,
smalls.as_slice(),
);
}
paths.sort();
paths.dedup();
paths.len()
}
#[aoc(day12, part2)]
fn part2(input: &str) -> Result<usize> {
let mut nodes = HashMap::new();
input.lines().for_each(|p| {
let (n1, n2) = p.split_once('-').expect("missing dash");
nodes.entry(n1).or_insert_with(Vec::new).push(n2);
nodes.entry(n2).or_insert_with(Vec::new).push(n1);
});
Ok(paths2(&nodes))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
start-A
start-b
A-c
A-b
b-d
A-end
b-end
"#
.trim();
assert_eq!(part1(input)?, 10);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
start-A
start-b
A-c
A-b
b-d
A-end
b-end
"#
.trim();
assert_eq!(part2(input)?, 36);
Ok(())
}
}

258
2021/src/day13.rs Normal file
View File

@@ -0,0 +1,258 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
struct Image {
width: usize,
height: usize,
pixels: Vec<u8>,
}
impl Image {
fn new(width: usize, height: usize) -> Image {
let pixels = vec![0; width * height];
Image {
width,
height,
pixels,
}
}
fn new_with_pts(width: usize, height: usize, pts: &[(usize, usize)]) -> Image {
let pixels = vec![0; width * height];
let mut im = Image {
width,
height,
pixels,
};
dbg!(&width, &height);
pts.iter().for_each(|xy| im[*xy] = 1);
im
}
fn fold_y(&self, y_axis: usize) -> Image {
println!("fold_y @ {}", y_axis);
let mut im = Image::new(self.width, y_axis);
let odd = self.height % 2;
for y in 0..self.height {
for x in 0..self.width {
//dbg!( self.width, self.height, x, y, y_axis, (y % y_axis), self.pixels.len(), im.pixels.len());
if self[(x, y)] > 0 {
if y > y_axis {
im[(x, self.height - y - odd)] = self[(x, y)];
} else {
im[(x, y)] = self[(x, y)];
}
}
}
}
im
}
fn fold_x(&self, x_axis: usize) -> Image {
let odd = self.width % 2;
println!("fold_x @ {}", x_axis);
for y in 0..self.height {
assert_eq!(
self[(x_axis, y)],
0,
"w,h {},{} x_axis {}",
self.width,
self.height,
x_axis,
);
}
let mut im = Image::new(x_axis, self.height);
for y in 0..self.height {
for x in 0..self.width {
if self[(x, y)] > 0 {
if x > x_axis {
im[(self.width - x - odd, y)] = self[(x, y)];
} else {
im[(x, y)] = self[(x, y)];
}
}
}
}
im
}
fn count(&self) -> usize {
self.pixels.iter().filter(|&n| *n != 0).count()
}
}
impl Debug for Image {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f)?;
for y in 0..self.height {
for x in 0..self.width {
if self[(x, y)] > 0 {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
}
writeln!(f)?;
}
Ok(())
}
}
impl Index<(usize, usize)> for Image {
type Output = u8;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
//dbg!(self.width, self.height, x, y, self.pixels.len());
&mut self.pixels[x + y * self.width]
}
}
#[aoc(day13, part1)]
fn part1(input: &str) -> Result<usize> {
let (pts, folds) = input.split_once("\n\n").unwrap();
let pts: Vec<(usize, usize)> = pts
.lines()
.map(|l| l.split_once(',').unwrap())
.map(|(x, y)| (x.parse().unwrap(), y.parse().unwrap()))
.collect();
let folds: Vec<_> = folds
.lines()
.map(|l| l.split(' ').nth(2).unwrap().split_once('=').unwrap())
.map(|(axis, idx)| (axis, idx.parse().unwrap()))
.collect();
let (maxx, maxy) = pts
.iter()
.fold((0, 0), |(maxx, maxy), (x, y)| (maxx.max(*x), maxy.max(*y)));
let mut im = Image::new_with_pts(maxx + 1, maxy + 1, &pts);
//dbg!(&im);
for (axis, idx) in folds.iter().take(1) {
im = if *axis == "y" {
im.fold_y(*idx)
} else {
im.fold_x(*idx)
};
}
//assert!(im.count() < 896);
dbg!(&im);
Ok(im.count())
}
#[aoc(day13, part2)]
fn part2(input: &str) -> Result<usize> {
let (pts, folds) = input.split_once("\n\n").unwrap();
let pts: Vec<(usize, usize)> = pts
.lines()
.map(|l| l.split_once(',').unwrap())
.map(|(x, y)| (x.parse().unwrap(), y.parse().unwrap()))
.collect();
let folds: Vec<_> = folds
.lines()
.map(|l| l.split(' ').nth(2).unwrap().split_once('=').unwrap())
.map(|(axis, idx)| (axis, idx.parse().unwrap()))
.collect();
let (maxx, maxy) = pts
.iter()
.fold((0, 0), |(maxx, maxy), (x, y)| (maxx.max(*x), maxy.max(*y)));
let mut im = Image::new_with_pts(maxx + 1, maxy + 1, &pts);
//dbg!(&im);
for (axis, idx) in folds.iter() {
im = if *axis == "y" {
im.fold_y(*idx)
} else {
im.fold_x(*idx)
};
}
dbg!(&im);
Ok(im.count())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
6,10
0,14
9,10
0,3
10,4
4,11
6,0
6,12
4,1
0,13
10,12
3,4
3,0
8,4
1,10
2,14
8,10
9,0
fold along y=7
fold along x=5
"#
.trim();
assert_eq!(part1(input)?, 17);
Ok(())
}
#[test]
fn test_fold_x() -> Result<()> {
let input = r#"
0,0
1,1
3,3
4,4
fold along x=2
fold along y=2
"#
.trim();
let (pts, folds) = input.split_once("\n\n").unwrap();
let pts: Vec<(usize, usize)> = pts
.lines()
.map(|l| l.split_once(',').unwrap())
.map(|(x, y)| (x.parse().unwrap(), y.parse().unwrap()))
.collect();
let folds: Vec<_> = folds
.lines()
.map(|l| l.split(' ').nth(2).unwrap().split_once('=').unwrap())
.map(|(axis, idx)| (axis, idx.parse().unwrap()))
.collect();
let (maxx, maxy) = pts
.iter()
.fold((0, 0), |(maxx, maxy), (x, y)| (maxx.max(*x), maxy.max(*y)));
let mut im = Image::new_with_pts(maxx + 1, maxy + 1, &pts);
dbg!(&im);
for (axis, idx) in folds.iter() {
im = if *axis == "y" {
im.fold_y(*idx)
} else {
im.fold_x(*idx)
};
}
dbg!(&im);
//assert_eq!(im.count(), 17);
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part2(input)?, usize::MAX);
Ok(())
}
*/
}

298
2021/src/day14.rs Normal file
View File

@@ -0,0 +1,298 @@
use std::collections::HashMap;
use anyhow::Result;
use aoc_runner_derive::aoc;
struct TupleWindow<I, T>
where
I: Iterator<Item = T>,
{
iter: I,
prev: Option<T>,
next: Option<T>,
}
impl<I, T> TupleWindow<I, T>
where
I: Iterator<Item = T>,
{
fn new(iter: I, rules: &HashMap<&[u8], u8>) -> Self {
TupleWindow {
iter,
prev: None,
next: None,
}
}
}
impl<I, T> Iterator for TupleWindow<I, T>
where
I: Iterator<Item = T>,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.prev.is_none() {
self.prev = self.iter.next();
}
/*
template.next() {
template.flat_map(|y|
let z = rules[xy];
res[i * 2] = xy[0];
res[i * 2 + 1] = z;
res[i * 2 + 2] = xy[1];
});
//dbg!(String::from_utf8_lossy(&res));
res
*/
if let Some(next) = self.iter.next() {
let prev = self.prev.take();
self.prev = Some(next);
return prev;
}
None
}
}
fn expand_it<'a, I: 'a + Iterator<Item = &'a u8>>(
template: I,
rules: &HashMap<&[u8], u8>,
) -> impl Iterator<Item = &'a u8> {
TupleWindow::new(template, rules)
}
fn forty_steps<'a, I: 'a + Iterator<Item = &'a u8>>(it: I, rules: &HashMap<&[u8], u8>) -> usize {
return 0;
//let it = (1..40).fold(it, |acc, _| expand_it(acc, &rules));
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(
expand_it(it, &rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules),
&rules,
)
.count()
}
fn expand(template: &[u8], rules: &HashMap<&[u8], u8>) -> Vec<u8> {
let mut res = vec![0u8; template.len() * 2 - 1];
template.windows(2).enumerate().for_each(|(i, xy)| {
let z = rules[xy];
res[i * 2] = xy[0];
res[i * 2 + 1] = z;
res[i * 2 + 2] = xy[1];
});
//dbg!(String::from_utf8_lossy(&res));
res
}
fn count(template: &[u8]) -> (usize, usize) {
let m = template
.iter()
.fold(HashMap::<u8, usize>::new(), |mut m, v| {
*m.entry(*v).or_insert(0) += 1;
m
});
let mut keys: Vec<_> = m.keys().collect();
keys.sort_unstable();
let mut s = "".to_string();
for k in keys {
s.push_str(&format!("{}: {} ", String::from_utf8_lossy(&[*k]), m[k]));
}
m.values()
.fold((usize::MAX, 0), |(min, max), v| (min.min(*v), max.max(*v)))
}
#[aoc(day14, part1)]
fn part1(input: &str) -> Result<usize> {
let (template, rules) = input.split_once("\n\n").unwrap();
let rules: HashMap<&[u8], u8> = rules
.lines()
.map(|l| {
let (pair, insert) = l.split_once(" -> ").unwrap();
(pair.as_bytes(), insert.as_bytes()[0])
})
.collect();
let mut template = template.as_bytes().to_vec();
for i in 1..11 {
template = expand(&template, &rules);
let s = String::from_utf8_lossy(&template);
count(&template);
}
let (min, max) = count(&template);
Ok(max - min)
}
// TODO
//#[aoc(day14, part2)]
fn part2(input: &str) -> Result<usize> {
let (template, rules) = input.split_once("\n\n").unwrap();
let rules: HashMap<&[u8], u8> = rules
.lines()
.map(|l| {
let (pair, insert) = l.split_once(" -> ").unwrap();
(pair.as_bytes(), insert.as_bytes()[0])
})
.collect();
let cnt = forty_steps(template.as_bytes().iter(), &rules);
dbg!(cnt);
//println!("After step {}: {}", i, String::from_utf8_lossy(&template));
//let (min, max) = count(template);
//Ok(max - min)
Ok(0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
NNCB
CH -> B
HH -> N
CB -> H
NH -> C
HB -> C
HC -> B
HN -> C
NN -> C
BH -> H
NC -> B
NB -> B
BN -> B
BB -> N
BC -> B
CC -> N
CN -> C
"#
.trim();
assert_eq!(part1(input)?, 1588);
Ok(())
}
// TODO
//#[test]
fn test_part2() -> Result<()> {
let input = r#"
NNCB
CH -> B
HH -> N
CB -> H
NH -> C
HB -> C
HC -> B
HN -> C
NN -> C
BH -> H
NC -> B
NB -> B
BN -> B
BB -> N
BC -> B
CC -> N
CN -> C
"#
.trim();
assert_eq!(part2(input)?, 2188189693529);
Ok(())
}
}
// BB -> N BN NB BB NB NB BB
// BC -> B BB BC BN NB BB BC
// BH -> H BH HH BH HH HN NH
// BN -> B BB NB BN NB NB BB
// CB -> H CH HB \
// CC -> N CN NC
// CH -> B CB BH
// CN -> C CC CN
// HB -> C HC CB
// HC -> B HB BC
// HH -> N HN NH
// HN -> C HC CN
// NB -> B NB BB
// NC -> B NC BC
// NH -> C NC CH
// NN -> C NC CN
//
//
//

272
2021/src/day15.rs Normal file
View File

@@ -0,0 +1,272 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
struct Image {
width: usize,
height: usize,
pixels: Vec<usize>,
}
impl Image {
fn new(width: usize, height: usize) -> Image {
let pixels = vec![0; width * height];
Image {
width,
height,
pixels,
}
}
}
impl Debug for Image {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f)?;
for y in 0..self.height {
for x in 0..self.width {
write!(f, "{}", self[(x, y)])?;
}
writeln!(f)?;
}
Ok(())
}
}
impl Index<(usize, usize)> for Image {
type Output = usize;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
&mut self.pixels[x + y * self.width]
}
}
impl FromStr for Image {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rows: Vec<_> = s.lines().collect();
let width = rows[0].len();
let height = rows.len();
let pixels = rows
.iter()
.flat_map(|row| row.as_bytes().iter().map(|b| (b - b'0') as usize))
.collect();
Ok(Image {
width,
height,
pixels,
})
}
}
use std::{cmp::Ordering, collections::BinaryHeap};
#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
cost: usize,
position: usize,
}
// The priority queue depends on `Ord`.
// Explicitly implement the trait so the queue becomes a min-heap
// instead of a max-heap.
impl Ord for State {
fn cmp(&self, other: &Self) -> Ordering {
// Notice that the we flip the ordering on costs.
// In case of a tie we compare positions - this step is necessary
// to make implementations of `PartialEq` and `Ord` consistent.
other
.cost
.cmp(&self.cost)
.then_with(|| self.position.cmp(&other.position))
}
}
// `PartialOrd` needs to be implemented as well.
impl PartialOrd for State {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
// Each node is represented as a `usize`, for a shorter implementation.
struct Edge {
node: usize,
cost: usize,
}
impl Debug for Edge {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "Edge{{node: {}, cost: {}}}", self.node, self.cost)?;
Ok(())
}
}
// From https://doc.rust-lang.org/std/collections/binary_heap/index.html
// Dijkstra's shortest path algorithm.
// Start at `start` and use `dist` to track the current shortest distance
// to each node. This implementation isn't memory-efficient as it may leave duplicate
// nodes in the queue. It also uses `usize::MAX` as a sentinel value,
// for a simpler implementation.
fn shortest_path(adj_list: &[Vec<Edge>], start: usize, goal: usize) -> Option<usize> {
// dist[node] = current shortest distance from `start` to `node`
let mut dist: Vec<_> = (0..adj_list.len()).map(|_| usize::MAX).collect();
let mut heap = BinaryHeap::new();
// We're at `start`, with a zero cost
dist[start] = 0;
heap.push(State {
cost: 0,
position: start,
});
// Examine the frontier with lower cost nodes first (min-heap)
while let Some(State { cost, position }) = heap.pop() {
// Alternatively we could have continued to find all shortest paths
if position == goal {
return Some(cost);
}
// Important as we may have already found a better way
if cost > dist[position] {
continue;
}
// For each node we can reach, see if we can find a way with
// a lower cost going through this node
for edge in &adj_list[position] {
let next = State {
cost: cost + edge.cost,
position: edge.node,
};
// If so, add it to the frontier and continue
if next.cost < dist[next.position] {
heap.push(next);
// Relaxation, we have now found a better way
dist[next.position] = next.cost;
}
}
}
// Goal not reachable
None
}
fn make_graph(im: &Image) -> Vec<Vec<Edge>> {
let idx = |x, y| y * im.width + x;
let mut graph: Vec<_> = Vec::new();
for y in 0..im.height {
for x in 0..im.width {
let mut edges = Vec::new();
if x > 0 {
edges.push(Edge {
node: idx(x - 1, y),
cost: im[(x - 1, y)],
});
}
if x < im.width - 1 {
edges.push(Edge {
node: idx(x + 1, y),
cost: im[(x + 1, y)],
});
}
if y > 0 {
edges.push(Edge {
node: idx(x, y - 1),
cost: im[(x, y - 1)],
});
}
if y < im.height - 1 {
edges.push(Edge {
node: idx(x, y + 1),
cost: im[(x, y + 1)],
});
}
graph.push(edges);
}
}
graph
}
#[aoc(day15, part1)]
fn part1(input: &str) -> Result<usize> {
let im: Image = input.parse()?;
let graph = make_graph(&im);
Ok(shortest_path(&graph, 0, im.pixels.len() - 1).unwrap())
}
fn x5(im: &Image) -> Image {
let mut im5 = Image::new(im.width * 5, im.height * 5);
for iy in 0..5 {
for ix in 0..5 {
for y in 0..im.height {
for x in 0..im.width {
let v = im[(x, y)] + ix + iy;
let dst_x = ix * im.width + x;
let dst_y = iy * im.height + y;
im5[(dst_x, dst_y)] = if v > 9 { v % 9 } else { v };
}
}
}
}
im5
}
#[aoc(day15, part2)]
fn part2(input: &str) -> Result<usize> {
let im: Image = input.parse()?;
let im = x5(&im);
let graph = make_graph(&im);
Ok(shortest_path(&graph, 0, im.pixels.len() - 1).unwrap())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
1163751742
1381373672
2136511328
3694931569
7463417111
1319128137
1359912421
3125421639
1293138521
2311944581
"#
.trim();
assert_eq!(part1(input)?, 40);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
1163751742
1381373672
2136511328
3694931569
7463417111
1319128137
1359912421
3125421639
1293138521
2311944581
"#
.trim();
assert_eq!(part2(input)?, 315);
Ok(())
}
}

245
2021/src/day16.rs Normal file
View File

@@ -0,0 +1,245 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
fn hex(b: &u8) -> u8 {
if *b >= b'A' {
10 + b - b'A'
} else {
b - b'0'
}
}
fn sum_version(packet: &Packet) -> u64 {
fn sum_packets(packets: &[Packet]) -> u64 {
packets.iter().map(sum_version).sum()
}
packet.version as u64
+ match &packet.packet_type {
PacketType::Sum(packets) => sum_packets(packets),
PacketType::Product(packets) => sum_packets(packets),
PacketType::Minimum(packets) => sum_packets(packets),
PacketType::Maximum(packets) => sum_packets(packets),
PacketType::Literal(_) => 0,
PacketType::GreaterThan(packets) => sum_packets(packets),
PacketType::LessThan(packets) => sum_packets(packets),
PacketType::Equal(packets) => sum_packets(packets),
}
}
fn interpret(packet: &Packet) -> u64 {
match &packet.packet_type {
PacketType::Sum(packets) => packets.iter().map(interpret).sum(),
PacketType::Product(packets) => packets.iter().map(interpret).product(),
PacketType::Minimum(packets) => packets.iter().map(interpret).min().unwrap(),
PacketType::Maximum(packets) => packets.iter().map(interpret).max().unwrap(),
PacketType::Literal(v) => *v,
PacketType::GreaterThan(packets) => {
if interpret(&packets[0]) > interpret(&packets[1]) {
1
} else {
0
}
}
PacketType::LessThan(packets) => {
if interpret(&packets[0]) < interpret(&packets[1]) {
1
} else {
0
}
}
PacketType::Equal(packets) => {
if interpret(&packets[0]) == interpret(&packets[1]) {
1
} else {
0
}
}
}
}
#[derive(Debug)]
enum PacketType {
// 0
Sum(Vec<Packet>),
// 1
Product(Vec<Packet>),
// 2
Minimum(Vec<Packet>),
// 3
Maximum(Vec<Packet>),
// 4
Literal(u64),
// 5
GreaterThan(Vec<Packet>),
// 6
LessThan(Vec<Packet>),
// 7
Equal(Vec<Packet>),
}
#[derive(Debug)]
struct Packet {
version: u64,
bit_size: u64,
packet_type: PacketType,
}
struct Parser<'a> {
bytes: &'a [u8],
tmp: u64,
tmp_len: usize,
}
impl<'a> Parser<'a> {
fn new(input: &str) -> Parser {
Parser {
bytes: input.as_bytes(),
tmp: 0,
tmp_len: 0,
}
}
fn read(&mut self, n: usize) -> u64 {
assert!(n < 32, "can't read more than 32 bits at time");
//print!( " BEGIN n {0} tmp 0b{1:b} len {2} - ", n, self.tmp, self.tmp_len);
while self.tmp_len < n {
let mut buf = [0; 1];
self.bytes.read_exact(&mut buf).expect("EOF");
// Convert the byte from hexdecimal to binary and merge with any leftover bits.
self.tmp = (self.tmp << 4) | hex(&buf[0]) as u64;
self.tmp_len += 4;
}
let mask = (1 << n) - 1;
self.tmp_len -= n;
let v = (self.tmp >> self.tmp_len) & mask;
let mask = (1 << self.tmp_len) - 1;
self.tmp &= mask;
//println!( " END n {0} tmp 0b{2:b} len {3} v 0b{1:00$b} ", n, v, self.tmp, self.tmp_len);
v as u64
}
}
fn parse_packet(p: &mut Parser) -> Packet {
let mut bit_size: u64 = 0;
let version = p.read(3);
bit_size += 3;
let packet_type_id = p.read(3);
bit_size += 3;
let packet_type = if packet_type_id == 4 {
// Literal, read 5 bits at a time until MSB is 0
let mut v = 0;
loop {
let l = p.read(5);
v = (v << 4) | (l & 0b1111);
bit_size += 5;
if 0b10000 & l == 0 {
break;
}
}
PacketType::Literal(v)
} else {
// length type ID
let ltid = p.read(1);
bit_size += 1;
let mut packets = Vec::new();
if ltid == 0 {
// If the length type ID is 0, then the next 15 bits are a number that represents the total length in bits of the sub-packets contained by this packet.
let len = p.read(15);
bit_size += 15;
let mut sub_bits = 0;
while sub_bits < len {
let sub_p = parse_packet(p);
bit_size += sub_p.bit_size;
sub_bits += sub_p.bit_size;
packets.push(sub_p);
}
} else {
// If the length type ID is 1, then the next 11 bits are a number that represents the number of sub-packets immediately contained by this packet.
let num = p.read(11);
bit_size += 11;
for _ in 0..num {
let sub_p = parse_packet(p);
bit_size += sub_p.bit_size;
packets.push(sub_p);
}
}
match packet_type_id {
0 => PacketType::Sum(packets),
1 => PacketType::Product(packets),
2 => PacketType::Minimum(packets),
3 => PacketType::Maximum(packets),
5 => PacketType::GreaterThan(packets),
6 => PacketType::LessThan(packets),
7 => PacketType::Equal(packets),
_ => panic!("unknown packet type ID {}", packet_type_id),
}
};
Packet {
version,
bit_size,
packet_type,
}
}
#[aoc(day16, part1)]
fn part1(input: &str) -> Result<u64> {
let mut p = Parser::new(input);
let packet = parse_packet(&mut p);
Ok(sum_version(&packet))
}
#[aoc(day16, part2)]
fn part2(input: &str) -> Result<u64> {
let mut p = Parser::new(input);
let packet = parse_packet(&mut p);
Ok(interpret(&packet))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = vec![
("D2FE28", 6),
//("38006F45291200", 1 + 0 + 0),
("8A004A801A8002F478", 16),
("620080001611562C8802118E34", 12),
("C0015000016115A2E0802F182340", 23),
("A0016C880162017C3686B18A3D4780", 31),
];
for (inp, want) in input {
print!("\nTesting '{}'\n - ", inp);
inp.as_bytes().iter().for_each(|c| print!("{:04b}", hex(c)));
println!();
assert_eq!(part1(inp)?, want);
println!("Passed '{}'", inp);
}
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = vec![
("C200B40A82", 3),
("04005AC33890", 54),
("880086C3E88112", 7),
("CE00C43D881120", 9),
("D8005AC2A8F0", 1),
("F600BC2D8F", 0),
("9C005AC2F8F0", 0),
("9C0141080250320F1802104A08", 1),
];
for (inp, want) in input {
print!("\nTesting '{}'\n - ", inp);
inp.as_bytes().iter().for_each(|c| print!("{:04b}", hex(c)));
println!();
assert_eq!(part2(inp)?, want);
println!("Passed '{}'", inp);
}
Ok(())
}
}

107
2021/src/day17.rs Normal file
View File

@@ -0,0 +1,107 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
#[derive(Debug)]
struct Target {
x_min: isize,
x_max: isize,
y_min: isize,
y_max: isize,
}
impl Target {
fn hit(&self, x: isize, y: isize) -> bool {
x >= self.x_min && x <= self.x_max && y >= self.y_min && y <= self.y_max
}
}
fn shoot(x: isize, y: isize, tgt: &Target) -> bool {
let mut x_inc = x;
let mut y_inc = y;
let mut x_cur = 0;
let mut y_cur = 0;
while x_cur <= tgt.x_max && y_cur >= tgt.y_min {
x_cur += x_inc;
y_cur += y_inc;
if x_inc > 0 {
x_inc -= 1;
}
y_inc -= 1;
if tgt.hit(x_cur, y_cur) {
return true;
}
}
false
}
impl FromStr for Target {
type Err = Infallible;
fn from_str(input: &str) -> std::result::Result<Target, Infallible> {
let parts: Vec<_> = input.split(' ').collect();
let x = &parts[2][2..].strip_suffix(',').unwrap();
let y = &parts[3][2..];
let (x_min, x_max) = x
.split_once("..")
.map(|(min, max)| (min.parse().unwrap(), max.parse().unwrap()))
.unwrap();
let (y_min, y_max) = y
.split_once("..")
.map(|(min, max)| (min.parse().unwrap(), max.parse().unwrap()))
.unwrap();
Ok(Target {
x_min,
x_max,
y_min,
y_max,
})
}
}
#[aoc(day17, part1)]
fn part1(input: &str) -> Result<isize> {
let tgt: Target = input.parse()?;
let n = tgt.y_min.abs() - 1;
Ok(n * (n + 1) / 2)
}
#[aoc(day17, part2)]
fn part2(input: &str) -> Result<usize> {
let tgt: Target = input.parse()?;
let mut cnt = 0;
let y_range = tgt.y_min.abs().max(tgt.y_min.abs());
for y in -y_range..=y_range {
for x in 1..=tgt.x_max {
if shoot(x, y, &tgt) {
cnt += 1;
}
}
}
Ok(cnt)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
target area: x=20..30, y=-10..-5
"#
.trim();
assert_eq!(part1(input)?, 45);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
target area: x=20..30, y=-10..-5
"#
.trim();
assert_eq!(part2(input)?, 112);
Ok(())
}
}

732
2021/src/day18.rs Normal file
View File

@@ -0,0 +1,732 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
use std::{
io::{BufReader, Cursor, Read},
ops::Add,
};
#[derive(Copy, Clone, Debug, PartialEq)]
enum ChildType {
None,
Value(usize),
Subtree(Idx),
}
#[derive(Copy, Clone, Default, PartialEq)]
struct Idx(usize);
impl Debug for Idx {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl Display for Idx {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, PartialEq)]
struct Node {
deleted: bool,
idx: Idx,
parent: Option<Idx>,
left: ChildType,
right: ChildType,
}
// Tree needs to support merging two into one for adding snailfish numbers.
// Tree needs to support rightward and leftward depth first searches to find neighbors for applying
// exploded spill over.
// Need to support remove and/or replace for explode.
// Need to support insert and/or replace for split.
#[derive(Debug, Default)]
struct Tree {
root: Idx,
nodes: Vec<Node>,
}
struct TreeIter {
it: std::vec::IntoIter<Idx>,
}
impl TreeIter {
fn new(indices: &[Idx]) -> TreeIter {
let indices = indices.to_vec();
TreeIter {
it: indices.into_iter(),
}
}
}
impl Iterator for TreeIter {
type Item = Idx;
fn next(&mut self) -> Option<Self::Item> {
self.it.next()
}
}
impl PartialEq for Tree {
fn eq(&self, other: &Self) -> bool {
// Lazy but should work.
self.to_string() == other.to_string()
}
}
fn read_byte<R: Read>(reader: &mut R) -> std::io::Result<Option<u8>> {
reader.bytes().next().transpose()
}
impl Tree {
fn reduce(&mut self) {
let mut changed = true;
while changed {
changed = self.explode();
println!("after explode {}", self);
if changed {
continue;
}
changed = self.split();
println!("after split {}", self);
//println!("splice changed {}", changed);
}
}
fn magnitude(&self) -> usize {
fn inner(tree: &Tree, node: &Node) -> usize {
match (node.left, node.right) {
(ChildType::Value(l), ChildType::Value(r)) => 3 * l + 2 * r,
(ChildType::Subtree(idx), ChildType::Value(r)) => {
3 * inner(&tree, &tree[idx]) + 2 * r
}
(ChildType::Value(l), ChildType::Subtree(idx)) => {
3 * l + 2 * inner(&tree, &tree[idx])
}
(ChildType::Subtree(l_idx), ChildType::Subtree(r_idx)) => {
3 * inner(&tree, &tree[l_idx]) + 2 * inner(&tree, &tree[r_idx])
}
_ => panic!("unhandled combo for magnitude"),
}
}
inner(self, &self[self.root])
}
fn split(&mut self) -> bool {
if let Some(split_idx) = self
.left_to_right()
.skip_while(|idx| {
let n = &self[*idx];
if let ChildType::Value(v) = n.left {
if v > 9 {
return false;
}
}
if let ChildType::Value(v) = n.right {
if v > 9 {
return false;
}
}
true
})
.next()
{
if let ChildType::Value(v) = self[split_idx].left {
if v > 9 {
let l = v / 2;
let r = if v % 2 == 1 { 1 + v / 2 } else { v / 2 };
let mut new_idx = self.add_node(ChildType::Value(l), ChildType::Value(r));
self[new_idx].parent = Some(split_idx);
self[split_idx].left = ChildType::Subtree(new_idx);
}
}
if let ChildType::Value(v) = self[split_idx].right {
if v > 9 {
let l = v / 2;
let r = if v % 2 == 1 { 1 + v / 2 } else { v / 2 };
let mut new_idx = self.add_node(ChildType::Value(l), ChildType::Value(r));
self[new_idx].parent = Some(split_idx);
self[split_idx].right = ChildType::Subtree(new_idx);
}
}
return true;
}
false
}
fn explode(&mut self) -> bool {
let mut changed = false;
if let Some(node) = self
.nodes
.iter()
.filter(|n| !n.deleted)
.find(|n| self.depth(n) >= 4)
{
changed = true;
let ex_idx = node.idx;
// Find spillover to the right
if let Some(spillover) = self
.left_to_right()
.skip_while(|idx| *idx != ex_idx)
.skip(1)
.find(|idx| {
let n = &self[*idx];
match (n.left, n.right) {
(ChildType::Subtree(_), ChildType::Subtree(_)) => false,
_ => true,
}
})
{
let src = self[ex_idx].right;
let tgt = &mut self[spillover];
if let (ChildType::Value(l), ChildType::Value(r)) = (src, tgt.left) {
tgt.left = ChildType::Value(l + r);
} else if let (ChildType::Value(l), ChildType::Value(r)) = (src, tgt.right) {
tgt.right = ChildType::Value(l + r);
} else {
unreachable!()
};
}
// Find spillover to the left
if let Some(spillover) = self
.right_to_left()
.skip_while(|idx| *idx != ex_idx)
.skip(1)
.find(|idx| {
let n = &self[*idx];
match (n.left, n.right) {
(ChildType::Subtree(_), ChildType::Subtree(_)) => false,
_ => true,
}
})
{
let src = self[ex_idx].left;
let tgt = &mut self[spillover];
if let (ChildType::Value(l), ChildType::Value(r)) = (src, tgt.right) {
tgt.right = ChildType::Value(l + r);
} else if let (ChildType::Value(l), ChildType::Value(r)) = (src, tgt.left) {
tgt.left = ChildType::Value(l + r);
} else {
unreachable!()
};
}
// Replace exploded node
self[ex_idx].deleted = true;
let p_idx = self[ex_idx].parent.expect("exploded root");
let p = &mut self[p_idx];
if let ChildType::Subtree(idx) = p.left {
if idx == ex_idx {
p.left = ChildType::Value(0);
}
}
if let ChildType::Subtree(idx) = p.right {
if idx == ex_idx {
p.right = ChildType::Value(0);
}
}
}
changed
}
fn depth(&self, node: &Node) -> usize {
if let Some(parent_idx) = node.parent {
1 + self.depth(&self[parent_idx])
} else {
0
}
}
fn find_root(&self, node: &Node) -> Idx {
match node.parent {
Some(parent_idx) => self.find_root(&self[parent_idx]),
None => node.idx,
}
}
fn add_node(&mut self, left: ChildType, right: ChildType) -> Idx {
let idx = Idx(self.nodes.len());
self.nodes.push(Node {
deleted: false,
idx,
parent: None,
left,
right,
});
idx
}
fn from_str_node(&mut self, r: &mut BufReader<Cursor<&[u8]>>) -> ChildType {
let mut parsing_left = true;
// Can this be rewritten to eliminate the need for `None`?
let mut left = ChildType::None;
let mut right = ChildType::None;
while let Ok(Some(b)) = read_byte(r) {
match b {
b'[' => {
let node = self.from_str_node(r);
if parsing_left {
left = node;
} else {
right = node;
}
}
b']' => {
let mut left_idx = None;
let mut right_idx = None;
if let ChildType::Subtree(idx) = left {
left_idx = Some(idx);
}
if let ChildType::Subtree(idx) = right {
right_idx = Some(idx);
}
let child_idx = self.add_node(left, right);
if let Some(idx) = left_idx {
self[idx].parent = Some(child_idx);
}
if let Some(idx) = right_idx {
self[idx].parent = Some(child_idx);
}
return ChildType::Subtree(child_idx);
}
b',' => parsing_left = false,
b'0'..=b'9' => {
let mut v = b - b'0';
if let Ok(Some(peek)) = read_byte(r) {
match peek {
b'0'..=b'9' => v = (peek - b'0') + 10 * v,
// Wasn't a number >9, push the byte back into the buffer.
_ => r.seek_relative(-1).expect("failed to seek"),
}
}
if parsing_left {
left = ChildType::Value(v.into());
parsing_left = false;
} else {
right = ChildType::Value(v.into());
}
continue;
}
_ => panic!("unknown byte '{}'", b),
}
}
unreachable!()
}
fn fmt_node(&self, f: &mut Formatter<'_>, node: &Node) -> std::fmt::Result {
write!(f, "[")?;
match node.left {
ChildType::None => panic!("left node was None"),
ChildType::Value(v) => write!(f, "{}", v)?,
ChildType::Subtree(idx) => self.fmt_node(f, &self[idx])?,
};
write!(f, ",")?;
match node.right {
ChildType::None => panic!("right node was None"),
ChildType::Value(v) => write!(f, "{}", v)?,
ChildType::Subtree(idx) => self.fmt_node(f, &self[idx])?,
};
write!(f, "]")?;
Ok(())
}
fn left_to_right(&mut self) -> TreeIter {
fn dfs(tree: &Tree, n: &Node, mut indices: &mut Vec<Idx>) {
if let ChildType::Subtree(idx) = n.left {
dfs(tree, &tree[idx], indices);
}
indices.push(n.idx);
if let ChildType::Subtree(idx) = n.right {
dfs(tree, &tree[idx], indices);
}
}
let mut indices = Vec::with_capacity(self.nodes.len());
dfs(self, &self[self.root], &mut indices);
TreeIter::new(&indices)
}
fn right_to_left(&mut self) -> TreeIter {
fn dfs(tree: &Tree, n: &Node, mut indices: &mut Vec<Idx>) {
if let ChildType::Subtree(idx) = n.right {
dfs(tree, &tree[idx], indices);
}
indices.push(n.idx);
if let ChildType::Subtree(idx) = n.left {
dfs(tree, &tree[idx], indices);
}
}
let mut indices = Vec::with_capacity(self.nodes.len());
dfs(self, &self[self.root], &mut indices);
TreeIter::new(&indices)
}
}
impl Add for Tree {
type Output = Tree;
fn add(self, other: Self) -> Self {
// This is lazy but works for simple any obvious reasons (if FromStr and Display work
// correctly).
format!("[{},{}]", self, other)
.parse()
.expect("failed to parse merge tree")
}
}
impl FromStr for Tree {
type Err = Infallible;
fn from_str(input: &str) -> std::result::Result<Tree, Infallible> {
let mut tree = Tree::default();
let mut bytes = input.as_bytes();
assert_eq!(
read_byte(&mut bytes).expect("couldn't read first byte"),
Some(b'[')
);
let mut b = BufReader::new(Cursor::new(bytes));
tree.from_str_node(&mut b);
tree.root = tree.find_root(&tree[Idx(0)]);
Ok(tree)
}
}
impl Index<Idx> for Tree {
type Output = Node;
fn index(&self, idx: Idx) -> &Self::Output {
&self.nodes[idx.0]
}
}
impl IndexMut<Idx> for Tree {
fn index_mut(&mut self, idx: Idx) -> &mut Self::Output {
&mut self.nodes[idx.0]
}
}
impl Display for Tree {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if self.nodes.is_empty() {
return write!(f, "[]");
}
let node = &self[self.root];
self.fmt_node(f, &node)?;
Ok(())
}
}
fn sum(input: &str) -> Tree {
input
.lines()
.map(|l| l.parse().expect("failed to parse"))
.reduce(|acc, t| acc + t)
.expect("failed to reduce")
}
#[aoc(day18, part1)]
fn part1(input: &str) -> Result<usize> {
let nums: Vec<Tree> = input
.lines()
.map(|l| {
dbg!(l);
l.parse().expect("failed to parse")
})
.collect();
let mut it = nums.into_iter();
let mut last = it.next().unwrap();
while let Some(next) = it.next() {
println!(" {}", last);
println!("+ {}", next);
last = last + next;
println!("= {}", last);
last.reduce();
println!("= {}\n", last);
}
Ok(last.magnitude())
}
/*
#[aoc(day18, part2)]
fn part2(input: &str) -> Result<usize> {
todo!("part2");
Ok(0)
}
*/
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_display() -> Result<()> {
for (i, s) in ["[1,2]", "[[1,2],3]", "[1,[2,3]]", "[[1,2],[3,4]]"]
.into_iter()
.enumerate()
{
let t = s.parse::<Tree>()?;
assert_eq!(&t.to_string(), s, "input {}: '{}'", i, s);
//assert_eq!(&t.to_string(), s, "input {}: '{}'\ntree: {:#?}", i, s, t);
}
Ok(())
}
#[test]
fn test_sum() -> Result<()> {
let l: Tree = "[1,2]".parse().unwrap();
let r: Tree = "[[3,4],5]".parse().unwrap();
assert_eq!(l + r, "[[1,2],[[3,4],5]]".parse().unwrap());
let input = r#"
[[[[4,3],4],4],[7,[[8,4],9]]]
[1,1]
"#
.trim();
let mut s = sum(input);
s.reduce();
assert_eq!(s.to_string(), "[[[[0,7],4],[[7,8],[6,0]]],[8,1]]");
Ok(())
}
#[test]
fn test_reduce() -> Result<()> {
for (input, want) in [
("[0,[0,[0,[0,[0,0]]]]]", "[0,[0,[0,[0,0]]]]"),
("[[[[[[[[0,0],0],0],0],0],0],0],0]", "[[[[0,0],0],0],0]"),
("[[[[[[[0,0],0],0],0],0],0],0]", "[[[[0,0],0],0],0]"),
] {
println!("== test_reduce: {}", input);
let mut tree: Tree = input.parse()?;
tree.reduce();
let want = want.parse()?;
assert_eq!(tree, want, "\nInput {} Got {} Want {}", input, tree, want);
}
Ok(())
}
#[test]
fn test_explode() -> Result<()> {
for (input, want) in [
("[[[[0,0],0],0],0]", "[[[[0,0],0],0],0]"),
("[[[0,0],0],0]", "[[[0,0],0],0]"),
("[[0,0],0]", "[[0,0],0]"),
("[0,[0,[0,[0,0]]]]", "[0,[0,[0,[0,0]]]]"),
("[0,[0,[0,0]]]", "[0,[0,[0,0]]]"),
("[0,[0,0]]", "[0,[0,0]]"),
("[[[[[9,8],1],2],3],4]", "[[[[0,9],2],3],4]"),
("[7,[6,[5,[4,[3,2]]]]]", "[7,[6,[5,[7,0]]]]"),
("[[6,[5,[4,[3,2]]]],1]", "[[6,[5,[7,0]]],3]"),
(
"[[3,[2,[1,[7,3]]]],[6,[5,[4,[3,2]]]]]",
"[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]",
),
(
"[[3,[2,[8,0]]],[9,[5,[4,[3,2]]]]]",
"[[3,[2,[8,0]]],[9,[5,[7,0]]]]",
),
] {
println!("== test_explode: {}", input);
let mut tree: Tree = input.parse()?;
tree.explode();
let want = want.parse()?;
assert_eq!(tree, want, "\nInput {} Got {} Want {}", input, tree, want);
}
Ok(())
}
#[test]
fn test_split() -> Result<()> {
for (input, want) in [
("[10,0]", "[[5,5],0]"), //
("[0,11]", "[0,[5,6]]"),
("[[0,11],0]", "[[0,[5,6]],0]"),
("[11,0]", "[[5,6],0]"),
("[0,[11,0]]", "[0,[[5,6],0]]"),
("[12,0]", "[[6,6],0]"),
("[0,12]", "[0,[6,6]]"),
] {
println!("== test_split: {}", input);
let mut tree: Tree = input.parse()?;
dbg!(&tree);
tree.split();
let want = want.parse()?;
assert_eq!(tree, want, "\nInput {} Got {} Want {}", input, tree, want);
}
Ok(())
}
#[test]
fn test_magnitude() -> Result<()> {
for (input, want) in [
("[9,1]", 29),
("[1,9]", 21),
("[[9,1],[1,9]]", 129),
("[[1,2],[[3,4],5]]", 143),
("[[[[0,7],4],[[7,8],[6,0]]],[8,1]]", 1384),
("[[[[1,1],[2,2]],[3,3]],[4,4]]", 445),
("[[[[3,0],[5,3]],[4,4]],[5,5]]", 791),
("[[[[5,0],[7,4]],[5,5]],[6,6]]", 1137),
(
"[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]",
3488,
),
] {
let tree: Tree = input.parse()?;
assert_eq!(tree.magnitude(), want);
}
Ok(())
}
#[test]
fn test_add_and_reduce() -> Result<()> {
for (input, want) in [
(
r#"
[1,1]
[2,2]
[3,3]
[4,4]
"#,
"[[[[1,1],[2,2]],[3,3]],[4,4]]",
),
(
r#"
[1,1]
[2,2]
[3,3]
[4,4]
[5,5]
"#
.trim(),
"[[[[3,0],[5,3]],[4,4]],[5,5]]",
),
(
r#"
[1,1]
[2,2]
[3,3]
[4,4]
[5,5]
[6,6]
"#
.trim(),
"[[[[5,0],[7,4]],[5,5]],[6,6]]",
),
(
r#"
[[[[4,3],4],4],[7,[[8,4],9]]]
[1,1]
"#
.trim(),
"[[[[0,7],4],[[7,8],[6,0]]],[8,1]]",
),
] {
println!("== 1. test_add_and_reduce: {}", input);
let mut num = sum(input.trim());
println!("before reduce: {}", num);
num.reduce();
println!("after reduce: {}", num);
assert_eq!(num.to_string(), want);
}
for (l, r, eq) in [
(
"[[[[4,3],4],4],[7,[[8,4],9]]]",
"[1,1]",
"[[[[0,7],4],[[7,8],[6,0]]],[8,1]]",
),
(
"[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]",
"[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]",
"[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]",
),
(
"[[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]",
"[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]",
"[[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]",
),
(
"[[[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]]]",
"[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]",
"[[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]",
),
(
"[[[[7,0],[7,7]],[[7,7],[7,8]]],[[[7,7],[8,8]],[[7,7],[8,7]]]]",
"[7,[5,[[3,8],[1,4]]]]",
"[[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]",
),
(
"[[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]",
"[[2,[2,2]],[8,[8,1]]]",
"[[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]",
),
(
"[[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]",
"[2,9]",
"[[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]",
),
(
"[[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]",
"[1,[[[9,3],9],[[9,0],[0,7]]]]",
"[[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]",
),
(
"[[[[7,8],[6,7]],[[6,8],[0,8]]],[[[7,7],[5,0]],[[5,5],[5,6]]]]",
"[[[5,[7,4]],7],1]",
"[[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]",
),
(
"[[[[7,7],[7,7]],[[8,7],[8,7]]],[[[7,0],[7,7]],9]]",
"[[[[4,2],2],6],[8,7]]",
"[[[[8,7],[7,7]],[[8,6],[7,7]]],[[[0,7],[6,6]],[8,7]]]",
),
] {
let l: Tree = l.parse()?;
let r: Tree = r.parse()?;
let mut num = l + r;
println!("== 2. test_add_and_reduce: {}", num);
println!("before reduce: {}", num);
num.reduce();
println!("after reduce: {}", num);
assert_eq!(num.to_string(), eq);
}
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"
[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
[7,[5,[[3,8],[1,4]]]]
[[2,[2,2]],[8,[8,1]]]
[2,9]
[1,[[[9,3],9],[[9,0],[0,7]]]]
[[[5,[7,4]],7],1]
[[[[4,2],2],6],[8,7]]
"#
.trim();
assert_eq!(part1(input)?, 3488);
let input = r#"
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
[[[5,[2,8]],4],[5,[[9,9],0]]]
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
[[[[5,4],[7,7]],8],[[8,3],8]]
[[9,3],[[9,9],[6,[4,9]]]]
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
"#
.trim();
assert_eq!(part1(input)?, 4140);
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part2(input)?, usize::MAX);
Ok(())
}
*/
}

469
2021/src/day19.rs Normal file
View File

@@ -0,0 +1,469 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
use std::ops::{Add, Sub};
#[derive(Clone, Copy, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
struct Vec3([i64; 3]);
impl Add for Vec3 {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
Vec3([
self.0[0] + other.0[0],
self.0[1] + other.0[1],
self.0[2] + other.0[2],
])
}
}
impl Sub for Vec3 {
type Output = Self;
fn sub(self, other: Self) -> Self::Output {
Vec3([
self.0[0] - other.0[0],
self.0[1] - other.0[1],
self.0[2] - other.0[2],
])
}
}
impl Debug for Vec3 {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "<{:4},{:4},{:4}>", self.0[0], self.0[1], self.0[2])
}
}
impl FromStr for Vec3 {
type Err = Infallible;
fn from_str(input: &str) -> std::result::Result<Vec3, Infallible> {
let v: Vec<_> = input.split(',').map(|s| s.parse().unwrap()).collect();
Ok(Vec3(v.try_into().unwrap()))
}
}
#[derive(Debug)]
struct Scanner {
id: usize,
offset: Option<Vec3>,
points: Vec<Vec3>,
}
impl Scanner {
fn translate(&mut self, distance: Vec3, orientation: [usize; 3], signs: [i64; 3]) {
for p in &mut self.points {
*p = Vec3([
signs[0] * p.0[orientation[0]] + distance.0[0],
signs[1] * p.0[orientation[1]] + distance.0[1],
signs[2] * p.0[orientation[2]] + distance.0[2],
]);
}
}
}
impl FromStr for Scanner {
type Err = Infallible;
fn from_str(input: &str) -> std::result::Result<Scanner, Infallible> {
let mut it = input.lines();
let id = it
.next()
.unwrap()
.split(' ')
.nth(2)
.unwrap()
.parse()
.unwrap();
Ok(Scanner {
id,
offset: None,
points: it.map(|l| l.parse().unwrap()).collect(),
})
}
}
#[derive(Debug, PartialEq)]
struct Match {
abs_points: Vec<Vec3>,
distance: Vec3,
orientation: [usize; 3],
signs: [i64; 3],
}
// Returns overlap, and in s1 space
fn find_overlap(s1: &Scanner, s2: &Scanner) -> Option<Match> {
let mut counts: HashMap<(Vec3, [usize; 3], [i64; 3]), Vec<Vec3>> = HashMap::new();
let orientations = [
[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0],
];
let signs = [
[-1, -1, -1],
[1, -1, -1],
[-1, 1, -1],
[1, 1, -1],
[-1, -1, 1],
[1, -1, 1],
[-1, 1, 1],
];
for v1 in &s1.points {
for v2 in &s2.points {
for or in orientations {
for sign in signs {
let [x, y, z] = sign;
let v = Vec3([x * v2.0[or[0]], y * v2.0[or[1]], z * v2.0[or[2]]]);
let diff = *v1 - v;
counts.entry((diff, or, sign)).or_default().push(*v1);
}
}
}
}
if let Some(((distance, orientation, signs), list)) =
counts.into_iter().find(|(_k, v)| v.len() >= 12)
{
// s1's points should already be in absolute coords. s2 will be translated in
// part1().
return Some(Match {
abs_points: list,
distance,
orientation,
signs,
});
}
None
}
fn parse(input: &str) -> Result<Vec<Scanner>> {
input.split("\n\n").map(|s| Ok(s.parse()?)).collect()
}
#[aoc(day19, part1)]
fn part1(input: &str) -> Result<usize> {
let mut scanner = parse(input)?;
// Assign the first scanner to the origin (0,0,0).
// Put that in a list of recently registered scanners.
// In a loop
// - For each recently registered scanner, attempt to find overlap with each unregistered
// scanner.
// - Matches should be translated according to the offsets found during the match. This should
// put them in absolute space.
// - Each match should be added to the recently registered list for the next iteration.
// - Do this until all scanners are registered.
scanner[0].offset = Some(Vec3::default());
let (mut registered, mut unregistered): (VecDeque<_>, VecDeque<_>) =
scanner.into_iter().partition(|s| s.offset.is_some());
let mut becons = HashSet::new();
let mut done = Vec::new();
while let Some(reg) = registered.pop_front() {
let mut unregs = VecDeque::new();
for mut unreg in unregistered {
if let Some(mat) = find_overlap(&reg, &unreg) {
unreg.offset = Some(mat.distance);
unreg.translate(mat.distance, mat.orientation, mat.signs);
println!(
"scanner {} @ {:?} found {} hits",
&unreg.id,
&unreg.offset.unwrap(),
mat.abs_points.len()
);
registered.push_back(unreg);
for pt in mat.abs_points {
becons.insert(pt);
}
} else {
unregs.push_back(unreg);
}
}
done.push(reg);
unregistered = unregs;
}
println!("before pass 2: {}", becons.len());
for i in 0..registered.len() {
for j in i..registered.len() {
let s1 = &registered[i];
let s2 = &registered[j];
if let Some(mat) = find_overlap(s1, s2) {
for pt in mat.abs_points {
becons.insert(pt);
}
}
}
}
println!("after pass 2: {}", becons.len());
//assert_eq!(done.len(), 12);
let mut becons: Vec<_> = becons.iter().collect();
becons.sort();
dbg!(&becons);
Ok(becons.len())
}
/*
#[aoc(day19, part2)]
fn part2(input: &str) -> Result<usize> {
todo!("part2");
Ok(0)
}
*/
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_overlap() -> Result<()> {
use pretty_assertions::assert_eq;
let input = r#"
--- scanner 0 ---
404,-588,-901
528,-643,409
-838,591,734
390,-675,-793
-537,-823,-458
-485,-357,347
-345,-311,381
-661,-816,-575
-876,649,763
-618,-824,-621
553,345,-567
474,580,667
-447,-329,318
-584,868,-557
544,-627,-890
564,392,-477
455,729,728
-892,524,684
-689,845,-530
423,-701,434
7,-33,-71
630,319,-379
443,580,662
-789,900,-551
459,-707,401
--- scanner 1 ---
686,422,578
605,423,415
515,917,-361
-336,658,858
95,138,22
-476,619,847
-340,-569,-846
567,-361,727
-460,603,-452
669,-402,600
729,430,532
-500,-761,534
-322,571,750
-466,-666,-811
-429,-592,574
-355,545,-477
703,-491,-529
-328,-685,520
413,935,-424
-391,539,-444
586,-435,557
-364,-763,-893
807,-499,-711
755,-354,-619
553,889,-390
"#
.trim();
let mut abs_points: Vec<Vec3> = r#"
-618,-824,-621
-537,-823,-458
-447,-329,318
404,-588,-901
544,-627,-890
528,-643,409
-661,-816,-575
390,-675,-793
423,-701,434
-345,-311,381
459,-707,401
-485,-357,347
"#
.trim()
.lines()
.map(|l| l.parse().unwrap())
.collect();
abs_points.sort();
let orientation = [0, 1, 2];
let signs = [-1, 1, -1];
let distance = Vec3([68, -1246, -43]);
let want = Match {
distance,
abs_points,
orientation,
signs,
};
let scanners = parse(input)?;
let mut got = find_overlap(&scanners[0], &scanners[1]).unwrap();
got.abs_points.sort();
assert_eq!(want, got);
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"
--- scanner 0 ---
404,-588,-901
528,-643,409
-838,591,734
390,-675,-793
-537,-823,-458
-485,-357,347
-345,-311,381
-661,-816,-575
-876,649,763
-618,-824,-621
553,345,-567
474,580,667
-447,-329,318
-584,868,-557
544,-627,-890
564,392,-477
455,729,728
-892,524,684
-689,845,-530
423,-701,434
7,-33,-71
630,319,-379
443,580,662
-789,900,-551
459,-707,401
--- scanner 1 ---
686,422,578
605,423,415
515,917,-361
-336,658,858
95,138,22
-476,619,847
-340,-569,-846
567,-361,727
-460,603,-452
669,-402,600
729,430,532
-500,-761,534
-322,571,750
-466,-666,-811
-429,-592,574
-355,545,-477
703,-491,-529
-328,-685,520
413,935,-424
-391,539,-444
586,-435,557
-364,-763,-893
807,-499,-711
755,-354,-619
553,889,-390
--- scanner 2 ---
649,640,665
682,-795,504
-784,533,-524
-644,584,-595
-588,-843,648
-30,6,44
-674,560,763
500,723,-460
609,671,-379
-555,-800,653
-675,-892,-343
697,-426,-610
578,704,681
493,664,-388
-671,-858,530
-667,343,800
571,-461,-707
-138,-166,112
-889,563,-600
646,-828,498
640,759,510
-630,509,768
-681,-892,-333
673,-379,-804
-742,-814,-386
577,-820,562
--- scanner 3 ---
-589,542,597
605,-692,669
-500,565,-823
-660,373,557
-458,-679,-417
-488,449,543
-626,468,-788
338,-750,-386
528,-832,-391
562,-778,733
-938,-730,414
543,643,-506
-524,371,-870
407,773,750
-104,29,83
378,-903,-323
-778,-728,485
426,699,580
-438,-605,-362
-469,-447,-387
509,732,623
647,635,-688
-868,-804,481
614,-800,639
595,780,-596
--- scanner 4 ---
727,592,562
-293,-554,779
441,611,-461
-714,465,-776
-743,427,-804
-660,-479,-426
832,-632,460
927,-485,-438
408,393,-506
466,436,-512
110,16,151
-258,-428,682
-393,719,612
-211,-452,876
808,-476,-593
-575,615,604
-485,667,467
-680,325,-822
-627,-443,-432
872,-547,-609
833,512,582
807,604,487
839,-516,451
891,-625,532
-652,-548,-490
30,-46,-14
"#
.trim();
assert_eq!(part1(input)?, 79);
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part2(input)?, usize::MAX);
Ok(())
}
*/
}

125
2021/src/day2.rs Normal file
View File

@@ -0,0 +1,125 @@
//! --- Day 2: Dive! ---
//! Now, you need to figure out how to pilot this thing.
//!
//! It seems like the submarine can take a series of commands like forward 1, down 2, or up 3:
//!
//! forward X increases the horizontal position by X units.
//! down X increases the depth by X units.
//! up X decreases the depth by X units.
//! Note that since you're on a submarine, down and up affect your depth, and so they have the opposite result of what you might expect.
//!
//! The submarine seems to already have a planned course (your puzzle input). You should probably figure out where it's going. For example:
//!
//! forward 5
//! down 5
//! forward 8
//! up 3
//! down 8
//! forward 2
//! Your horizontal position and depth both start at 0. The steps above would then modify them as follows:
//!
//! forward 5 adds 5 to your horizontal position, a total of 5.
//! down 5 adds 5 to your depth, resulting in a value of 5.
//! forward 8 adds 8 to your horizontal position, a total of 13.
//! up 3 decreases your depth by 3, resulting in a value of 2.
//! down 8 adds 8 to your depth, resulting in a value of 10.
//! forward 2 adds 2 to your horizontal position, a total of 15.
//! After following these instructions, you would have a horizontal position of 15 and a depth of 10. (Multiplying these together produces 150.)
//!
//! Calculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth?
//!
//! --- Part Two ---
//! Based on your calculations, the planned course doesn't seem to make any sense. You find the submarine manual and discover that the process is actually slightly more complicated.
//!
//! In addition to horizontal position and depth, you'll also need to track a third value, aim, which also starts at 0. The commands also mean something entirely different than you first thought:
//!
//! down X increases your aim by X units.
//! up X decreases your aim by X units.
//! forward X does two things:
//! It increases your horizontal position by X units.
//! It increases your depth by your aim multiplied by X.
//! Again note that since you're on a submarine, down and up do the opposite of what you might expect: "down" means aiming in the positive direction.
//!
//! Now, the above example does something different:
//!
//! forward 5 adds 5 to your horizontal position, a total of 5. Because your aim is 0, your depth does not change.
//! down 5 adds 5 to your aim, resulting in a value of 5.
//! forward 8 adds 8 to your horizontal position, a total of 13. Because your aim is 5, your depth increases by 8*5=40.
//! up 3 decreases your aim by 3, resulting in a value of 2.
//! down 8 adds 8 to your aim, resulting in a value of 10.
//! forward 2 adds 2 to your horizontal position, a total of 15. Because your aim is 10, your depth increases by 2*10=20 to a total of 60.
//! After following these new instructions, you would have a horizontal position of 15 and a depth of 60. (Multiplying these produces 900.)
//!
//! Using this new interpretation of the commands, calculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth?
use anyhow::Result;
use aoc_runner_derive::aoc;
#[aoc(day2, part1)]
fn part1(input: &str) -> Result<i32> {
let mut horizontal: i32 = 0;
let mut depth: i32 = 0;
for l in input.split('\n') {
let p: Vec<_> = l.split(' ').collect();
match p[0] {
"forward" => horizontal += p[1].parse::<i32>()?,
"up" => depth -= p[1].parse::<i32>()?,
"down" => depth += p[1].parse::<i32>()?,
_ => panic!("unknown command {}", p[0]),
}
}
Ok(horizontal * depth)
}
#[aoc(day2, part2)]
fn part2(input: &str) -> Result<i32> {
let mut horizontal: i32 = 0;
let mut depth: i32 = 0;
let mut aim: i32 = 0;
for l in input.split('\n') {
let p: Vec<_> = l.split(' ').collect();
match p[0] {
"forward" => {
let v = p[1].parse::<i32>()?;
horizontal += v;
depth += v * aim;
}
"up" => aim -= p[1].parse::<i32>()?,
"down" => aim += p[1].parse::<i32>()?,
_ => panic!("unknown command {}", p[0]),
}
}
Ok(horizontal * depth)
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"
forward 5
down 5
forward 8
up 3
down 8
forward 2
"#
.trim();
assert_eq!(part1(input)?, 150);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
forward 5
down 5
forward 8
up 3
down 8
forward 2
"#
.trim();
assert_eq!(part2(input)?, 900);
Ok(())
}

199
2021/src/day20.rs Normal file
View File

@@ -0,0 +1,199 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
use std::ops::RangeInclusive;
struct Image(HashSet<(isize, isize)>);
impl Image {
fn new(input: &str) -> Image {
let rows: Vec<_> = input.lines().collect();
let width = rows[0].len();
Image(
rows.iter()
.flat_map(|row| row.as_bytes().iter())
.enumerate()
.filter(|(_i, b)| *b == &b'#')
.map(|(i, _b)| ((i % width) as isize, (i / width) as isize))
.collect(),
)
}
fn lookup(
&self,
x: isize,
y: isize,
algo: &[bool],
odd: bool,
x_rng: &RangeInclusive<isize>,
y_rng: &RangeInclusive<isize>,
) -> usize {
assert_eq!(algo.len(), 512);
let mut idx = 0;
for y_off in -1..=1 {
for x_off in -1..=1 {
let x_idx = x + x_off;
let y_idx = y + y_off;
let out_of_bounds = !(x_rng.contains(&x_idx) && y_rng.contains(&y_idx));
let val = if (odd && out_of_bounds && algo[0]) || self.0.contains(&(x_idx, y_idx)) {
1
} else {
0
};
idx <<= 1;
idx |= val;
}
}
idx
}
fn extents(&self) -> (isize, isize, isize, isize) {
self.0.iter().fold(
(isize::MAX, isize::MIN, isize::MAX, isize::MIN),
|(min_x, max_x, min_y, max_y), (x, y)| {
(min_x.min(*x), max_x.max(*x), min_y.min(*y), max_y.max(*y))
},
)
}
fn enhance(&self, algo: &[bool], odd: bool) -> Image {
let (min_x, max_x, min_y, max_y) = self.extents();
let x_rng = min_x..=max_x;
let y_rng = min_y..=max_y;
let mut new_im = HashSet::new();
for y in min_y - 1..=max_y + 1 {
for x in min_x - 1..=max_x + 1 {
let idx = self.lookup(x, y, algo, odd, &x_rng, &y_rng);
if algo[idx] {
new_im.insert((x, y));
}
}
}
Image(new_im)
}
fn lights(&self) -> usize {
self.0.len()
}
fn crop(&self, min_x: isize, max_x: isize, min_y: isize, max_y: isize) -> Image {
let x_rng = min_x..=max_x;
let y_rng = min_y..=max_y;
Image(
self.0
.iter()
.filter(|(x, y)| x_rng.contains(x) && y_rng.contains(y))
.cloned()
.collect(),
)
}
}
impl Debug for Image {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
let (min_x, max_x, min_y, max_y) = self.extents();
writeln!(f, "({}..{})x({}..{})", min_x, max_x, min_y, max_y)?;
for y in min_y..=max_y {
for x in min_x..=max_x {
if self.0.contains(&(x, y)) {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
}
writeln!(f)?;
}
Ok(())
}
}
fn process(im: Image, algo: &[bool], num_steps: isize) -> Image {
let mut im = im;
for step in 0..num_steps {
let (min_x, max_x, min_y, max_y) = im.extents();
im = im.enhance(algo, step % 2 == 1);
im = im.crop(min_x - 1, max_x + 1, min_y - 1, max_y + 1)
}
im
}
#[aoc(day20, part1)]
fn part1(input: &str) -> Result<usize> {
let (algo, im) = input.split_once("\n\n").unwrap();
let im = Image::new(im);
let algo: Vec<bool> = algo.as_bytes().iter().map(|c| c == &b'#').collect();
let im = process(im, &algo, 2);
dbg!(&im, im.lights());
let answer = im.lights();
assert!(answer == 5268 || answer == 35);
Ok(answer)
}
#[aoc(day20, part2)]
fn part2(input: &str) -> Result<usize> {
let (algo, im) = input.split_once("\n\n").unwrap();
let im = Image::new(im);
let algo: Vec<bool> = algo.as_bytes().iter().map(|c| c == &b'#').collect();
let im = process(im, &algo, 50);
dbg!(&im, im.lights());
let answer = im.lights();
assert!(answer < 19245);
Ok(answer)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn lookup() -> Result<()> {
let input = r#"
..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
#..#.
#....
##..#
..#..
..###
"#
.trim();
let (algo, im) = input.split_once("\n\n").unwrap();
let im = Image::new(im);
let algo: Vec<bool> = algo.as_bytes().iter().map(|c| c == &b'#').collect();
let (min_x, max_x, min_y, max_y) = im.extents();
assert_eq!(
im.lookup(2, 2, &algo, false, &(min_x..=max_x), &(min_y..=max_y)),
34,
);
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"
..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
#..#.
#....
##..#
..#..
..###
"#
.trim();
assert_eq!(part1(input)?, 35);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
#..#.
#....
##..#
..#..
..###
"#
.trim();
assert_eq!(part2(input)?, 3351);
Ok(())
}
}

171
2021/src/day21.rs Normal file
View File

@@ -0,0 +1,171 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
#[derive(Copy, Clone, Debug)]
struct Player {
tally: usize,
score: usize,
}
impl Player {
fn space(&self) -> usize {
(self.tally % 10) + 1
}
}
#[derive(Debug, Default)]
struct Die {
roll_count: usize,
}
impl Die {
fn roll(&mut self) -> usize {
let val = (self.roll_count % 100) + 1;
self.roll_count += 1;
val
}
}
fn take_turn(p: &mut Player, die: &mut Die) -> bool {
p.tally += die.roll() + die.roll() + die.roll();
p.score += p.space();
if p.score >= 1000 {
return true;
}
false
}
#[aoc(day21, part1)]
fn part1(input: &str) -> Result<usize> {
let mut p: Vec<_> = input
.lines()
.map(|l| l.split_once(": ").unwrap())
.map(|(_, space)| space.parse().expect("couldn't parse starting spaceition"))
.map(|space: usize| Player {
tally: space - 1,
score: 0,
})
.collect();
let mut die = Die::default();
loop {
if take_turn(&mut p[0], &mut die) {
return Ok(die.roll_count * p[1].score);
}
//println!( "Player 1 space {} for a total score of {}.", p[0].space(), p[0].score);
if take_turn(&mut p[1], &mut die) {
return Ok(die.roll_count * p[0].score);
}
//println!( "Player 2 space {} for a total score of {}.", p[1].space(), p[1].score);
}
}
fn play_part2(p1: Player, p2: Player) -> (usize, usize) {
fn play_part2_rec(
mut p1: Player,
mut p2: Player,
r1: usize,
r2: usize,
r3: usize,
r4: usize,
r5: usize,
r6: usize,
) -> (usize, usize) {
//println!( "p1 {} {} p2 {} {} die {} {} {} {} {} {}", p1.score, p1.space(), p2.score, p2.space(), r1, r2, r3, r4, r5, r6,);
p1.tally += r1 + r2 + r3;
p1.score += p1.space();
if p1.score >= 21 {
return (1, 0);
}
p2.tally += r4 + r5 + r6;
p2.score += p2.space();
if p2.score >= 21 {
return (0, 1);
}
let mut p1_score = 0;
let mut p2_score = 0;
for i in [1, 2, 3] {
for j in [1, 2, 3] {
for k in [1, 2, 3] {
for x in [1, 2, 3] {
for y in [1, 2, 3] {
for z in [1, 2, 3] {
let (p1s, p2s) = play_part2_rec(p1, p2, i, j, k, x, y, z);
p1_score += p1s;
p2_score += p2s;
}
}
}
}
}
}
(p1_score, p2_score)
}
let mut p1_score = 0;
let mut p2_score = 0;
for i in [1, 2, 3] {
for j in [1, 2, 3] {
for k in [1, 2, 3] {
for x in [1, 2, 3] {
for y in [1, 2, 3] {
for z in [1, 2, 3] {
let (p1s, p2s) = play_part2_rec(p1, p2, i, j, k, x, y, z);
p1_score += p1s;
p2_score += p2s;
println!("Running score {} vs {}", p1_score, p2_score);
}
}
}
}
}
}
(p1_score, p2_score)
}
//#[aoc(day21, part2)]
fn part2(input: &str) -> Result<usize> {
let p: Vec<_> = input
.lines()
.map(|l| l.split_once(": ").unwrap())
.map(|(_, space)| space.parse().expect("couldn't parse starting spaceition"))
.map(|space: usize| Player {
tally: space - 1,
score: 0,
})
.collect();
let (p1_wins, p2_wins) = play_part2(p[0], p[1]);
Ok(if p1_wins > p2_wins { p1_wins } else { p2_wins })
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
Player 1 starting position: 4
Player 2 starting position: 8
"#
.trim();
assert_eq!(part1(input)?, 739785);
Ok(())
}
//#[test]
fn test_part2() -> Result<()> {
let input = r#"
Player 1 starting position: 4
Player 2 starting position: 8
"#
.trim();
assert_eq!(part2(input)?, 444356092776315);
Ok(())
}
}

214
2021/src/day22.rs Normal file
View File

@@ -0,0 +1,214 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
#[derive(Debug)]
struct Instruction {
on: bool,
x_rng: RangeInclusive<i64>,
y_rng: RangeInclusive<i64>,
z_rng: RangeInclusive<i64>,
}
impl FromStr for Instruction {
type Err = Infallible;
fn from_str(input: &str) -> std::result::Result<Instruction, Infallible> {
// on x=11..13,y=11..13,z=11..13
// off x=9..11,y=9..11,z=9..11
let (verb, rest) = input.split_once(' ').unwrap();
let on = match verb {
"on" => true,
"off" => false,
_ => unreachable!("unexpected instruction type"),
};
let parts: Vec<_> = rest.split(',').collect();
let parse_rng = |s: &str| -> RangeInclusive<i64> {
s.split_once('=')
.unwrap()
.1
.split_once("..")
.map(|(lo, hi)| (lo.parse().unwrap(), hi.parse().unwrap()))
.map(|(lo, hi)| lo..=hi)
.unwrap()
};
let x_rng = parse_rng(parts[0]);
let y_rng = parse_rng(parts[1]);
let z_rng = parse_rng(parts[2]);
Ok(Instruction {
on,
x_rng,
y_rng,
z_rng,
})
}
}
fn part1_apply(insts: Vec<Instruction>) -> usize {
let mut grid = HashSet::new();
for inst in &insts {
dbg!(&inst);
for x in inst.x_rng.clone() {
for y in inst.y_rng.clone() {
for z in inst.z_rng.clone() {
if inst.on {
grid.insert((x, y, z));
} else {
grid.remove(&(x, y, z));
}
}
}
}
}
grid.len()
}
fn inbounds(r: &RangeInclusive<i64>) -> bool {
// lazy but good enough for part1
r.start().abs() <= 50
}
#[aoc(day22, part1)]
fn part1(input: &str) -> Result<usize> {
let insts: Vec<Instruction> = input
.lines()
.map(|l| l.parse().expect("failed to parse instruction"))
.filter(|i: &Instruction| inbounds(&i.x_rng) && inbounds(&i.y_rng) && inbounds(&i.z_rng))
.collect();
dbg!(&insts);
Ok(part1_apply(insts))
}
//#[aoc(day22, part2)]
fn part2(input: &str) -> Result<usize> {
let insts: Vec<Instruction> = input
.lines()
.map(|l| l.parse().expect("failed to parse instruction"))
.collect();
dbg!(&insts);
for i in insts {
if i.x_rng.end()
- i.x_rng.start() * i.y_rng.end()
- i.y_rng.start() * i.z_rng.end()
- i.z_rng.start()
== 2758514936282235
{
println!("magic instructions {:?}", i)
}
}
Ok(0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
on x=10..12,y=10..12,z=10..12
on x=11..13,y=11..13,z=11..13
off x=9..11,y=9..11,z=9..11
on x=10..10,y=10..10,z=10..10
"#
.trim();
assert_eq!(part1(input)?, 39);
let input = r#"
on x=-20..26,y=-36..17,z=-47..7
on x=-20..33,y=-21..23,z=-26..28
on x=-22..28,y=-29..23,z=-38..16
on x=-46..7,y=-6..46,z=-50..-1
on x=-49..1,y=-3..46,z=-24..28
on x=2..47,y=-22..22,z=-23..27
on x=-27..23,y=-28..26,z=-21..29
on x=-39..5,y=-6..47,z=-3..44
on x=-30..21,y=-8..43,z=-13..34
on x=-22..26,y=-27..20,z=-29..19
off x=-48..-32,y=26..41,z=-47..-37
on x=-12..35,y=6..50,z=-50..-2
off x=-48..-32,y=-32..-16,z=-15..-5
on x=-18..26,y=-33..15,z=-7..46
off x=-40..-22,y=-38..-28,z=23..41
on x=-16..35,y=-41..10,z=-47..6
off x=-32..-23,y=11..30,z=-14..3
on x=-49..-5,y=-3..45,z=-29..18
off x=18..30,y=-20..-8,z=-3..13
on x=-41..9,y=-7..43,z=-33..15
on x=-54112..-39298,y=-85059..-49293,z=-27449..7877
on x=967..23432,y=45373..81175,z=27513..53682
"#
.trim();
assert_eq!(part1(input)?, 590784);
Ok(())
}
//#[test]
fn test_part2() -> Result<()> {
let input = r#"
on x=-5..47,y=-31..22,z=-19..33
on x=-44..5,y=-27..21,z=-14..35
on x=-49..-1,y=-11..42,z=-10..38
on x=-20..34,y=-40..6,z=-44..1
off x=26..39,y=40..50,z=-2..11
on x=-41..5,y=-41..6,z=-36..8
off x=-43..-33,y=-45..-28,z=7..25
on x=-33..15,y=-32..19,z=-34..11
off x=35..47,y=-46..-34,z=-11..5
on x=-14..36,y=-6..44,z=-16..29
on x=-57795..-6158,y=29564..72030,z=20435..90618
on x=36731..105352,y=-21140..28532,z=16094..90401
on x=30999..107136,y=-53464..15513,z=8553..71215
on x=13528..83982,y=-99403..-27377,z=-24141..23996
on x=-72682..-12347,y=18159..111354,z=7391..80950
on x=-1060..80757,y=-65301..-20884,z=-103788..-16709
on x=-83015..-9461,y=-72160..-8347,z=-81239..-26856
on x=-52752..22273,y=-49450..9096,z=54442..119054
on x=-29982..40483,y=-108474..-28371,z=-24328..38471
on x=-4958..62750,y=40422..118853,z=-7672..65583
on x=55694..108686,y=-43367..46958,z=-26781..48729
on x=-98497..-18186,y=-63569..3412,z=1232..88485
on x=-726..56291,y=-62629..13224,z=18033..85226
on x=-110886..-34664,y=-81338..-8658,z=8914..63723
on x=-55829..24974,y=-16897..54165,z=-121762..-28058
on x=-65152..-11147,y=22489..91432,z=-58782..1780
on x=-120100..-32970,y=-46592..27473,z=-11695..61039
on x=-18631..37533,y=-124565..-50804,z=-35667..28308
on x=-57817..18248,y=49321..117703,z=5745..55881
on x=14781..98692,y=-1341..70827,z=15753..70151
on x=-34419..55919,y=-19626..40991,z=39015..114138
on x=-60785..11593,y=-56135..2999,z=-95368..-26915
on x=-32178..58085,y=17647..101866,z=-91405..-8878
on x=-53655..12091,y=50097..105568,z=-75335..-4862
on x=-111166..-40997,y=-71714..2688,z=5609..50954
on x=-16602..70118,y=-98693..-44401,z=5197..76897
on x=16383..101554,y=4615..83635,z=-44907..18747
off x=-95822..-15171,y=-19987..48940,z=10804..104439
on x=-89813..-14614,y=16069..88491,z=-3297..45228
on x=41075..99376,y=-20427..49978,z=-52012..13762
on x=-21330..50085,y=-17944..62733,z=-112280..-30197
on x=-16478..35915,y=36008..118594,z=-7885..47086
off x=-98156..-27851,y=-49952..43171,z=-99005..-8456
off x=2032..69770,y=-71013..4824,z=7471..94418
on x=43670..120875,y=-42068..12382,z=-24787..38892
off x=37514..111226,y=-45862..25743,z=-16714..54663
off x=25699..97951,y=-30668..59918,z=-15349..69697
off x=-44271..17935,y=-9516..60759,z=49131..112598
on x=-61695..-5813,y=40978..94975,z=8655..80240
off x=-101086..-9439,y=-7088..67543,z=33935..83858
off x=18020..114017,y=-48931..32606,z=21474..89843
off x=-77139..10506,y=-89994..-18797,z=-80..59318
off x=8476..79288,y=-75520..11602,z=-96624..-24783
on x=-47488..-1262,y=24338..100707,z=16292..72967
off x=-84341..13987,y=2429..92914,z=-90671..-1318
off x=-37810..49457,y=-71013..-7894,z=-105357..-13188
off x=-27365..46395,y=31009..98017,z=15428..76570
off x=-70369..-16548,y=22648..78696,z=-1892..86821
on x=-53470..21291,y=-120233..-33476,z=-44150..38147
off x=-93533..-4276,y=-16170..68771,z=-104985..-24507
"#
.trim();
assert_eq!(part2(input)?, 2758514936282235);
Ok(())
}
}

41
2021/src/day23.rs Normal file
View File

@@ -0,0 +1,41 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
#[aoc(day23, part1)]
fn part1(input: &str) -> Result<usize> {
todo!("part1");
Ok(0)
}
/*
#[aoc(day23, part2)]
fn part2(input: &str) -> Result<usize> {
todo!("part2");
Ok(0)
}
*/
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part1(input)?, usize::MAX);
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part2(input)?, usize::MAX);
Ok(())
}
*/
}

198
2021/src/day3.rs Normal file
View File

@@ -0,0 +1,198 @@
//! --- Day 3: Binary Diagnostic ---
//! The submarine has been making some odd creaking noises, so you ask it to produce a diagnostic report just in case.
//!
//! The diagnostic report (your puzzle input) consists of a list of binary numbers which, when decoded properly, can tell you many useful things about the conditions of the submarine. The first parameter to check is the power consumption.
//!
//! You need to use the binary numbers in the diagnostic report to generate two new binary numbers (called the gamma rate and the epsilon rate). The power consumption can then be found by multiplying the gamma rate by the epsilon rate.
//!
//! Each bit in the gamma rate can be determined by finding the most common bit in the corresponding position of all numbers in the diagnostic report. For example, given the following diagnostic report:
//!
//! 00100
//! 11110
//! 10110
//! 10111
//! 10101
//! 01111
//! 00111
//! 11100
//! 10000
//! 11001
//! 00010
//! 01010
//! Considering only the first bit of each number, there are five 0 bits and seven 1 bits. Since the most common bit is 1, the first bit of the gamma rate is 1.
//!
//! The most common second bit of the numbers in the diagnostic report is 0, so the second bit of the gamma rate is 0.
//!
//! The most common value of the third, fourth, and fifth bits are 1, 1, and 0, respectively, and so the final three bits of the gamma rate are 110.
//!
//! So, the gamma rate is the binary number 10110, or 22 in decimal.
//!
//! The epsilon rate is calculated in a similar way; rather than use the most common bit, the least common bit from each position is used. So, the epsilon rate is 01001, or 9 in decimal. Multiplying the gamma rate (22) by the epsilon rate (9) produces the power consumption, 198.
//!
//! Use the binary numbers in your diagnostic report to calculate the gamma rate and epsilon rate, then multiply them together. What is the power consumption of the submarine? (Be sure to represent your answer in decimal, not binary.)
//!
//! --- Part Two ---
//! Next, you should verify the life support rating, which can be determined by multiplying the oxygen generator rating by the CO2 scrubber rating.
//!
//! Both the oxygen generator rating and the CO2 scrubber rating are values that can be found in your diagnostic report - finding them is the tricky part. Both values are located using a similar process that involves filtering out values until only one remains. Before searching for either rating value, start with the full list of binary numbers from your diagnostic report and consider just the first bit of those numbers. Then:
//!
//! Keep only numbers selected by the bit criteria for the type of rating value for which you are searching. Discard numbers which do not match the bit criteria.
//! If you only have one number left, stop; this is the rating value for which you are searching.
//! Otherwise, repeat the process, considering the next bit to the right.
//! The bit criteria depends on which type of rating value you want to find:
//!
//! To find oxygen generator rating, determine the most common value (0 or 1) in the current bit position, and keep only numbers with that bit in that position. If 0 and 1 are equally common, keep values with a 1 in the position being considered.
//! To find CO2 scrubber rating, determine the least common value (0 or 1) in the current bit position, and keep only numbers with that bit in that position. If 0 and 1 are equally common, keep values with a 0 in the position being considered.
//! For example, to determine the oxygen generator rating value using the same example diagnostic report from above:
//!
//! Start with all 12 numbers and consider only the first bit of each number. There are more 1 bits (7) than 0 bits (5), so keep only the 7 numbers with a 1 in the first position: 11110, 10110, 10111, 10101, 11100, 10000, and 11001.
//! Then, consider the second bit of the 7 remaining numbers: there are more 0 bits (4) than 1 bits (3), so keep only the 4 numbers with a 0 in the second position: 10110, 10111, 10101, and 10000.
//! In the third position, three of the four numbers have a 1, so keep those three: 10110, 10111, and 10101.
//! In the fourth position, two of the three numbers have a 1, so keep those two: 10110 and 10111.
//! In the fifth position, there are an equal number of 0 bits and 1 bits (one each). So, to find the oxygen generator rating, keep the number with a 1 in that position: 10111.
//! As there is only one number left, stop; the oxygen generator rating is 10111, or 23 in decimal.
//! Then, to determine the CO2 scrubber rating value from the same example above:
//!
//! Start again with all 12 numbers and consider only the first bit of each number. There are fewer 0 bits (5) than 1 bits (7), so keep only the 5 numbers with a 0 in the first position: 00100, 01111, 00111, 00010, and 01010.
//! Then, consider the second bit of the 5 remaining numbers: there are fewer 1 bits (2) than 0 bits (3), so keep only the 2 numbers with a 1 in the second position: 01111 and 01010.
//! In the third position, there are an equal number of 0 bits and 1 bits (one each). So, to find the CO2 scrubber rating, keep the number with a 0 in that position: 01010.
//! As there is only one number left, stop; the CO2 scrubber rating is 01010, or 10 in decimal.
//! Finally, to find the life support rating, multiply the oxygen generator rating (23) by the CO2 scrubber rating (10) to get 230.
//!
//! Use the binary numbers in your diagnostic report to calculate the oxygen generator rating and CO2 scrubber rating, then multiply them together. What is the life support rating of the submarine? (Be sure to represent your answer in decimal, not binary.)
use std::fmt::{Debug, Error, Formatter};
use anyhow::Result;
use aoc_runner_derive::aoc;
#[aoc(day3, part1)]
fn part1(input: &str) -> Result<u64> {
let lines: Vec<_> = input.trim().split('\n').collect();
let num_bits = lines[0].len();
let majority = lines.len() / 2;
let mut bits = vec![0; num_bits];
lines.iter().for_each(|l| {
for (i, c) in l.chars().enumerate() {
if c == '1' {
bits[i] += 1;
}
}
});
let mut gamma: u64 = 0;
for (i, &b) in bits.iter().rev().enumerate() {
if b > majority {
gamma |= 1 << i;
}
}
let mask = (1 << (num_bits)) - 1;
let epsilon = (!gamma) & mask;
Ok(epsilon * gamma)
}
fn oxygen(nums: &[u64], num_bits: usize) -> u64 {
partition(nums, num_bits - 1, Partition::Oxygen)
}
fn co2(nums: &[u64], num_bits: usize) -> u64 {
partition(nums, num_bits - 1, Partition::CO2)
}
#[derive(Copy, Clone, Debug)]
enum Partition {
Oxygen,
CO2,
}
struct Binaries<'a>(&'a [u64]);
impl<'a> Debug for Binaries<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f, "[")?;
for n in self.0.iter() {
writeln!(f, " 0b{:08b},", n)?;
}
writeln!(f, "]")?;
Ok(())
}
}
fn partition(nums: &[u64], bit_offset: usize, partition_type: Partition) -> u64 {
let (one, zero): (Vec<u64>, Vec<u64>) =
nums.iter().partition(|n| (*n & (1 << bit_offset)) != 0);
let remainder = match partition_type {
Partition::Oxygen => {
if one.len() >= zero.len() {
one
} else {
zero
}
}
Partition::CO2 => {
if one.len() >= zero.len() {
zero
} else {
one
}
}
};
if remainder.len() == 1 {
return remainder[0];
}
partition(&remainder, bit_offset - 1, partition_type)
}
#[aoc(day3, part2)]
fn part2(input: &str) -> Result<u64> {
let lines: Vec<_> = input.trim().split('\n').collect();
let nums: Vec<_> = lines
.iter()
.map(|s| u64::from_str_radix(s, 2))
.collect::<Result<_, std::num::ParseIntError>>()?;
let num_bits = lines[0].chars().count();
let o = oxygen(&nums, num_bits);
let c = co2(&nums, num_bits);
Ok(o * c)
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010
"#
.trim();
assert_eq!(part1(input)?, 198);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010
"#
.trim();
assert_eq!(part2(input)?, 230);
Ok(())
}

369
2021/src/day4.rs Normal file
View File

@@ -0,0 +1,369 @@
//! --- Day 4: Giant Squid ---
//! You're already almost 1.5km (almost a mile) below the surface of the ocean, already so deep that you can't see any sunlight. What you can see, however, is a giant squid that has attached itself to the outside of your submarine.
//!
//! Maybe it wants to play bingo?
//!
//! Bingo is played on a set of boards each consisting of a 5x5 grid of numbers. Numbers are chosen at random, and the chosen number is marked on all boards on which it appears. (Numbers may not appear on all boards.) If all numbers in any row or any column of a board are marked, that board wins. (Diagonals don't count.)
//!
//! The submarine has a bingo subsystem to help passengers (currently, you and the giant squid) pass the time. It automatically generates a random order in which to draw numbers and a random set of boards (your puzzle input). For example:
//!
//! 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
//!
//! 22 13 17 11 0
//! 8 2 23 4 24
//! 21 9 14 16 7
//! 6 10 3 18 5
//! 1 12 20 15 19
//!
//! 3 15 0 2 22
//! 9 18 13 17 5
//! 19 8 7 25 23
//! 20 11 10 24 4
//! 14 21 16 12 6
//!
//! 14 21 17 24 4
//! 10 16 15 9 19
//! 18 8 23 26 20
//! 22 11 13 6 5
//! 2 0 12 3 7
//! After the first five numbers are drawn (7, 4, 9, 5, and 11), there are no winners, but the boards are marked as follows (shown here adjacent to each other to save space):
//!
//! 22 13 17 11 0 3 15 0 2 22 14 21 17 24 4
//! 8 2 23 4 24 9 18 13 17 5 10 16 15 9 19
//! 21 9 14 16 7 19 8 7 25 23 18 8 23 26 20
//! 6 10 3 18 5 20 11 10 24 4 22 11 13 6 5
//! 1 12 20 15 19 14 21 16 12 6 2 0 12 3 7
//! After the next six numbers are drawn (17, 23, 2, 0, 14, and 21), there are still no winners:
//!
//! 22 13 17 11 0 3 15 0 2 22 14 21 17 24 4
//! 8 2 23 4 24 9 18 13 17 5 10 16 15 9 19
//! 21 9 14 16 7 19 8 7 25 23 18 8 23 26 20
//! 6 10 3 18 5 20 11 10 24 4 22 11 13 6 5
//! 1 12 20 15 19 14 21 16 12 6 2 0 12 3 7
//! Finally, 24 is drawn:
//!
//! 22 13 17 11 0 3 15 0 2 22 14 21 17 24 4
//! 8 2 23 4 24 9 18 13 17 5 10 16 15 9 19
//! 21 9 14 16 7 19 8 7 25 23 18 8 23 26 20
//! 6 10 3 18 5 20 11 10 24 4 22 11 13 6 5
//! 1 12 20 15 19 14 21 16 12 6 2 0 12 3 7
//! At this point, the third board wins because it has at least one complete row or column of marked numbers (in this case, the entire top row is marked: 14 21 17 24 4).
//!
//! The score of the winning board can now be calculated. Start by finding the sum of all unmarked numbers on that board; in this case, the sum is 188. Then, multiply that sum by the number that was just called when the board won, 24, to get the final score, 188 * 24 = 4512.
//!
//! To guarantee victory against the giant squid, figure out which board will win first. What will your final score be if you choose that board?
//!
//! --- Part Two ---
//! On the other hand, it might be wise to try a different strategy: let the giant squid win.
//!
//! You aren't sure how many bingo boards a giant squid could play at once, so rather than waste time counting its arms, the safe thing to do is to figure out which board will win last and choose that one. That way, no matter which boards it picks, it will win for sure.
//!
//! In the above example, the second board is the last to win, which happens after 13 is eventually called and its middle column is completely marked. If you were to keep playing until this point, the second board would have a sum of unmarked numbers equal to 148 for a final score of 148 * 13 = 1924.
//!
//! Figure out which board will win last. Once it wins, what would its final score be?
use std::{
collections::{HashMap, HashSet},
fmt::{Debug, Error, Formatter},
num::ParseIntError,
str::FromStr,
};
use ansi_term::Color::Green;
use anyhow::Result;
use aoc_runner_derive::aoc;
use thiserror::Error;
#[derive(Debug, Default)]
struct Game {
numbers: Vec<u64>,
boards: Vec<Board>,
skip_boards: HashSet<usize>,
}
#[derive(Debug, Error)]
enum GameError {
#[error("couldn't parse number {0}")]
ParseIntError(#[from] ParseIntError),
#[error("couldn't parse board {0}")]
BoardError(#[from] BoardError),
}
impl Game {
// If return not None, it contains a winning board
fn apply_number(&mut self, number: u64) -> Option<&Board> {
for b in &mut self.boards {
b.mark(number);
if b.is_bingo() {
return Some(b);
}
}
None
}
// If return not None, it contains a winning board. This will remove winning boards until only
// one remains.
fn apply_number_part2(&mut self, number: u64) -> Option<&Board> {
let num_boards = self.boards.len();
for (idx, b) in self.boards.iter_mut().enumerate() {
if self.skip_boards.contains(&idx) {
continue;
}
b.mark(number);
if b.is_bingo() {
self.skip_boards.insert(idx);
if self.skip_boards.len() == num_boards {
return Some(b);
}
}
}
None
}
}
impl FromStr for Game {
type Err = GameError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut it = s.split("\n\n");
let numbers = it
.next()
.unwrap()
.split(',')
.map(|s| s.parse())
.collect::<Result<_, ParseIntError>>()?;
let boards: Vec<_> = it.map(|s| s.parse()).collect::<Result<_, BoardError>>()?;
Ok(Game {
numbers,
boards,
skip_boards: Default::default(),
})
}
}
#[derive(Default)]
struct MarkerBoard(u32);
impl MarkerBoard {
fn mark(&mut self, (x, y): (usize, usize)) {
let bit = 1 << (x + y * 5);
self.0 |= bit;
}
fn is_marked(&self, (x, y): (usize, usize)) -> bool {
let bit = 1 << (x + y * 5);
(self.0 & bit) != 0
}
fn is_bingo(&self) -> bool {
let h = 0b11111;
#[allow(clippy::unusual_byte_groupings)]
let v = 0b00001_00001_00001_00001_00001;
let m = self.0;
// Bingo horizontally
(m & h == h)
|| ((m >> 5 & h) == h)
|| ((m >> 10 & h) == h)
|| ((m >> 15 & h) == h)
|| ((m >> 20 & h) == h)
// Bingo vertically
|| ((m & v) == v)
|| ((m >> 1 & v) == v)
|| ((m >> 2 & v) == v)
|| ((m >> 3 & v) == v)
|| ((m >> 4 & v) == v)
}
}
#[derive(Default)]
struct Board {
numbers: HashMap<(usize, usize), u64>,
marked: MarkerBoard,
}
#[derive(Debug, Error)]
enum BoardError {
#[error("couldn't parse number {0}")]
ParseIntError(#[from] ParseIntError),
}
impl Board {
fn is_bingo(&self) -> bool {
self.marked.is_bingo()
}
fn sum_uncovered(&self) -> u64 {
self.numbers
.iter()
.map(|((x, y), v)| {
if !self.marked.is_marked((*x, *y)) {
*v
} else {
0
}
})
.sum()
}
// Returns true if board has num.
fn mark(&mut self, num: u64) -> bool {
for ((x, y), v) in self.numbers.iter() {
if *v == num {
self.marked.mark((*x, *y));
return true;
}
}
false
}
}
impl Debug for Board {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f)?;
for y in 0..5 {
for x in 0..5 {
if self.marked.is_marked((x, y)) {
let v = format!("{:3}", self.numbers[&(x, y)]);
write!(f, "{}", Green.bold().paint(v))?;
} else {
write!(f, "{:3}", self.numbers[&(x, y)])?;
}
}
writeln!(f)?;
}
Ok(())
}
}
impl FromStr for Board {
type Err = BoardError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let numbers: Vec<Vec<_>> = s
.split('\n')
.map(|l| {
l.split(' ')
// Remove the double space that happens before single digit cells.
.filter(|c| !c.is_empty())
.map(|c| c.parse())
.collect::<Result<_, ParseIntError>>()
})
.collect::<Result<_, ParseIntError>>()?;
let numbers: HashMap<_, _> = numbers
.iter()
.enumerate()
.flat_map(|(y, row)| row.iter().enumerate().map(move |(x, c)| ((x, y), *c)))
.collect();
Ok(Board {
numbers,
marked: Default::default(),
})
}
}
#[aoc(day4, part1)]
fn part1(input: &str) -> Result<u64> {
let mut g: Game = input.parse()?;
let numbers = g.numbers.clone();
for n in numbers {
if let Some(b) = g.apply_number(n) {
//println!("winning board {:?}", b);
return Ok(n as u64 * b.sum_uncovered());
}
}
unreachable!("We should have had a winner by now");
}
#[aoc(day4, part2)]
fn part2(input: &str) -> Result<u64> {
let mut g: Game = input.parse()?;
let numbers = g.numbers.clone();
for n in numbers {
if let Some(b) = g.apply_number_part2(n) {
//println!("winning board {:?}", b);
return Ok(n as u64 * b.sum_uncovered());
}
}
unreachable!("We should have had a winner by now");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_board() -> Result<()> {
let input = r#"
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7
"#
.trim();
let mut b = Board::from_str(input)?;
assert!(!b.is_bingo());
assert!(!b.mark(100));
for num in &[7, 4, 9, 5, 11, 17, 23, 2, 0, 14, 21, 24] {
assert!(b.mark(*num));
}
assert!(b.is_bingo());
assert_eq!(b.sum_uncovered(), 188);
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7
"#
.trim();
assert_eq!(part1(input)?, 4512);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7
"#
.trim();
assert_eq!(part2(input)?, 1924);
Ok(())
}
}

309
2021/src/day5.rs Normal file
View File

@@ -0,0 +1,309 @@
//!
//! --- Day 5: Hydrothermal Venture ---
//! You come across a field of hydrothermal vents on the ocean floor! These vents constantly produce large, opaque clouds, so it would be best to avoid them if possible.
//!
//! They tend to form in lines; the submarine helpfully produces a list of nearby lines of vents (your puzzle input) for you to review. For example:
//!
//! 0,9 -> 5,9
//! 8,0 -> 0,8
//! 9,4 -> 3,4
//! 2,2 -> 2,1
//! 7,0 -> 7,4
//! 6,4 -> 2,0
//! 0,9 -> 2,9
//! 3,4 -> 1,4
//! 0,0 -> 8,8
//! 5,5 -> 8,2
//! Each line of vents is given as a line segment in the format x1,y1 -> x2,y2 where x1,y1 are the coordinates of one end the line segment and x2,y2 are the coordinates of the other end. These line segments include the points at both ends. In other words:
//!
//! An entry like 1,1 -> 1,3 covers points 1,1, 1,2, and 1,3.
//! An entry like 9,7 -> 7,7 covers points 9,7, 8,7, and 7,7.
//! For now, only consider horizontal and vertical lines: lines where either x1 = x2 or y1 = y2.
//!
//! So, the horizontal and vertical lines from the above list would produce the following diagram:
//!
//! .......1..
//! ..1....1..
//! ..1....1..
//! .......1..
//! .112111211
//! ..........
//! ..........
//! ..........
//! ..........
//! 222111....
//! In this diagram, the top left corner is 0,0 and the bottom right corner is 9,9. Each position is shown as the number of lines which cover that point or . if no line covers that point. The top-left pair of 1s, for example, comes from 2,2 -> 2,1; the very bottom row is formed by the overlapping lines 0,9 -> 5,9 and 0,9 -> 2,9.
//!
//! To avoid the most dangerous areas, you need to determine the number of points where at least two lines overlap. In the above example, this is anywhere in the diagram with a 2 or larger - a total of 5 points.
//!
//! Consider only horizontal and vertical lines. At how many points do at least two lines overlap?
//!
//! --- Part Two ---
//! Unfortunately, considering only horizontal and vertical lines doesn't give you the full picture; you need to also consider diagonal lines.
//!
//! Because of the limits of the hydrothermal vent mapping system, the lines in your list will only ever be horizontal, vertical, or a diagonal line at exactly 45 degrees. In other words:
//!
//! An entry like 1,1 -> 3,3 covers points 1,1, 2,2, and 3,3.
//! An entry like 9,7 -> 7,9 covers points 9,7, 8,8, and 7,9.
//! Considering all lines from the above example would now produce the following diagram:
//!
//! 1.1....11.
//! .111...2..
//! ..2.1.111.
//! ...1.2.2..
//! .112313211
//! ...1.2....
//! ..1...1...
//! .1.....1..
//! 1.......1.
//! 222111....
//! You still need to determine the number of points where at least two lines overlap. In the above example, this is still anywhere in the diagram with a 2 or larger - now a total of 12 points.
//!
//! Consider all of the lines. At how many points do at least two lines overlap?
use std::{
fmt::{Debug, Error, Formatter},
num::ParseIntError,
ops::{Index, IndexMut},
str::FromStr,
};
use anyhow::Result;
use aoc_runner_derive::{aoc, aoc_generator};
use thiserror::Error;
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
struct Line {
p0: Point,
p1: Point,
}
#[derive(Debug, Error)]
enum LineError {
#[error("couldn't parse number {0}")]
ParseIntError(#[from] ParseIntError),
#[error("input truncated")]
PrematureEOL,
}
impl Debug for Line {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(
f,
"{},{} -> {},{}",
self.p0.x, self.p0.y, self.p1.x, self.p1.y,
)
}
}
impl FromStr for Line {
type Err = LineError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut it = s.split(' ');
let parse_point = |it: &mut dyn Iterator<Item = &str>| -> Result<Point, LineError> {
let p = it.next().ok_or(LineError::PrematureEOL)?;
let nums: Vec<_> = p
.split(',')
.map(|n| n.parse())
.collect::<Result<_, ParseIntError>>()?;
Ok(Point {
x: nums[0],
y: nums[1],
})
};
let p0 = parse_point(&mut it)?;
let _ = it.next().ok_or(LineError::PrematureEOL)?;
let p1 = parse_point(&mut it)?;
Ok(Line { p0, p1 })
}
}
struct Image {
width: usize,
height: usize,
pixels: Vec<u32>,
}
impl Image {
fn new(width: usize, height: usize) -> Image {
Image {
width,
height,
pixels: vec![0; width * height],
}
}
fn answer(&self) -> u32 {
self.pixels.iter().filter(|&v| *v > 1).count() as u32
}
}
impl Index<(usize, usize)> for Image {
type Output = u32;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
&mut self.pixels[x + y * self.width]
}
}
impl Debug for Image {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f, "({}, {})", self.width, self.height)?;
for y in 0..self.height {
for x in 0..self.width {
let v = self[(x, y)];
if v == 0 {
write!(f, ".")?;
} else {
write!(f, "{}", v)?;
}
}
writeln!(f)?;
}
writeln!(f)?;
Ok(())
}
}
#[aoc_generator(day5)]
fn parse(input: &str) -> Result<Vec<Line>> {
Ok(input
.split('\n')
.map(|l| l.parse())
.collect::<Result<_, LineError>>()?)
}
fn draw(im: &mut Image, l: &Line) {
let dx = l.p1.x - l.p0.x;
let dy = l.p1.y - l.p0.y;
if dx == 0 {
let x = l.p0.x as usize;
let sy = l.p0.y;
let ey = l.p1.y;
let (sy, ey) = if sy > ey { (ey, sy) } else { (sy, ey) };
for y in sy..=ey {
im[(x, y as usize)] += 1;
}
} else if dy == 0 {
let y = l.p0.y as usize;
let sx = l.p0.x;
let ex = l.p1.x;
let (sx, ex) = if sx > ex { (ex, sx) } else { (sx, ex) };
for x in sx..=ex {
im[(x as usize, y)] += 1;
}
} else {
// We only support 45 degree angles.
assert_eq!(dx.abs(), dy.abs());
let dx = dx / dx.abs();
let dy = dy / dy.abs();
let mut x = l.p0.x;
let mut y = l.p0.y;
while x != l.p1.x && y != l.p1.y {
im[(x as usize, y as usize)] += 1;
x += dx;
y += dy;
}
im[(x as usize, y as usize)] += 1;
}
}
#[aoc(day5, part1)]
fn part1(lines: &[Line]) -> Result<u32> {
let width = lines
.iter()
.map(|l| l.p0.x.max(l.p1.x) as usize)
.max()
.expect("couldn't find max width")
+ 1;
let height = lines
.iter()
.map(|l| l.p0.y.max(l.p1.y) as usize)
.max()
.expect("couldn't find max height")
+ 1;
let mut im = Image::new(width, height);
for l in lines
.iter()
.filter(|l| l.p0.x == l.p1.x || l.p0.y == l.p1.y)
{
draw(&mut im, l);
}
Ok(im.answer())
}
#[aoc(day5, part2)]
fn part2(lines: &[Line]) -> Result<u32> {
let width = lines
.iter()
.map(|l| l.p0.x.max(l.p1.x) as usize)
.max()
.expect("couldn't find max width")
+ 1;
let height = lines
.iter()
.map(|l| l.p0.y.max(l.p1.y) as usize)
.max()
.expect("couldn't find max height")
+ 1;
let mut im = Image::new(width, height);
for l in lines {
draw(&mut im, l);
}
Ok(im.answer())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2
"#
.trim();
assert_eq!(part1(&parse(input)?)?, 5);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2
"#
.trim();
assert_eq!(part2(&parse(input)?)?, 12);
Ok(())
}
}

122
2021/src/day6.rs Normal file
View File

@@ -0,0 +1,122 @@
//! --- Day 6: Lanternfish ---
//! The sea floor is getting steeper. Maybe the sleigh keys got carried this way?
//!
//! A massive school of glowing lanternfish swims past. They must spawn quickly to reach such large numbers - maybe exponentially quickly? You should model their growth rate to be sure.
//!
//! Although you know nothing about this specific species of lanternfish, you make some guesses about their attributes. Surely, each lanternfish creates a new lanternfish once every 7 days.
//!
//! However, this process isn't necessarily synchronized between every lanternfish - one lanternfish might have 2 days left until it creates another lanternfish, while another might have 4. So, you can model each fish as a single number that represents the number of days until it creates a new lanternfish.
//!
//! Furthermore, you reason, a new lanternfish would surely need slightly longer before it's capable of producing more lanternfish: two more days for its first cycle.
//!
//! So, suppose you have a lanternfish with an internal timer value of 3:
//!
//! After one day, its internal timer would become 2.
//! After another day, its internal timer would become 1.
//! After another day, its internal timer would become 0.
//! After another day, its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8.
//! After another day, the first lanternfish would have an internal timer of 5, and the second lanternfish would have an internal timer of 7.
//! A lanternfish that creates a new fish resets its timer to 6, not 7 (because 0 is included as a valid timer value). The new lanternfish starts with an internal timer of 8 and does not start counting down until the next day.
//!
//! Realizing what you're trying to do, the submarine automatically produces a list of the ages of several hundred nearby lanternfish (your puzzle input). For example, suppose you were given the following list:
//!
//! 3,4,3,1,2
//! This list means that the first fish has an internal timer of 3, the second fish has an internal timer of 4, and so on until the fifth fish, which has an internal timer of 2. Simulating these fish over several days would proceed as follows:
//!
//! Initial state: 3,4,3,1,2
//! After 1 day: 2,3,2,0,1
//! After 2 days: 1,2,1,6,0,8
//! After 3 days: 0,1,0,5,6,7,8
//! After 4 days: 6,0,6,4,5,6,7,8,8
//! After 5 days: 5,6,5,3,4,5,6,7,7,8
//! After 6 days: 4,5,4,2,3,4,5,6,6,7
//! After 7 days: 3,4,3,1,2,3,4,5,5,6
//! After 8 days: 2,3,2,0,1,2,3,4,4,5
//! After 9 days: 1,2,1,6,0,1,2,3,3,4,8
//! After 10 days: 0,1,0,5,6,0,1,2,2,3,7,8
//! After 11 days: 6,0,6,4,5,6,0,1,1,2,6,7,8,8,8
//! After 12 days: 5,6,5,3,4,5,6,0,0,1,5,6,7,7,7,8,8
//! After 13 days: 4,5,4,2,3,4,5,6,6,0,4,5,6,6,6,7,7,8,8
//! After 14 days: 3,4,3,1,2,3,4,5,5,6,3,4,5,5,5,6,6,7,7,8
//! After 15 days: 2,3,2,0,1,2,3,4,4,5,2,3,4,4,4,5,5,6,6,7
//! After 16 days: 1,2,1,6,0,1,2,3,3,4,1,2,3,3,3,4,4,5,5,6,8
//! After 17 days: 0,1,0,5,6,0,1,2,2,3,0,1,2,2,2,3,3,4,4,5,7,8
//! After 18 days: 6,0,6,4,5,6,0,1,1,2,6,0,1,1,1,2,2,3,3,4,6,7,8,8,8,8
//! Each day, a 0 becomes a 6 and adds a new 8 to the end of the list, while each other number decreases by 1 if it was present at the start of the day.
//!
//! In this example, after 18 days, there are a total of 26 fish. After 80 days, there would be a total of 5934.
//!
//! Find a way to simulate lanternfish. How many lanternfish would there be after 80 days?
//!
//! --- Part Two ---
//! Suppose the lanternfish live forever and have unlimited food and space. Would they take over the entire ocean?
//!
//! After 256 days in the example above, there would be a total of 26984457539 lanternfish!
use std::num::ParseIntError;
use anyhow::Result;
use aoc_runner_derive::aoc;
#[aoc(day6, part1)]
fn part1(input: &str) -> Result<usize> {
let mut fish = input
.split(',')
.map(|s| s.parse())
.collect::<Result<Vec<u64>, ParseIntError>>()?;
for _ in 0..80 {
let mut new_fish = Vec::new();
for f in fish.iter_mut() {
if *f == 0 {
new_fish.push(8);
*f = 7;
}
*f -= 1;
}
fish.extend(new_fish);
}
Ok(fish.len())
}
#[aoc(day6, part2)]
fn part2(input: &str) -> Result<usize> {
let mut counts = [0; 9];
input
.split(',')
.map(|s| s.parse())
.collect::<Result<Vec<usize>, ParseIntError>>()?
.into_iter()
.for_each(|n| counts[n] += 1);
for _ in 0..256 {
let mut tmp = [0; 9];
for (i, c) in counts.iter().enumerate() {
if i == 0 {
tmp[6] = *c;
tmp[8] = *c;
} else {
tmp[i - 1] += *c;
}
}
counts = tmp;
}
Ok(counts.iter().sum())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"3,4,3,1,2"#.trim();
assert_eq!(part1(input)?, 5934);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"3,4,3,1,2"#.trim();
assert_eq!(part2(input)?, 26984457539);
Ok(())
}
}

140
2021/src/day7.rs Normal file
View File

@@ -0,0 +1,140 @@
//! --- Day 7: The Treachery of Whales ---
//! A giant whale has decided your submarine is its next meal, and it's much faster than you are. There's nowhere to run!
//!
//! Suddenly, a swarm of crabs (each in its own tiny submarine - it's too deep for them otherwise) zooms in to rescue you! They seem to be preparing to blast a hole in the ocean floor; sensors indicate a massive underground cave system just beyond where they're aiming!
//!
//! The crab submarines all need to be aligned before they'll have enough power to blast a large enough hole for your submarine to get through. However, it doesn't look like they'll be aligned before the whale catches you! Maybe you can help?
//!
//! There's one major catch - crab submarines can only move horizontally.
//!
//! You quickly make a list of the horizontal position of each crab (your puzzle input). Crab submarines have limited fuel, so you need to find a way to make all of their horizontal positions match while requiring them to spend as little fuel as possible.
//!
//! For example, consider the following horizontal positions:
//!
//! 16,1,2,0,4,2,7,1,2,14
//! This means there's a crab with horizontal position 16, a crab with horizontal position 1, and so on.
//!
//! Each change of 1 step in horizontal position of a single crab costs 1 fuel. You could choose any horizontal position to align them all on, but the one that costs the least fuel is horizontal position 2:
//!
//! Move from 16 to 2: 14 fuel
//! Move from 1 to 2: 1 fuel
//! Move from 2 to 2: 0 fuel
//! Move from 0 to 2: 2 fuel
//! Move from 4 to 2: 2 fuel
//! Move from 2 to 2: 0 fuel
//! Move from 7 to 2: 5 fuel
//! Move from 1 to 2: 1 fuel
//! Move from 2 to 2: 0 fuel
//! Move from 14 to 2: 12 fuel
//! This costs a total of 37 fuel. This is the cheapest possible outcome; more expensive outcomes include aligning at position 1 (41 fuel), position 3 (39 fuel), or position 10 (71 fuel).
//!
//! Determine the horizontal position that the crabs can align to using the least fuel possible. How much fuel must they spend to align to that position?
//!
//! --- Part Two ---
//! The crabs don't seem interested in your proposed solution. Perhaps you misunderstand crab engineering?
//!
//! As it turns out, crab submarine engines don't burn fuel at a constant rate. Instead, each change of 1 step in horizontal position costs 1 more unit of fuel than the last: the first step costs 1, the second step costs 2, the third step costs 3, and so on.
//!
//! As each crab moves, moving further becomes more expensive. This changes the best horizontal position to align them all on; in the example above, this becomes 5:
//!
//! Move from 16 to 5: 66 fuel
//! Move from 1 to 5: 10 fuel
//! Move from 2 to 5: 6 fuel
//! Move from 0 to 5: 15 fuel
//! Move from 4 to 5: 1 fuel
//! Move from 2 to 5: 6 fuel
//! Move from 7 to 5: 3 fuel
//! Move from 1 to 5: 10 fuel
//! Move from 2 to 5: 6 fuel
//! Move from 14 to 5: 45 fuel
//! This costs a total of 168 fuel. This is the new cheapest possible outcome; the old alignment position (2) now costs 206 fuel instead.
//!
//! Determine the horizontal position that the crabs can align to using the least fuel possible so they can make you an escape route! How much fuel must they spend to align to that position?
use std::num::ParseIntError;
use anyhow::Result;
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day7)]
fn parse(input: &str) -> Result<Vec<u64>, ParseIntError> {
input
.split(',')
.map(|s| s.parse())
.collect::<Result<Vec<u64>, ParseIntError>>()
}
fn score1(nums: &[u64], mid: u64) -> u64 {
nums.iter()
.map(|n| ((*n as i64) - (mid as i64)).abs())
.sum::<i64>() as u64
}
#[aoc(day7, part1)]
fn part1(input: &[u64]) -> Result<u64> {
let mut input: Vec<_> = input.to_vec();
input.sort_unstable();
Ok(score1(&input, input[input.len() / 2]))
}
fn score2(nums: &[u64], mid: u64) -> u64 {
nums.iter()
.map(|n| {
let d = ((*n as i64) - (mid as i64)).abs();
(d * (d + 1)) / 2
})
.sum::<i64>() as u64
}
#[aoc(day7, part2)]
fn part2(input: &[u64]) -> Result<u64> {
let input: Vec<_> = input.to_vec();
let avg = input.iter().sum::<u64>() / input.len() as u64;
let s = if avg > 10 { avg - 10 } else { 0 };
let num = input.len() as u64;
let e = if avg + 10 < num { avg + 10 } else { num };
let answer = (s..e)
.map(|i| score2(&input, i))
.min()
.expect("couldn't find min");
if input.len() > 10 {
// The real data needs an answer lower than our first attempt.
assert!(answer < 94862126);
}
Ok(answer)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_score1() -> Result<()> {
let nums: Vec<u64> = parse("16,1,2,0,4,2,7,1,2,14")?;
assert_eq!(score1(&nums, 1), 41);
assert_eq!(score1(&nums, 2), 37);
assert_eq!(score1(&nums, 3), 39);
assert_eq!(score1(&nums, 10), 71);
Ok(())
}
#[test]
fn test_part1() -> Result<()> {
let input = r#"16,1,2,0,4,2,7,1,2,14"#.trim();
assert_eq!(part1(&parse(input)?)?, 37);
Ok(())
}
#[test]
fn test_score2() -> Result<()> {
let nums: Vec<u64> = parse("16,1,2,0,4,2,7,1,2,14")?;
assert_eq!(score2(&nums, 5), 168);
assert_eq!(score2(&nums, 2), 206);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"16,1,2,0,4,2,7,1,2,14"#.trim();
assert_eq!(part2(&parse(input)?)?, 168);
Ok(())
}
}

331
2021/src/day8.rs Normal file
View File

@@ -0,0 +1,331 @@
//! --- Day 8: Seven Segment Search ---
//! You barely reach the safety of the cave when the whale smashes into the cave mouth, collapsing it. Sensors indicate another exit to this cave at a much greater depth, so you have no choice but to press on.
//!
//! As your submarine slowly makes its way through the cave system, you notice that the four-digit seven-segment displays in your submarine are malfunctioning; they must have been damaged during the escape. You'll be in a lot of trouble without them, so you'd better figure out what's wrong.
//!
//! Each digit of a seven-segment display is rendered by turning on or off any of seven segments named a through g:
//!
//! 0: 1: 2: 3: 4:
//! aaaa .... aaaa aaaa ....
//! b c . c . c . c b c
//! b c . c . c . c b c
//! .... .... dddd dddd dddd
//! e f . f e . . f . f
//! e f . f e . . f . f
//! gggg .... gggg gggg ....
//!
//! 5: 6: 7: 8: 9:
//! aaaa aaaa aaaa aaaa aaaa
//! b . b . . c b c b c
//! b . b . . c b c b c
//! dddd dddd .... dddd dddd
//! . f e f . f e f . f
//! . f e f . f e f . f
//! gggg gggg .... gggg gggg
//! So, to render a 1, only segments c and f would be turned on; the rest would be off. To render a 7, only segments a, c, and f would be turned on.
//!
//! The problem is that the signals which control the segments have been mixed up on each display. The submarine is still trying to display numbers by producing output on signal wires a through g, but those wires are connected to segments randomly. Worse, the wire/segment connections are mixed up separately for each four-digit display! (All of the digits within a display use the same connections, though.)
//!
//! So, you might know that only signal wires b and g are turned on, but that doesn't mean segments b and g are turned on: the only digit that uses two segments is 1, so it must mean segments c and f are meant to be on. With just that information, you still can't tell which wire (b/g) goes to which segment (c/f). For that, you'll need to collect more information.
//!
//! For each display, you watch the changing signals for a while, make a note of all ten unique signal patterns you see, and then write down a single four digit output value (your puzzle input). Using the signal patterns, you should be able to work out which pattern corresponds to which digit.
//!
//! For example, here is what you might see in a single entry in your notes:
//!
//! acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
//! cdfeb fcadb cdfeb cdbaf
//! (The entry is wrapped here to two lines so it fits; in your notes, it will all be on a single line.)
//!
//! Each entry consists of ten unique signal patterns, a | delimiter, and finally the four digit output value. Within an entry, the same wire/segment connections are used (but you don't know what the connections actually are). The unique signal patterns correspond to the ten different ways the submarine tries to render a digit using the current wire/segment connections. Because 7 is the only digit that uses three segments, dab in the above example means that to render a 7, signal lines d, a, and b are on. Because 4 is the only digit that uses four segments, eafb means that to render a 4, signal lines e, a, f, and b are on.
//!
//! Using this information, you should be able to work out which combination of signal wires corresponds to each of the ten digits. Then, you can decode the four digit output value. Unfortunately, in the above example, all of the digits in the output value (cdfeb fcadb cdfeb cdbaf) use five segments and are more difficult to deduce.
//!
//! For now, focus on the easy digits. Consider this larger example:
//!
//! be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb |
//! fdgacbe cefdb cefbgd gcbe
//! edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec |
//! fcgedb cgb dgebacf gc
//! fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef |
//! cg cg fdcagb cbg
//! fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega |
//! efabcd cedba gadfec cb
//! aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga |
//! gecf egdcabf bgf bfgea
//! fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf |
//! gebdcfa ecba ca fadegcb
//! dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf |
//! cefg dcbef fcge gbcadfe
//! bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd |
//! ed bcgafe cdgba cbgef
//! egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg |
//! gbdfcae bgc cg cgb
//! gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc |
//! fgae cfgab fg bagce
//! Because the digits 1, 4, 7, and 8 each use a unique number of segments, you should be able to tell which combinations of signals correspond to those digits. Counting only digits in the output values (the part after | on each line), in the above example, there are 26 instances of digits that use a unique number of segments (highlighted above).
//!
//! In the output values, how many times do digits 1, 4, 7, or 8 appear?
//!
//! --- Part Two ---
//! Through a little deduction, you should now be able to determine the remaining digits. Consider again the first example above:
//!
//! acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab |
//! cdfeb fcadb cdfeb cdbaf
//! After some careful analysis, the mapping between signal wires and segments only make sense in the following configuration:
//!
//! dddd
//! e a
//! e a
//! ffff
//! g b
//! g b
//! cccc
//! So, the unique signal patterns would correspond to the following digits:
//!
//! acedgfb: 8
//! cdfbe: 5
//! gcdfa: 2
//! fbcad: 3
//! dab: 7
//! cefabd: 9
//! cdfgeb: 6
//! eafb: 4
//! cagedb: 0
//! ab: 1
//! Then, the four digits of the output value can be decoded:
//!
//! cdfeb: 5
//! fcadb: 3
//! cdfeb: 5
//! cdbaf: 3
//! Therefore, the output value for this entry is 5353.
//!
//! Following this same process for each entry in the second, larger example above, the output value of each entry can be determined:
//!
//! fdgacbe cefdb cefbgd gcbe: 8394
//! fcgedb cgb dgebacf gc: 9781
//! cg cg fdcagb cbg: 1197
//! efabcd cedba gadfec cb: 9361
//! gecf egdcabf bgf bfgea: 4873
//! gebdcfa ecba ca fadegcb: 8418
//! cefg dcbef fcge gbcadfe: 4548
//! ed bcgafe cdgba cbgef: 1625
//! gbdfcae bgc cg cgb: 8717
//! fgae cfgab fg bagce: 4315
//! Adding all of the output values in this larger example produces 61229.
//!
//! For each entry, determine all of the wire/segment connections and decode the four-digit output values. What do you get if you add up all of the output values?
//!
use std::{
collections::HashMap,
convert::Infallible,
fmt::{Debug, Error, Formatter},
ops::BitAnd,
str::FromStr,
};
use anyhow::Result;
use aoc_runner_derive::aoc;
#[aoc(day8, part1, original)]
fn part1(input: &str) -> Result<usize> {
Ok(input
.lines()
.map(|l| {
l.split_once(" | ")
.unwrap()
.1
.split(' ')
// 1 | 7 | 4 | 8
.filter(|s| matches!(s.len(), 2 | 3 | 4 | 7))
.count()
})
.sum())
}
#[aoc(day8, part1, no_result)]
fn part1_no_result(input: &str) -> usize {
input
.lines()
.map(|l| {
l.split_once(" | ")
.unwrap()
.1
.split(' ')
// 1 | 7 | 4 | 8
.filter(|s| matches!(s.len(), 2 | 3 | 4 | 7))
.count()
})
.sum()
}
#[aoc(day8, part1, flat_map)]
fn part1_flat_map(input: &str) -> usize {
input
.lines()
.flat_map(|l| l.split_once(" | ").unwrap().1.split(' '))
// 1 | 7 | 4 | 8
.filter(|s| matches!(s.len(), 2 | 3 | 4 | 7))
.count()
}
#[aoc(day8, part1, glenng)]
fn part1_glenng(input: &str) -> usize {
input
.split('\n')
.flat_map(|line| {
let (_, output) = line.split_once(" | ").unwrap();
output.split(' ')
})
.filter(|s| [2usize, 3, 4, 7].contains(&s.len()))
.count()
}
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
struct Segment(u8);
impl Debug for Segment {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "{:07b}", self.0)
}
}
impl FromStr for Segment {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut bits = 0;
for b in s.as_bytes() {
bits |= 1 << (b - b'a');
}
Ok(Segment(bits))
}
}
impl BitAnd for Segment {
type Output = Self;
// rhs is the "right-hand side" of the expression `a & b`
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & rhs.0)
}
}
fn build_lookup(input: &str) -> Result<HashMap<Segment, u8>> {
let mut map: HashMap<u8, Segment> = HashMap::new();
let set: Vec<_> = input.split(' ').collect();
for digit in &set {
let s = digit.parse().unwrap();
match digit.len() {
// 1
2 => map.insert(1, s),
// 7
3 => map.insert(7, s),
// 4
4 => map.insert(4, s),
// 8
7 => map.insert(8, s),
_ => None,
};
}
let one = map[&1];
let four = map[&4];
// 0, 6 or 9 have 6 segments:
// 9 contains 1 and 4
// 0 intersects w/ 1 but not w/ 4
// 6 is the left overs.
set.iter().filter(|s| s.len() == 6).for_each(|d| {
let s: Segment = d.parse().unwrap();
if s & one == one && s & four == four {
map.insert(9, s);
} else if s & one == one {
map.insert(0, s);
} else {
map.insert(6, s);
}
});
let nine = map[&9];
// 2, 3 and 5 have 5 segments:
// 3 has overlap w/ 1
// 5 is a subset of 9
// 2 is the left overs.
set.iter().filter(|s| s.len() == 5).for_each(|d| {
let s: Segment = d.parse().unwrap();
if s & one == one {
map.insert(3, s);
} else if s & nine == s {
map.insert(5, s);
} else {
map.insert(2, s);
}
});
// Swap key/value.
Ok(map.into_iter().map(|(k, v)| (v, k)).collect())
}
fn output(line: &str) -> Result<u64> {
let (inp, out) = line.split_once(" | ").expect("line missing |");
let lookup = build_lookup(inp)?;
Ok(out
.split(' ')
.map(|s| {
let s: Segment = s.parse().unwrap();
lookup[&s]
})
.fold(0, |answer, d| 10 * answer + d as u64))
}
#[aoc(day8, part2)]
fn part2(input: &str) -> Result<u64> {
Ok(input
.lines()
.map(|l| output(l).expect("couldn't parse line"))
.sum())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
"#
.trim();
assert_eq!(part1(input)?, 26);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
"#
.trim();
assert_eq!(part2(input)?, 61229);
Ok(())
}
}

244
2021/src/day9.rs Normal file
View File

@@ -0,0 +1,244 @@
//! --- Day 9: Smoke Basin ---
//! These caves seem to be lava tubes. Parts are even still volcanically active; small hydrothermal vents release smoke into the caves that slowly settles like rain.
//!
//! If you can model how the smoke flows through the caves, you might be able to avoid it and be that much safer. The submarine generates a heightmap of the floor of the nearby caves for you (your puzzle input).
//!
//! Smoke flows to the lowest point of the area it's in. For example, consider the following heightmap:
//!
//! 2199943210
//! 3987894921
//! 9856789892
//! 8767896789
//! 9899965678
//! Each number corresponds to the height of a particular location, where 9 is the highest and 0 is the lowest a location can be.
//!
//! Your first goal is to find the low points - the locations that are lower than any of its adjacent locations. Most locations have four adjacent locations (up, down, left, and right); locations on the edge or corner of the map have three or two adjacent locations, respectively. (Diagonal locations do not count as adjacent.)
//!
//! In the above example, there are four low points, all highlighted: two are in the first row (a 1 and a 0), one is in the third row (a 5), and one is in the bottom row (also a 5). All other locations on the heightmap have some lower adjacent location, and so are not low points.
//!
//! The risk level of a low point is 1 plus its height. In the above example, the risk levels of the low points are 2, 1, 6, and 6. The sum of the risk levels of all low points in the heightmap is therefore 15.
//!
//! Find all of the low points on your heightmap. What is the sum of the risk levels of all low points on your heightmap?
//!
//! --- Part Two ---
//! Next, you need to find the largest basins so you know what areas are most important to avoid.
//!
//! A basin is all locations that eventually flow downward to a single low point. Therefore, every low point has a basin, although some basins are very small. Locations of height 9 do not count as being in any basin, and all other locations will always be part of exactly one basin.
//!
//! The size of a basin is the number of locations within the basin, including the low point. The example above has four basins.
//!
//! The top-left basin, size 3:
//!
//! 2199943210
//! 3987894921
//! 9856789892
//! 8767896789
//! 9899965678
//! The top-right basin, size 9:
//!
//! 2199943210
//! 3987894921
//! 9856789892
//! 8767896789
//! 9899965678
//! The middle basin, size 14:
//!
//! 2199943210
//! 3987894921
//! 9856789892
//! 8767896789
//! 9899965678
//! The bottom-right basin, size 9:
//!
//! 2199943210
//! 3987894921
//! 9856789892
//! 8767896789
//! 9899965678
//! Find the three largest basins and multiply their sizes together. In the above example, this is 9 * 14 * 9 = 1134.
//!
//! What do you get if you multiply together the sizes of the three largest basins?
use std::{
collections::{HashSet, VecDeque},
convert::Infallible,
fmt::{Debug, Error, Formatter},
ops::Index,
str::FromStr,
};
use anyhow::Result;
use aoc_runner_derive::{aoc, aoc_generator};
struct HeightMap {
width: usize,
height: usize,
pixels: Vec<u8>,
}
impl Debug for HeightMap {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
for y in 0..self.height {
for x in 0..self.width {
write!(f, "{}", self[(x, y)])?;
}
writeln!(f)?;
}
Ok(())
}
}
impl HeightMap {
fn low_points(&self) -> Vec<u8> {
let mut pts = Vec::new();
for y in 0..self.height {
for x in 0..self.width {
let c = self[(x, y)];
if (x == 0 || c < self[(x - 1, y)])
&& (y == 0 || c < self[(x, y - 1)])
&& (x == self.width - 1 || c < self[(x + 1, y)])
&& (y == self.height - 1 || c < self[(x, y + 1)])
{
pts.push(c);
}
}
}
pts
}
// counts number of neighbors not 9.
fn flood_fill(&self, initial: (isize, isize), coords: &mut HashSet<(isize, isize)>) {
// This is an iterative implementation of what would be nice to do recursively. Rust
// stack overflows on the final dataset if written recursively.
let mut q = VecDeque::new();
q.push_back(initial);
while let Some((x, y)) = q.pop_front() {
// Can be negative or outside the width,height, Indeximpl will return 9.
let c = self[(x, y)] as usize;
if c == 9 {
// Don't count 9's that are neighbors and don't explore their neighbors.
continue;
}
if coords.insert((x, y)) {
q.push_back((x - 1, y));
q.push_back((x, y - 1));
q.push_back((x + 1, y));
q.push_back((x, y + 1));
}
}
}
fn basins(&self) -> Vec<usize> {
let mut bs = Vec::new();
for y in 0..self.height {
for x in 0..self.width {
let c = self[(x, y)];
if (x == 0 || c < self[(x - 1, y)])
&& (y == 0 || c < self[(x, y - 1)])
&& (x == self.width - 1 || c < self[(x + 1, y)])
&& (y == self.height - 1 || c < self[(x, y + 1)])
{
let mut coords = HashSet::new();
self.flood_fill((x as isize, y as isize), &mut coords);
bs.push(coords.len());
}
}
}
bs
}
}
// Index implementation that panics if x or y are greater than width or height.
impl Index<(usize, usize)> for HeightMap {
type Output = u8;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
// Index implementation that returns 9 for out of range requests.
impl Index<(isize, isize)> for HeightMap {
type Output = u8;
fn index(&self, (x, y): (isize, isize)) -> &Self::Output {
if x < 0 || y < 0 || x > self.width as isize - 1 || y > self.height as isize - 1 {
return &9;
}
&self.pixels[x as usize + y as usize * self.width]
}
}
impl FromStr for HeightMap {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rows: Vec<_> = s.lines().collect();
let width = rows[0].len();
let height = rows.len();
let pixels = rows
.iter()
.flat_map(|row| row.as_bytes().iter().map(|b| b - b'0'))
.collect();
Ok(HeightMap {
width,
height,
pixels,
})
}
}
#[aoc_generator(day9)]
fn parse(input: &str) -> Result<HeightMap> {
Ok(input.parse()?)
}
#[aoc(day9, part1)]
fn part1(input: &HeightMap) -> Result<u64> {
Ok(input.low_points().iter().map(|b| (*b + 1) as u64).sum())
}
#[aoc(day9, part2)]
fn part2(hm: &HeightMap) -> Result<usize> {
let mut sizes = hm.basins();
sizes.sort_unstable();
Ok(sizes[sizes.len() - 3..].iter().product())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
2199943210
3987894921
9856789892
8767896789
9899965678
"#
.trim();
let hm = parse(input)?;
assert_eq!(hm.low_points(), vec![1, 0, 5, 5]);
assert_eq!(part1(&hm)?, 15);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let input = r#"
2199943210
3987894921
9856789892
8767896789
9899965678
"#
.trim();
let hm = parse(input)?;
assert_eq!(hm.basins(), vec![3, 9, 14, 9]);
assert_eq!(part2(&hm)?, 1134);
Ok(())
}
}

37
2021/src/lib.rs Normal file
View File

@@ -0,0 +1,37 @@
pub mod day1;
pub mod day10;
pub mod day11;
pub mod day12;
pub mod day13;
//pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17;
//pub mod day18;
pub mod day19;
pub mod day2;
pub mod day20;
pub mod day21;
pub mod day22;
//pub mod day23;
pub mod day3;
pub mod day4;
pub mod day5;
pub mod day6;
pub mod day7;
pub mod day8;
pub mod day9;
use aoc_runner_derive::aoc_lib;
#[macro_export]
macro_rules! debug_print{
($($arg:tt)*) => (#[cfg(debug_assertions)] print!($($arg)*));
}
#[macro_export]
macro_rules! debug_println {
($($arg:tt)*) => (#[cfg(debug_assertions)] println!($($arg)*));
}
aoc_lib! { year = 2021 }

3
2021/src/main.rs Normal file
View File

@@ -0,0 +1,3 @@
use aoc_runner_derive::aoc_main;
aoc_main! { lib = advent2021 }

41
2021/src/template.rs Normal file
View File

@@ -0,0 +1,41 @@
use advent::prelude::*;
use aoc_runner_derive::aoc;
#[aoc(dayX, part1)]
fn part1(input: &str) -> Result<usize> {
todo!("part1");
Ok(0)
}
/*
#[aoc(dayX, part2)]
fn part2(input: &str) -> Result<usize> {
todo!("part2");
Ok(0)
}
*/
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part1() -> Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part1(input)?, usize::MAX);
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
"#
.trim();
assert_eq!(part2(input)?, usize::MAX);
Ok(())
}
*/
}

16
Cargo.toml Normal file
View File

@@ -0,0 +1,16 @@
[package]
name = "advent"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.45"
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
pretty_assertions = "1.0.0"
thiserror = "1.0.30"
[lib]
name = "advent"

500
input/2021/day5.txt Normal file
View File

@@ -0,0 +1,500 @@
217,490 -> 217,764
44,270 -> 373,599
440,139 -> 440,303
161,663 -> 345,663
848,963 -> 908,963
299,207 -> 162,70
77,346 -> 77,686
693,743 -> 693,127
96,459 -> 96,779
864,39 -> 233,670
58,79 -> 203,79
158,596 -> 463,291
633,293 -> 136,293
656,474 -> 656,72
148,754 -> 947,754
535,780 -> 535,460
821,701 -> 821,796
592,200 -> 592,610
620,786 -> 722,786
632,731 -> 536,731
825,640 -> 195,10
956,547 -> 956,387
25,32 -> 981,988
870,613 -> 870,16
369,780 -> 369,362
348,924 -> 243,924
28,114 -> 540,114
702,690 -> 702,335
836,442 -> 184,442
602,11 -> 602,651
76,988 -> 608,988
15,922 -> 951,922
363,18 -> 296,18
130,580 -> 516,580
799,335 -> 858,335
571,842 -> 571,800
684,654 -> 684,971
815,674 -> 66,674
575,612 -> 575,919
652,126 -> 822,296
391,493 -> 730,493
810,479 -> 810,807
397,420 -> 780,37
187,740 -> 869,740
175,626 -> 175,169
773,901 -> 773,44
45,130 -> 45,17
226,253 -> 252,279
481,928 -> 481,521
121,506 -> 121,50
306,386 -> 653,733
115,635 -> 208,542
619,67 -> 212,67
82,79 -> 972,969
15,20 -> 15,933
606,136 -> 500,136
791,250 -> 791,316
128,931 -> 781,278
11,365 -> 11,226
705,326 -> 57,326
778,632 -> 173,27
121,624 -> 121,737
30,815 -> 909,815
18,114 -> 869,965
554,741 -> 554,771
284,826 -> 945,826
386,654 -> 295,654
235,848 -> 418,848
536,59 -> 497,59
156,922 -> 29,922
57,718 -> 174,718
964,774 -> 964,426
729,950 -> 729,254
896,117 -> 152,861
603,919 -> 603,776
176,472 -> 573,472
25,970 -> 939,56
478,482 -> 38,482
155,936 -> 956,135
351,621 -> 133,403
513,323 -> 103,323
679,167 -> 679,983
910,456 -> 241,456
16,266 -> 16,829
338,791 -> 973,156
564,73 -> 564,676
196,800 -> 339,800
15,776 -> 973,776
719,134 -> 719,775
730,692 -> 272,692
247,770 -> 244,770
853,720 -> 940,720
685,379 -> 873,379
944,647 -> 944,206
67,974 -> 967,74
828,194 -> 355,194
596,522 -> 596,169
677,970 -> 638,970
587,427 -> 587,354
804,488 -> 469,153
355,653 -> 787,221
798,873 -> 133,873
565,798 -> 534,829
239,273 -> 20,273
942,138 -> 398,138
499,743 -> 958,284
913,466 -> 514,466
504,705 -> 504,983
455,863 -> 451,863
638,255 -> 425,255
338,724 -> 338,457
147,880 -> 928,99
11,955 -> 806,160
566,961 -> 231,961
870,560 -> 611,560
714,925 -> 859,925
484,946 -> 905,946
112,394 -> 266,394
191,728 -> 191,635
983,806 -> 217,40
575,286 -> 730,286
366,323 -> 366,211
383,990 -> 834,990
834,976 -> 26,168
819,492 -> 819,648
257,522 -> 257,199
756,176 -> 244,176
165,199 -> 569,199
896,943 -> 18,65
986,642 -> 354,10
864,381 -> 349,381
177,982 -> 977,182
458,254 -> 458,920
550,322 -> 550,297
956,748 -> 270,62
412,305 -> 292,305
201,571 -> 375,571
608,139 -> 608,330
646,718 -> 432,504
449,325 -> 449,115
315,971 -> 955,331
248,143 -> 477,143
956,858 -> 111,13
776,608 -> 739,608
44,842 -> 548,842
590,487 -> 590,792
978,127 -> 978,748
620,948 -> 852,948
67,403 -> 67,122
340,256 -> 346,256
803,58 -> 474,387
876,448 -> 876,55
78,288 -> 565,288
235,80 -> 480,80
949,880 -> 949,666
529,734 -> 529,332
780,973 -> 780,824
900,279 -> 698,279
290,438 -> 34,694
766,569 -> 766,443
729,690 -> 729,137
72,938 -> 72,893
960,563 -> 960,322
669,293 -> 578,293
396,388 -> 984,388
675,694 -> 211,230
152,743 -> 63,743
203,660 -> 391,660
582,806 -> 906,806
698,837 -> 698,483
869,320 -> 595,594
283,817 -> 283,861
919,926 -> 919,235
16,64 -> 930,978
980,25 -> 16,989
181,890 -> 952,119
877,731 -> 877,364
130,55 -> 130,111
30,298 -> 590,858
134,933 -> 134,41
711,853 -> 711,196
123,206 -> 841,924
130,585 -> 130,394
161,952 -> 531,952
455,830 -> 455,919
612,817 -> 30,817
461,474 -> 106,119
511,100 -> 581,30
263,550 -> 263,814
976,973 -> 14,11
749,876 -> 380,876
731,226 -> 731,659
630,682 -> 570,622
914,780 -> 311,780
975,274 -> 87,274
328,957 -> 724,957
357,950 -> 357,659
466,580 -> 466,726
854,425 -> 854,559
39,106 -> 39,82
675,711 -> 956,711
204,117 -> 672,585
867,101 -> 49,919
849,88 -> 784,88
394,249 -> 394,730
865,188 -> 125,928
316,918 -> 722,918
781,336 -> 781,551
821,826 -> 258,826
597,273 -> 597,653
726,266 -> 90,902
701,701 -> 941,701
105,401 -> 949,401
890,486 -> 890,205
651,409 -> 651,408
450,88 -> 51,88
29,478 -> 29,667
676,293 -> 676,77
380,773 -> 962,773
253,836 -> 429,836
833,706 -> 123,706
689,167 -> 665,143
375,540 -> 375,346
867,222 -> 746,343
99,832 -> 370,561
133,349 -> 133,815
950,981 -> 12,43
195,466 -> 644,466
84,876 -> 84,720
128,237 -> 34,331
872,947 -> 960,947
641,220 -> 641,472
489,950 -> 489,441
508,513 -> 721,300
394,137 -> 332,137
456,672 -> 625,503
65,463 -> 540,463
207,745 -> 529,423
948,888 -> 891,831
39,642 -> 165,642
20,228 -> 20,386
706,50 -> 57,699
66,736 -> 66,840
944,450 -> 915,479
697,988 -> 697,862
987,969 -> 57,39
64,813 -> 64,468
814,85 -> 469,85
667,749 -> 154,236
755,337 -> 755,50
536,185 -> 536,217
732,48 -> 529,48
33,578 -> 430,578
511,658 -> 669,658
294,352 -> 353,352
109,937 -> 820,226
465,346 -> 465,114
878,965 -> 34,121
259,933 -> 576,933
240,750 -> 240,296
567,633 -> 899,965
29,609 -> 169,469
962,532 -> 962,921
443,875 -> 395,875
831,584 -> 510,263
859,35 -> 84,810
829,285 -> 829,463
486,661 -> 883,661
371,672 -> 959,84
722,532 -> 722,241
49,216 -> 468,216
308,343 -> 308,277
183,626 -> 264,545
748,611 -> 356,611
67,85 -> 925,943
726,972 -> 726,272
841,222 -> 841,867
597,250 -> 813,250
20,631 -> 555,631
803,846 -> 589,632
276,654 -> 222,708
400,952 -> 672,952
939,173 -> 534,173
638,316 -> 638,935
578,120 -> 578,101
54,457 -> 723,457
904,713 -> 904,721
902,180 -> 99,983
590,426 -> 174,10
740,975 -> 309,975
84,242 -> 803,961
28,667 -> 362,333
73,703 -> 73,354
902,26 -> 902,365
602,455 -> 578,431
339,686 -> 339,846
764,444 -> 311,444
780,535 -> 862,453
333,127 -> 911,127
451,296 -> 451,832
849,681 -> 849,580
309,672 -> 309,913
339,411 -> 147,411
907,478 -> 974,545
444,753 -> 855,342
642,285 -> 683,244
307,633 -> 751,633
292,128 -> 767,603
969,92 -> 647,414
80,120 -> 942,982
886,810 -> 740,810
205,846 -> 168,846
878,230 -> 72,230
186,822 -> 628,822
472,66 -> 472,609
251,753 -> 129,753
575,959 -> 102,959
582,194 -> 858,194
43,986 -> 43,589
355,402 -> 751,402
982,292 -> 86,292
329,966 -> 329,379
475,291 -> 475,924
625,70 -> 625,350
358,467 -> 981,467
319,700 -> 736,283
657,247 -> 654,247
450,803 -> 450,497
812,15 -> 812,425
649,160 -> 377,160
684,491 -> 690,491
925,429 -> 772,429
138,91 -> 883,91
602,121 -> 774,293
700,531 -> 451,531
250,216 -> 800,766
550,784 -> 289,784
53,759 -> 228,759
678,310 -> 645,343
147,70 -> 171,46
130,653 -> 130,103
292,640 -> 731,640
797,762 -> 618,762
154,75 -> 964,885
222,523 -> 557,523
989,103 -> 989,964
335,61 -> 422,61
782,954 -> 160,332
82,929 -> 82,528
732,540 -> 635,637
950,362 -> 798,362
415,566 -> 916,566
588,446 -> 743,291
495,46 -> 495,435
913,561 -> 303,561
788,902 -> 788,698
81,783 -> 715,149
867,990 -> 867,558
145,919 -> 145,725
850,861 -> 727,861
535,129 -> 535,496
922,772 -> 922,917
882,559 -> 672,349
496,80 -> 496,948
915,244 -> 516,643
633,461 -> 748,461
899,341 -> 677,341
66,981 -> 878,169
68,24 -> 984,940
12,880 -> 23,869
779,514 -> 779,752
878,641 -> 949,641
264,919 -> 229,919
213,281 -> 213,196
538,149 -> 538,278
184,478 -> 364,298
301,136 -> 923,758
559,266 -> 559,986
384,37 -> 384,558
815,529 -> 800,514
33,80 -> 624,80
561,261 -> 215,607
169,944 -> 169,921
673,42 -> 164,42
820,977 -> 424,581
816,29 -> 802,29
374,924 -> 121,671
962,555 -> 426,19
982,199 -> 860,77
334,62 -> 359,62
960,785 -> 260,85
681,280 -> 860,280
184,925 -> 184,30
332,398 -> 858,924
405,270 -> 218,270
261,846 -> 29,614
591,941 -> 591,716
313,502 -> 313,637
930,259 -> 779,259
432,15 -> 566,149
51,182 -> 223,182
603,536 -> 603,281
139,703 -> 825,17
965,22 -> 55,932
389,608 -> 771,608
209,617 -> 923,617
769,672 -> 769,236
163,717 -> 638,717
801,604 -> 136,604
974,881 -> 110,17
187,226 -> 929,968
430,949 -> 473,949
899,279 -> 899,224
964,806 -> 964,876
635,190 -> 349,190
142,656 -> 142,216
740,814 -> 35,109
588,956 -> 534,956
107,968 -> 707,968
787,639 -> 787,50
964,491 -> 964,148
30,70 -> 30,323
30,905 -> 806,129
592,419 -> 91,419
73,87 -> 973,987
540,683 -> 540,139
422,107 -> 422,90
935,74 -> 935,590
728,566 -> 188,26
839,313 -> 839,620
723,898 -> 723,719
679,814 -> 679,617
203,633 -> 417,633
36,812 -> 546,302
112,316 -> 598,802
798,773 -> 989,964
914,69 -> 520,69
213,556 -> 213,19
795,516 -> 795,220
348,803 -> 664,803
910,861 -> 238,189
633,691 -> 594,691
96,166 -> 96,60
278,848 -> 854,272
64,370 -> 64,815
386,196 -> 386,222
888,330 -> 888,834
166,482 -> 37,482
594,283 -> 594,865
515,267 -> 515,448
707,279 -> 239,747
302,745 -> 302,268
210,830 -> 885,155
592,180 -> 592,324
245,154 -> 245,613
607,954 -> 545,954
854,951 -> 19,116
77,878 -> 963,878
759,585 -> 759,892
750,918 -> 750,130
62,716 -> 329,983
785,880 -> 785,590
318,794 -> 318,599
403,547 -> 719,863
742,803 -> 742,937
680,579 -> 680,425
268,404 -> 826,962
425,959 -> 710,959
406,823 -> 976,253
359,361 -> 165,361
276,861 -> 657,480
74,260 -> 743,929
194,129 -> 194,651
879,835 -> 65,21
16,977 -> 980,13
538,525 -> 624,439
985,789 -> 985,510
699,850 -> 560,711
301,48 -> 477,224
28,938 -> 905,61
844,530 -> 793,530
286,325 -> 936,975
368,122 -> 677,431
924,153 -> 924,774
783,498 -> 783,148
250,392 -> 578,392
465,345 -> 573,345
860,763 -> 860,40
373,226 -> 599,226
169,562 -> 169,292
408,123 -> 569,123
510,396 -> 733,396
199,20 -> 199,770
892,631 -> 237,631
671,863 -> 705,863
141,530 -> 141,630
467,159 -> 367,159
729,501 -> 255,975
578,871 -> 578,225
821,363 -> 821,820

2
rustfmt.toml Normal file
View File

@@ -0,0 +1,2 @@
imports_granularity = "Crate"
format_code_in_doc_comments = true

95
src/image.rs Normal file
View File

@@ -0,0 +1,95 @@
use crate::prelude::*;
pub struct Image {
width: usize,
height: usize,
pixels: Vec<u8>,
}
impl Image {
fn kernel3x3<F>(&mut self, (x, y): (usize, usize), func: F)
where
F: Fn(u8) -> u8,
{
if x > 0 {
self[(x - 1, y)] = func(self[(x - 1, y)]);
if y > 0 {
self[(x - 1, y - 1)] = func(self[(x - 1, y - 1)]);
}
if y < self.height - 1 {
self[(x - 1, y + 1)] = func(self[(x - 1, y + 1)]);
}
}
if y > 0 {
self[(x, y - 1)] = func(self[(x, y - 1)]);
}
self[(x, y)] = func(self[(x, y)]);
if y < self.height - 1 {
self[(x, y + 1)] = func(self[(x, y + 1)]);
}
if x < self.width - 1 {
self[(x + 1, y)] = func(self[(x + 1, y)]);
if y > 0 {
self[(x + 1, y - 1)] = func(self[(x + 1, y - 1)]);
}
if y < self.height - 1 {
self[(x + 1, y + 1)] = func(self[(x + 1, y + 1)]);
}
}
}
}
impl PartialEq for Image {
fn eq(&self, other: &Self) -> bool {
self.width == other.width && self.height == other.height && self.pixels == other.pixels
}
}
impl Debug for Image {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(f)?;
for y in 0..self.height {
for x in 0..self.width {
write!(f, "{:2}", self[(x, y)] as char)?;
}
writeln!(f)?;
}
Ok(())
}
}
impl FromStr for Image {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let rows: Vec<_> = s.lines().collect();
let width = rows[0].len();
let height = rows.len();
let pixels = rows
.iter()
.flat_map(|row| row.as_bytes().iter())
.map(|b| *b)
.collect();
Ok(Image {
width,
height,
pixels,
})
}
}
impl Index<(usize, usize)> for Image {
type Output = u8;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * self.width]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
&mut self.pixels[x + y * self.width]
}
}

18
src/lib.rs Normal file
View File

@@ -0,0 +1,18 @@
pub mod prelude {
pub use std::{
collections::{HashMap, HashSet, VecDeque},
convert::Infallible,
fmt::{Debug, Display, Error, Formatter},
io::Read,
num::ParseIntError,
ops::{Index, IndexMut, RangeInclusive},
str::FromStr,
};
pub use anyhow::Result;
pub use thiserror::Error;
pub use crate::image::Image;
}
mod image;