diff --git a/21/Cargo.lock b/21/Cargo.lock new file mode 100644 index 0000000..1dfee22 --- /dev/null +++ b/21/Cargo.lock @@ -0,0 +1,266 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "day21" +version = "0.1.0" +dependencies = [ + "indicatif", + "petgraph", + "rayon", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/21/Cargo.toml b/21/Cargo.toml new file mode 100644 index 0000000..441e2ba --- /dev/null +++ b/21/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "day21" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +indicatif = "0.17.7" +petgraph = "0.6.4" +rayon = "1.8.0" diff --git a/21/input b/21/input new file mode 100644 index 0000000..b7f57f9 --- /dev/null +++ b/21/input @@ -0,0 +1,131 @@ +................................................................................................................................... +..............#...#........#...............#.#.......#....##...........#.#..#......#.....#.........#..##........................... +.#..##..##..#......#.#.#...##......###...##......#.#..#...................#.....#..........#..#................#...#..........#.... +.....................#..#.......#.....##.........#.......................................#........#....#.#..........#.#......#.#... +......##...#.....#.......#...#..###..........#..........#......................#........#.............#.....#........#....#........ +.................##.................#...#.........#................................#........#...........#............#........#.... +..............#.#....#........##.....##..........#.............##.............#...#......#..##..........#.........#.....#...#..#... +..#....#.......#...##..#......#.........#.#..#....#.#..............#........#...#...#...............#.#.....#..#..##......#...#.... +...#......##...##..#...#..........#...#..........#..............#...#..........#..#..#..#........#.#.#.#.#...........###........... +.#.#.#...#.#...##............................................#......................#...#......#......##.#......................... +.##.#.........#...#..................##...........#............#..................###...#...........#.................#....#....... +.....................#...#.#................#................#.#........................#...#...##....##....#.#...#.........#...#.. +...#.......#...#.........................#.#..................#........##..........................#......##....##............#.... +......................#.....................#...............#.......#.#...................#...............#...#........#.##......#. +............................#..........................#........#....#.##..#.......#.##..#...#.#..#...............#.#..#....#...... +.......................................................#.#..#.#....#......................#............#....#..#.......#.........#. +.....##........#...............#.......#...............#.#..........##..#...................#................#..#...#.#....#...###. +....#.....................##................#.......#.......#...#.#...#...............#................#...............##.......... +....#........#..#.......#.#.#........................#.#...........#.......#..#.........#....#.......#........#.#.#................ +......###.....#..#...........#.....#..#..#........#......#.#........###.....##............#..#...........#......................... +.....#...........#...................#..#..........#..#...###.#.........#.##...............#..##..........#.........#.............. +.#.........#....#............#.##..........................##.....#........#....#.............#.......#...#..............##.#...... +.#..#...#.......#...#.......##.......#.#.............................#...#...#.#...........#...#.................#.........#.#.#... +...#....................#.....##..............#.................#.................#............#......#....#.......#.........#..... +.......#...#.............#.##...#.#...................#.....#..#........#................................#.............#..#...##... +...#.###..............#....#........................#......#...#.........#......#.#....................#........#...#...#.......#.. +............#.#...#...........................#....###.###...#........#..#........#...................##.....###......#........#... +.....#...#................#.##..##..................#....#.........#............##...................##................#.....#..... +.#....#..............##...#..................#......#..........##.#....#......##.#...............#....##..............#....#....... +....#.#.##...........##.....#...........#.........#...#........#..#.......#......#................#.#...#....#...#................. +.......#...#...#...#..#.......#..........#..................#..#........#..#.#.....#.#.....................##...................... +.....##.........#.......##...#.............#.##.#.#...#.##.#...#......#...#....#.......#..#.........#...........#.##.###.#.....#... +...................#.#.......................#.....#.#......#.....##...#.#....#..#..........#...........#..##....#...#.......#.#... +.....#..#..#.........#...#.#.........#...#.#...##...#......##........#...............#.......#................#.....#...#.#........ +........#.....###.....................#.........#.........#.........#....##............#..##.............#.........#..#.......#.... +.#.........#....##..##.................#...#................................#...#.....#.........#.......#............#....#......#. +..#.........#.......#..................#..#.#...#........#.#.......#...##.#........#..........#.#..........#..#.....#.........#.... +..#...............#...................##.#.......#...#..........#....................##.........#.................#..#......##..#.. +.#........#.......#............##...........##........#.......................#................#....................#...###......#. +........###..........#..............#.............#..#.#.#............##...............#........#...#........#...................#. +...#............................#...##.##........#......#..#...................#.#.....#...#.##...............#........#...#....... +..#...##....................#.....##......#.......#..........#......#.........#...#..............#..............#.................. +.....#..#....................#....###.....#..#.............#...#....#................#.....#.....................#........#........ +.....#.#...#.....#..............##............#....##.#....#.#........##...........#....#.........................#....#......##... +....#..#.....##...........#.#.#.#............#....#.....#.........#........................##.......#.#..............##...#........ +...............#..............#................................#....#........#.......#.......##......#.#............#......#....#.. +.#......#....##........#.............#..#.#.............#...#..#.........#.........#................#..................#........... +.........#..............#....#......#.....##......#............#....#.........#....#...................#....#.........#......#..#.. +..............................#....#.#........#.#.....#..#.................#....#...#..........#............##.......#.#.#....#.... +.#..................#....#..#.......#.##..............#...#.......#................#............................................... +.#..##.........................#.....###......#....#......#.....#............#.#......##......##......##....#..........##.....#.... +..........................##.#.....#..........................................#.#..#....#..#..................#...........#........ +..##.....#.......#....#.........#..........#....................#.........#........###........................#..........#......... +.#.#...............#..........#.......#.....#....##.#..#.##...............#...#...#.#......#.......#.......#.#.............#....##. +..................#...............##.........##..#........#..#..........#.....................#............................#....... +.....#................#...##.......##.........#.....#.#....#.#........#...#..#....#..............#..#....#....#....#............... +..##.#........#...............#.#..#...................##...#......#.#...#..#.....##.................##...#.#...................#.. +...#...............#......#.....#.......#......#.........#...#......#...#..#....#..#......#.......#.......#...#.##.#...........##.. +..............##..........##..........#..##...............#...........##..#..#..#.#.......#...#.............#...................... +..........#.#........................#...#.#..#.#...##..#.#.#.#.......#....#.#.#..............#...#...#........###..##...........#. +......................#...#.#..##.....#....#.....###.#..#.....#..........#........#...........##...#..#...........##..#............ +..................................####.#..............#.................#........#.#............##......#.#..........#............. +..................#..........#.............................#...........#..#..#......#................#.......##...##..#............ +....................#...#....#.#.#.##......#................#.................#...........#....#..........#....#...##.###.......... +.................#.......#...#............###.###..#.......#......#.......#..##......#.#.....#.....................#............... +.................................................................S................................................................. +.......##...........#.........###.......#....###.#.#....#.#....#....#........#.......#...#...#.#.........#...................#..... +.......#...............#............#...#..#.......##...#...#.#............#.............#......##..........#..............#....... +.......##.........#.....................##...#...#.................#...#.......#..####......#.....#..............#..##............. +........#..#.............#.#..##..............#...#.............#.....#......#...#.#.......#...............##...##................. +.........#..#...#..#.#..#..#...................##......#.....#..#...##..............#......#..........#.##...#.#.##.#.............. +..............#..........#....................................#.........#.......#..#............##................#................ +...........#...#.....#.........#....#..###....#...#.......#....#...............##.....#.......#.#.....#.#....#.#..#................ +..#...................#........###..............#.#................#...###...##.............#.###......#...#...#.....#..........#.. +.#.#............#.....#....###......................................#..........................#..................#................ +................#..#...#................#.................##.................##..........#.......#...#.............#............... +.....##...........#....#.......#......#.#.....#.....#................#.....#.........#..#.................#........#........#...... +.#.#.............#..#.#..............#.....#..#.#.....#..#......#.........#.....#.#......#..#.......#.#......##............#..#.... +...................#............#....#...........#........#...................#.....##..............#........###...............#... +......###..........###.#.......#.................................................#..#.........#.#...#.........#.#..........#.#..... +..#.................#..#..#...#............#...#...#..##.#....##..#..................##.....#......#.........................#...#. +......................#.#.....#.#...#.......##...........#...#....#.............#.......#.............#.#.#.#...................... +......#..#.#..........#....#.........#......#................#.........##.#....#.......#........#.#....................#......#.... +..#....#....#...............#..........#...#.#......#...................#.........#..#.#......#..#.........................##....#. +..............#..........##......#.##...#...#.#................#...#..#.......#.#.....#........#...###..##.........#..##.........#. +........##...........................##.......#.#..................#........#.......#.#........#.........................##....#... +..#.#...........#.......................#.#.....#....#.....#...............####...#..............#...#....................#.#...... +.......#...#....#.#.......#####...##.....#.#.......#....#.#........#................................#.##..........##....#..#....... +.........#.....#................##.#..................#.....................#...#................#.###.#.......###....#............ +............#.#....#........#....#..................#...##.............#............#.......#.....#..#............##............... +....#.....#..........#..............#...#...#........##.....#.#....#....#........##.............................#.#.......#........ +..#..#.#.......#.................#................................#......##.#..#..............#.#................#...#.#........... +.....#.....#........................#..#................#......#.......#.........###.#.#.........#.........#.....#.......#......... +.......#.......................................#.......#...............#.#..###...#.#.##.......#...........#.#.....#.##........#... +......##.........#.................................#.........#........##.#................#.#...#.............#...#..#........#.... +......#.....#.#.......#...........#..#...........#.........#..#.#.......#.........##.....#....#.#...............#...#...#....#...#. +..#...#.#....#....#..............................#..#...#.......#.#.#..##..................#...............#......#..###..#.#...... +.....#...#..#......#.....##...............#..........#..#.#####.......#...........#...................#.....#...#.........#..#.#... +.................#.......#..................#........#.......##...##.#....#.#.............#.............#....#....#................ +...........####..#.....#....#.............#.......#...#..#.....#.............#...#....#.............#.#....#.#.............#....... +...#..#..#...#...#.#.....#.......................#....#..###.###.....#.........#....................#....#..#............#.....#... +.#.##....##...#......#.#.....#......................#.##..................#........#..#................#.#.......#.............#... +....##........#.......#..#..#............#..#..#..#...#......###..#..#..#...##...............................#.#........#......#.#. +..#..#..........#..........#..#.#.............#.....#...........#.##.......#............................#...........#...#.......... +..#.#..#...#....#.....#.....#...#................#.....#.....#....#..#...#..#....#....#.....................#....#................. +.......#........#...#.............#.................#...#.#.....#.#....#..........#......................#..#............#......... +....#........#........#..............#.........................#...................#..........#.........#..#.........#............. +................#........#.........#............................#.#.............#..##.......#......#..#.................#......#.#. +..#.....#.........#...#..#.#.........................#...#...#...........#.....#...........#........#.............#.....#........#. +....#...#....#......#....#...#..#.................#...##.....#.#............................##...#...#..##.#.....................#. +...#..##...............#............................#...........#......#.#.....#............#........#.##................#......... +................#..#.............#..#..............#.#....#...#.#...#...#.#.##.............................#..#...........#........ +.......#.......#....###............#.#.#.....................#.#..#....#.................##.....#.#..........##..#......#.......... +.......#..........##.#.......#.##...#...............##.....#..........#................#............#...#........#........#........ +...###.#.............................#.....#.#............##..#...#.....###..........#...............................#.....#....#.. +....###.#...#.......#.##........#......#..##.#..........#.#...#.#....#.#..............##....#..#...#...........#...#.#..#.......... +.....#....#.#..##.....#..........#..#...##..............#.......#.......#.............#..#.....#.......#.....#...##...###.......#.. +........##...#...##..#.#.....#..........................#.#.#..#..#...................#....#....#..#....#..........#....##......... +...........##.....#...#........##..#........#....#..........#..#...............................................#......#.#.......#.. +...#..##.........##....#...........##...#.......##.........#........#...........#........#.#.##...........#....#.....###...#....... +...#...#........................#..#...#..#........................................#......#..#...#.#....#...........#.............. +...#..#.......#..#......##...................#...............#.....#.#.............#.....#.........#.#..##.....#..........#..#..... +....###....#..#.....#.#........#.##.......##...#...............#...............###.###.#...#............##.....#.................#. +....#...#.........#.##............#.....#........#............................................##.#......#..##.........#....###..#.. +............#...##..#..........#........#.......#.#..........................#..#.#.......#......#.......................##.#..#... +....#......#....#....#..#.....#........#......#....#..#.#..............................#..#....#............#....#................. +..#.............#...#......#...#.....................#.##...............................##...#.......#........................#.##. +....#....##........#..............#....#.......#.....................................#........#........#...##..........#........... +....#.#.##..#..#....................#.................#.##.............#....#....#.............###...#...#..##....#.....##......... +.............#.......#...............#........#.#.....#..#.#................#.....#..##.....#....#...............#....#......#...#. +................................................................................................................................... diff --git a/21/src/main.rs b/21/src/main.rs new file mode 100644 index 0000000..53f1a6c --- /dev/null +++ b/21/src/main.rs @@ -0,0 +1,202 @@ +use core::panic; +use std::collections::HashSet; +use indicatif::{ProgressBar, ProgressStyle}; +use petgraph::algo::k_shortest_path; +use petgraph::prelude::*; +use rayon::prelude::*; +use std::fs::File; +use std::io::{BufRead, BufReader, Lines}; +use std::time::Instant; + +// BOILERPLATE +type InputIter = Lines>; + +fn get_input() -> InputIter { + let f = File::open("input").unwrap(); + let br = BufReader::new(f); + br.lines() +} + +fn main() { + let start = Instant::now(); + let ans1 = problem1(get_input()); + let duration = start.elapsed(); + println!("Problem 1 solution: {} [{}s]", ans1, duration.as_secs_f64()); + + let start = Instant::now(); + let ans2 = problem2(get_input()); + let duration = start.elapsed(); + println!("Problem 2 solution: {} [{}s]", ans2, duration.as_secs_f64()); +} + +// PARSE + +type Position = (usize, usize); +type Offset = (isize, isize); + +#[derive(Debug, Clone)] +struct MapTile { + c: char, + idx: NodeIndex, +} + +impl MapTile { + fn new(c: char, idx: NodeIndex) -> Self { + Self { c, idx } + } +} + +type GraphType = DiGraph; +struct GardenMap { + map: Vec>, + graph: GraphType, + start: Position, +} + +impl From> for GardenMap { + fn from(lines: Lines) -> Self { + let mut graph = DiGraph::new(); + let map = lines + .map(|line| { + line.unwrap() + .chars() + .map(|c| MapTile::new(c, graph.add_node(c))) + .collect() + }) + .collect(); + let mut new = Self { + map, + start: (0, 0), + graph, + }; + new.find_start(); + new.build_graph(); + new + } +} + +const ADJACENCIES: [Offset; 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)]; + +impl GardenMap { + fn width(&self) -> usize { + self.map[0].len() + } + fn height(&self) -> usize { + self.map.len() + } + fn at(&self, pos: &Position) -> &MapTile { + &self.map[pos.1][pos.0] + } + fn at_mut(&mut self, pos: &Position) -> &mut MapTile { + &mut self.map[pos.1][pos.0] + } + // return the valid 'moves' from pos + fn adjacent_to(&self, pos: &Position) -> Vec { + ADJACENCIES + .iter() + .filter_map(|ofs| self.offset_pos(pos, ofs)) + .filter(|pos| self.at(pos).c == '.' || self.at(pos).c == 'S') + .collect() + } + fn offset_pos(&self, pos: &Position, ofs: &Offset) -> Option { + let new_pos = (pos.0 as isize + ofs.0, pos.1 as isize + ofs.1); + if new_pos.0 < 0 || new_pos.1 < 0 || new_pos.0 >= self.width() as isize || new_pos.1 >= self.height() as isize { + return None; + } + return Some((new_pos.0 as usize, new_pos.1 as usize)); + } + fn find_start(&mut self) { + for (y, row) in self.map.iter().enumerate() { + for (x, tile) in row.iter().enumerate() { + if tile.c == 'S' { + self.start = (x, y); + return; + } + } + } + panic!("didn't find the start square!"); + } + fn build_graph(&mut self) { + for y in 0..self.height() { + for x in 0..self.width() { + for (x2, y2) in self.adjacent_to(&(x, y)) { + self.graph.add_edge(self.at(&(x, y)).idx, self.at(&(x2, y2)).idx, ()); + } + } + } + } + fn reachable_after(&self, from: &Position, n: usize) -> HashSet { + let mut visited_after: Vec> = Vec::new(); + visited_after.push(HashSet::from([*from])); + for i in 1..n + 1 { + visited_after.push( + visited_after[i - 1] + .iter() + .flat_map(|last| self.adjacent_to(last)) + .collect(), + ); + } + + visited_after[n].clone() + } + fn reachable_count_after(&self, from: &Position, n: usize) -> u64 { + self.reachable_after(from, n).len() as u64 + } +} + +fn print_visited(map: &GardenMap, visited: &Vec>) { + for (y, row) in visited.iter().enumerate() { + for (x, cell) in row.iter().enumerate() { + print!("{}", if *cell { 'O' } else { map.at(&(x, y)).c }); + } + println!(); + } +} + +// PROBLEM 1 solution + +fn problem1_impl(input: Lines, n: usize) -> u64 { + let map = GardenMap::from(input); + // println!("map: {:?} start: {:?}", map.map, &map.start); + + map.reachable_count_after(&map.start, n) +} + +fn problem1(input: Lines) -> u64 { + problem1_impl(input, 64) +} + +// PROBLEM 2 solution +fn problem2(input: Lines) -> u64 { + 0 +} + +#[cfg(test)] +mod tests { + use crate::*; + use std::io::Cursor; + + const EXAMPLE: &str = &"........... +.....###.#. +.###.##..#. +..#.#...#.. +....#.#.... +.##..S####. +.##..#...#. +.......##.. +.##.#.####. +.##..##.##. +..........."; + + #[test] + fn problem1_example() { + let c = Cursor::new(EXAMPLE); + assert_eq!(problem1_impl(c.lines(), 6), 16); + } + + #[test] + fn problem2_example() { + let c = Cursor::new(EXAMPLE); + assert_eq!(problem2(c.lines()), 0); + } +}