diff --git a/Cargo.lock b/Cargo.lock index 9223647..7e8746c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,6 +182,13 @@ dependencies = [ "priority-queue", ] +[[package]] +name = "day-18" +version = "0.0.0" +dependencies = [ + "indoc", +] + [[package]] name = "deprecate-until" version = "0.1.1" diff --git a/day-18/Cargo.toml b/day-18/Cargo.toml new file mode 100644 index 0000000..c1c3503 --- /dev/null +++ b/day-18/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "day-18" +version = "0.0.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[dev-dependencies] +indoc.workspace = true diff --git a/day-18/src/bin/input.txt b/day-18/src/bin/input.txt new file mode 100644 index 0000000..23db3ac --- /dev/null +++ b/day-18/src/bin/input.txt @@ -0,0 +1,738 @@ +L 4 (#3db750) +U 10 (#0e0433) +L 5 (#526490) +U 6 (#3e9193) +L 4 (#526492) +U 5 (#4418e3) +L 5 (#3ad2e0) +U 5 (#579f63) +L 4 (#118202) +D 5 (#411263) +L 5 (#135ac2) +U 4 (#1196f3) +L 4 (#5df7d2) +U 5 (#22e353) +L 4 (#1615c2) +U 5 (#17bc73) +L 9 (#038720) +U 6 (#16cff3) +L 7 (#57beb0) +U 4 (#16cff1) +L 6 (#3da480) +U 8 (#43bb73) +R 4 (#2c2540) +U 8 (#374033) +R 9 (#4f95d0) +U 7 (#374031) +L 9 (#0ff0e0) +U 8 (#12b433) +L 3 (#29b7c0) +U 5 (#57fa93) +L 4 (#3b4d90) +U 5 (#175463) +L 7 (#2945d0) +U 3 (#151b23) +R 6 (#34c720) +U 2 (#1f0a03) +R 8 (#3d8772) +U 4 (#3eba93) +R 7 (#0e4442) +U 2 (#012851) +R 2 (#2618e2) +U 8 (#5ca961) +L 3 (#0a2972) +U 3 (#5980f3) +L 4 (#43a0a2) +U 2 (#0450c3) +L 8 (#09fae2) +U 3 (#320053) +R 4 (#52e1a0) +U 4 (#03ce91) +R 8 (#330070) +U 3 (#03ce93) +L 5 (#43c770) +U 3 (#3d18a3) +L 8 (#488e60) +U 5 (#2d0d63) +L 7 (#1e78d0) +D 4 (#1680c3) +L 9 (#31ee60) +D 3 (#483563) +L 4 (#0c6710) +D 3 (#467ed3) +R 3 (#02df40) +D 2 (#1e2ad3) +R 10 (#3f20c2) +D 4 (#447ef3) +L 5 (#3f20c0) +D 7 (#07f723) +L 6 (#1a71e2) +D 7 (#23f173) +L 2 (#079be2) +D 2 (#5cd243) +L 7 (#3d9fc2) +D 3 (#107ee3) +L 3 (#165230) +D 4 (#69e463) +L 9 (#2159c0) +D 2 (#1dd863) +L 4 (#47e9a0) +D 4 (#1bff13) +R 10 (#12df90) +D 3 (#364e23) +R 3 (#517e12) +D 3 (#0a71a3) +L 8 (#2edfe2) +D 8 (#339f93) +L 5 (#27d7e0) +D 8 (#4a91f3) +L 8 (#44e320) +D 9 (#0ea943) +L 4 (#13a2f0) +D 5 (#6356e3) +R 10 (#05f220) +D 4 (#2644a3) +R 8 (#65bb92) +D 4 (#2ae573) +R 10 (#65bb90) +D 4 (#312573) +L 8 (#3b10c0) +D 6 (#154f21) +L 5 (#018462) +D 5 (#552bb1) +L 7 (#018460) +D 4 (#0a3be1) +L 3 (#2efbf0) +D 12 (#17a7c1) +L 4 (#30d400) +U 4 (#624c61) +L 7 (#38d3f0) +U 3 (#214351) +L 11 (#027d02) +U 4 (#3bdac1) +L 7 (#027d00) +U 6 (#13f621) +R 6 (#1c4f70) +U 6 (#1c1f81) +R 5 (#30ce40) +D 6 (#149481) +R 7 (#0d93b0) +U 5 (#491791) +R 7 (#50ae60) +U 5 (#128a91) +L 4 (#1f7990) +U 7 (#010331) +L 6 (#253e60) +U 6 (#1f2643) +L 3 (#232c10) +U 5 (#3d8083) +L 6 (#294c32) +U 10 (#3fcf53) +L 3 (#294c30) +U 7 (#1c9cd3) +L 8 (#26b342) +U 2 (#2107e3) +L 6 (#26b340) +U 6 (#3a17c3) +L 8 (#232c12) +D 6 (#3199c3) +L 7 (#34c162) +U 9 (#0a6463) +L 4 (#2f5132) +U 9 (#1ef1c3) +R 6 (#2318c0) +U 3 (#21b8f3) +R 3 (#40f9d0) +D 7 (#1a5473) +R 4 (#28adf0) +D 2 (#2e6181) +R 7 (#00d3f2) +U 9 (#355a41) +R 3 (#00d3f0) +D 10 (#1b04c1) +R 2 (#0ddf40) +D 3 (#298111) +R 4 (#42a8e0) +U 2 (#5b93c1) +R 4 (#4282b0) +U 11 (#25af91) +R 3 (#0ff3e0) +U 7 (#002661) +R 5 (#365a20) +U 10 (#3382c1) +R 6 (#3a83a0) +U 3 (#376591) +R 7 (#0894a0) +U 6 (#379891) +R 5 (#44e3d0) +U 3 (#41e791) +R 6 (#0133c0) +U 4 (#070071) +R 4 (#0627e0) +U 4 (#33bea1) +R 7 (#456812) +U 5 (#5ac051) +R 7 (#4254e2) +U 7 (#49a231) +R 5 (#0e82b2) +U 3 (#14b5a1) +R 4 (#320942) +D 8 (#126031) +R 8 (#103262) +U 7 (#3b7aa1) +R 4 (#103260) +U 5 (#30f9c1) +R 5 (#29ced2) +D 8 (#1ac681) +R 7 (#62bf32) +D 4 (#1a4041) +R 4 (#14df02) +U 8 (#443071) +R 4 (#47db32) +D 10 (#1b21b3) +R 4 (#129c02) +D 2 (#3e68b3) +R 11 (#533d52) +D 3 (#09d713) +R 3 (#058242) +D 6 (#52db63) +L 7 (#1c7002) +D 5 (#65d703) +L 4 (#1c7000) +D 7 (#0965f3) +R 6 (#1c20e2) +D 7 (#1d2273) +R 5 (#4389b2) +D 5 (#044e11) +R 4 (#27a040) +D 2 (#1178a1) +R 6 (#120170) +D 9 (#44ebc1) +R 3 (#120172) +D 9 (#152cc1) +R 4 (#27a042) +U 3 (#1f7081) +R 12 (#2fcb02) +U 2 (#1d0f31) +R 8 (#42cb20) +U 4 (#43ab11) +L 4 (#42cb22) +U 2 (#377091) +L 9 (#3b2d12) +U 3 (#1b21b1) +L 7 (#51b2b2) +U 6 (#3caf91) +R 10 (#4018c2) +U 5 (#2d7c51) +L 5 (#525612) +U 4 (#0c3071) +L 4 (#16b6f2) +D 6 (#400511) +L 7 (#263730) +U 6 (#13acb1) +L 4 (#42d5d0) +U 3 (#47f3a1) +R 9 (#4018c0) +U 7 (#154771) +R 2 (#2fbd52) +U 3 (#3a1df1) +L 8 (#51aed2) +U 7 (#4edb11) +L 3 (#120e82) +U 7 (#64c5f1) +R 9 (#0937d2) +U 4 (#1c4f21) +R 7 (#4551f2) +U 5 (#5a5493) +R 4 (#1edfb2) +U 5 (#169093) +R 10 (#37eac2) +D 3 (#188731) +R 5 (#0f1a82) +D 5 (#585df1) +R 3 (#120232) +D 2 (#2ae331) +R 8 (#2287d2) +D 5 (#103e81) +R 6 (#4690b0) +D 4 (#0772d3) +R 7 (#3305c0) +D 3 (#0772d1) +L 10 (#38f400) +D 6 (#380261) +L 6 (#29e240) +D 6 (#06f581) +L 5 (#439b60) +U 12 (#201da1) +L 3 (#402420) +D 6 (#144c91) +L 9 (#22f100) +D 4 (#3870e1) +R 6 (#0c31f2) +D 2 (#03ac33) +R 3 (#5bc432) +D 9 (#137063) +R 3 (#26ea62) +U 4 (#137061) +R 6 (#450eb2) +D 9 (#03ac31) +R 5 (#43b222) +U 9 (#05c961) +R 5 (#4055d0) +D 4 (#20af11) +R 7 (#1c10f0) +D 5 (#3943c1) +R 2 (#26e682) +D 4 (#1129c1) +R 8 (#358042) +D 4 (#070c01) +R 5 (#2956d2) +U 7 (#191821) +R 3 (#224300) +U 3 (#2af351) +R 2 (#0feeb0) +U 6 (#23cac1) +L 5 (#5dfd50) +U 5 (#2a7f41) +L 3 (#527870) +U 5 (#2a7f43) +L 8 (#4aaf60) +U 9 (#287f01) +L 2 (#13a150) +U 4 (#269d21) +R 10 (#35e962) +U 7 (#281351) +R 8 (#35e982) +U 4 (#281353) +R 9 (#15be82) +U 3 (#14d581) +R 3 (#251f22) +D 3 (#42a4e1) +R 4 (#04bf90) +D 9 (#1f56e3) +R 6 (#3438d0) +D 10 (#1f56e1) +R 4 (#36fdd0) +D 9 (#0cd891) +L 4 (#38caa0) +D 6 (#0cd893) +R 6 (#11cc20) +D 7 (#2ca3a1) +L 6 (#3e7d60) +D 7 (#271f11) +R 4 (#20ba00) +D 6 (#53c2b3) +R 3 (#11a9f0) +D 7 (#34ada3) +R 8 (#567fe2) +D 7 (#1f43f3) +R 7 (#10e032) +D 3 (#515b63) +R 7 (#1a0d52) +D 2 (#06c953) +R 3 (#1bd910) +D 8 (#339df3) +R 6 (#483b90) +D 8 (#2b9943) +R 5 (#040ff0) +D 8 (#249a13) +R 2 (#4a2a82) +D 2 (#2be7b3) +R 10 (#1dfa12) +U 4 (#23ec53) +R 4 (#4e4080) +U 4 (#431f73) +R 7 (#332ce0) +U 7 (#151433) +L 6 (#532250) +U 6 (#281c83) +R 6 (#3b2fa0) +U 3 (#580361) +R 2 (#381920) +U 4 (#423571) +R 3 (#365c20) +D 10 (#357b83) +R 4 (#2bc910) +U 10 (#17cef1) +R 6 (#0d2f50) +U 2 (#496f61) +R 5 (#0d2f52) +U 4 (#0a78e1) +L 5 (#0db930) +U 6 (#057ac3) +L 5 (#065930) +D 6 (#4034b3) +L 5 (#065932) +U 5 (#2607c3) +L 3 (#3772f0) +U 6 (#260ff3) +R 6 (#0a16c2) +U 5 (#0984c3) +L 6 (#4ebf82) +U 5 (#0984c1) +L 4 (#181ef2) +U 9 (#1d1d53) +R 4 (#384730) +U 2 (#219013) +R 6 (#065250) +U 6 (#2232b1) +R 5 (#3f4030) +U 5 (#471ca1) +R 6 (#33c210) +U 3 (#37cbe1) +L 7 (#53b020) +U 6 (#070661) +R 6 (#2199f0) +U 9 (#1d8d61) +L 6 (#35c702) +U 4 (#13cc81) +R 7 (#22f592) +U 3 (#36f1d1) +R 6 (#17d3d2) +D 7 (#4a1db1) +R 4 (#161810) +D 12 (#019c31) +R 4 (#46b5a0) +U 9 (#4bc491) +R 4 (#13c2b0) +U 2 (#07bdd1) +R 4 (#1bce00) +U 8 (#48c791) +R 5 (#54aa00) +U 3 (#079a91) +R 5 (#19b550) +D 4 (#2ff601) +R 7 (#1560c2) +D 10 (#3afde1) +R 5 (#1560c0) +D 5 (#19b1e1) +R 4 (#29d140) +D 2 (#1c83b3) +R 6 (#274ae0) +D 9 (#4f3ae3) +R 4 (#2e2280) +U 7 (#12aea3) +R 3 (#121630) +U 9 (#590343) +R 5 (#121632) +D 8 (#0f1813) +R 8 (#2e2282) +D 5 (#01f683) +R 4 (#0b3350) +D 8 (#2582f3) +R 2 (#358bc0) +D 8 (#495e93) +R 2 (#2b6380) +D 6 (#202a83) +R 2 (#025d40) +D 4 (#0600f1) +R 6 (#492c30) +D 9 (#310791) +L 8 (#06d2c0) +D 4 (#328091) +L 2 (#060230) +D 6 (#1d2163) +R 10 (#04a2c0) +D 4 (#201cc1) +R 5 (#047b62) +D 4 (#0e0ec1) +R 4 (#17bd32) +D 7 (#560041) +R 3 (#41b672) +D 5 (#1c40b1) +R 9 (#01fea2) +D 4 (#018691) +L 7 (#13d742) +D 4 (#56c211) +L 5 (#2f7662) +U 4 (#0e8e01) +L 3 (#46d980) +D 5 (#402761) +L 7 (#1e38e0) +D 8 (#402763) +R 3 (#3e28e0) +D 8 (#075c91) +R 3 (#4cd990) +D 2 (#1c83b1) +R 6 (#0df200) +U 6 (#4877c3) +R 2 (#0ab900) +U 4 (#5d14b3) +R 8 (#3f7a60) +D 5 (#061dd3) +R 6 (#265810) +U 3 (#4d7453) +R 4 (#113c80) +U 4 (#300853) +L 6 (#45ab00) +U 2 (#1ced03) +L 6 (#0eace0) +U 5 (#264f53) +R 12 (#41dc40) +U 3 (#199863) +R 5 (#3b2dc2) +U 10 (#0f4223) +R 4 (#482cf2) +D 5 (#1face3) +R 8 (#321642) +U 4 (#56f7a3) +R 4 (#321640) +U 10 (#2b6ef3) +R 5 (#325182) +D 5 (#4040a1) +R 5 (#02d5b2) +D 9 (#61d2d1) +R 8 (#3d5d32) +D 4 (#0f4221) +L 7 (#176402) +D 4 (#03b113) +L 8 (#01d860) +D 3 (#136273) +L 7 (#206090) +D 9 (#0ed183) +R 3 (#21eee0) +D 3 (#4b9c73) +R 4 (#27e9e2) +D 5 (#097b83) +R 5 (#27e9e0) +U 5 (#50f633) +R 5 (#16b820) +D 4 (#138331) +R 5 (#34b750) +D 8 (#5413f1) +R 7 (#134940) +D 7 (#4d4881) +L 6 (#53aa40) +D 7 (#00d6d1) +L 5 (#0a3520) +U 12 (#3c9a03) +L 3 (#4c3bd0) +U 5 (#3c9a01) +L 7 (#24a000) +D 10 (#0fb971) +R 5 (#4631b2) +D 3 (#3f5441) +L 8 (#01d1e0) +D 6 (#46ff21) +R 8 (#3ee970) +D 6 (#00a091) +L 5 (#51a350) +D 4 (#00a093) +L 8 (#46c180) +U 4 (#365041) +L 2 (#47fbe2) +U 4 (#226d01) +R 4 (#67b392) +U 10 (#226d03) +L 4 (#191b92) +U 4 (#416111) +L 2 (#105522) +U 7 (#5b2ce1) +L 7 (#4631b0) +D 8 (#334d41) +L 7 (#1e4350) +D 6 (#3021b1) +L 3 (#299130) +D 3 (#2b4123) +L 3 (#414a00) +U 5 (#2b4121) +L 8 (#0fafb0) +U 2 (#254f91) +L 4 (#3b0f82) +U 4 (#070d61) +L 4 (#0a6292) +U 6 (#070d63) +L 6 (#3518d2) +D 7 (#2b8b01) +L 7 (#1a4b62) +D 3 (#27a0c1) +L 5 (#66c7d2) +D 6 (#37f161) +R 3 (#482732) +D 5 (#1baa01) +R 9 (#45b112) +D 2 (#1baa03) +R 6 (#07fad2) +D 4 (#2f35a1) +R 5 (#4d0002) +D 6 (#1fa731) +L 8 (#696b42) +D 6 (#31c791) +L 9 (#08fd42) +D 2 (#0052f1) +L 3 (#065eb2) +D 5 (#2418b1) +L 5 (#3dbd92) +D 9 (#10bcf1) +L 5 (#09a212) +D 7 (#4ac071) +L 2 (#0c2842) +D 4 (#0299a1) +L 6 (#39aa72) +D 5 (#1eaff1) +L 3 (#302492) +U 4 (#4588d1) +L 8 (#13af62) +D 4 (#35a861) +L 7 (#4c5b02) +U 5 (#2dd353) +L 3 (#0077d2) +D 5 (#0ba793) +L 12 (#38e632) +D 5 (#476a13) +L 5 (#35f252) +U 7 (#5311a1) +L 2 (#047cf2) +U 8 (#267d63) +R 4 (#0affa2) +U 9 (#6a7183) +R 4 (#25b702) +U 7 (#0ab9d3) +L 11 (#1dd902) +U 2 (#0f0bd3) +R 11 (#17dea2) +U 6 (#0c2d03) +R 5 (#18de02) +D 11 (#52bf93) +R 4 (#18de00) +D 4 (#1199a3) +R 4 (#0ddee2) +U 3 (#063403) +R 6 (#46dcc2) +U 5 (#11b683) +R 7 (#0f98c2) +U 3 (#610763) +R 6 (#17f292) +U 6 (#312333) +R 4 (#2fd3e2) +U 4 (#083981) +L 6 (#4b2332) +U 5 (#083983) +L 7 (#161f42) +U 3 (#097733) +R 8 (#079502) +U 5 (#28a1b1) +R 5 (#60e982) +U 5 (#174aa1) +L 4 (#60e980) +U 7 (#2d1801) +L 5 (#3a7fc2) +U 6 (#267c01) +L 8 (#10ae32) +U 5 (#64c141) +L 3 (#39bea2) +U 4 (#0061e1) +L 2 (#03c742) +U 9 (#00fa21) +L 5 (#3f4a42) +D 13 (#0048e1) +L 3 (#21f600) +U 5 (#13e0d1) +L 5 (#57fcf0) +D 5 (#13e0d3) +L 9 (#4e0b20) +U 5 (#2fbea1) +L 10 (#1d7ee2) +D 6 (#5a3821) +L 4 (#187d12) +D 6 (#02da81) +L 5 (#39b022) +D 6 (#1e48d1) +L 5 (#0a01a2) +D 3 (#4f90e1) +L 7 (#0b91d2) +D 6 (#269903) +L 4 (#322902) +U 5 (#412583) +L 10 (#322900) +D 5 (#07dcc3) +L 4 (#416db2) +D 2 (#0118f3) +L 6 (#002942) +D 3 (#46c203) +R 10 (#1ec1c2) +D 7 (#0b31d1) +L 10 (#48d2b2) +D 6 (#499a71) +L 4 (#00dc22) +D 3 (#1adf01) +R 10 (#20c8b2) +D 8 (#2376b3) +L 10 (#34ebc2) +D 8 (#119bd3) +R 4 (#393252) +D 12 (#3a98c3) +L 3 (#6119f2) +D 10 (#22a903) +L 8 (#0f5442) +U 9 (#4466f1) +L 6 (#32ebf2) +U 6 (#291b41) +L 8 (#089fc2) +U 3 (#171d13) +L 6 (#4607a2) +U 6 (#3a53d3) +L 3 (#4607a0) +D 4 (#1c1153) +L 5 (#3aa062) +D 3 (#07ed63) +L 10 (#285362) +D 3 (#2033d3) +R 8 (#053532) +D 7 (#550e63) +R 7 (#233902) +D 7 (#159493) +L 3 (#428bc2) +D 3 (#4d6bc3) +R 10 (#434cf2) +D 2 (#220413) +R 5 (#3b8d52) +D 5 (#2d9a53) +L 6 (#24c242) +D 6 (#192663) +R 4 (#084250) +D 5 (#42e773) +L 4 (#580d40) +D 3 (#221923) +L 3 (#2c4a70) +U 5 (#1955e3) +L 2 (#22aa00) +U 9 (#325ae3) +L 4 (#45a220) +D 5 (#1b6af3) +L 5 (#2e7230) +U 7 (#47b843) +L 6 (#4786f0) +U 8 (#004a03) +L 8 (#25caa0) +D 4 (#2857e3) +L 6 (#2bc040) +D 7 (#216fc3) +L 5 (#28ac22) +D 4 (#0c70e1) +L 4 (#27c792) +D 9 (#0c70e3) +L 8 (#3ccc22) +U 10 (#236703) +L 5 (#248f22) +U 5 (#351f23) +L 8 (#1cdae2) +U 9 (#196223) +L 4 (#262512) +U 5 (#18a9e1) +L 6 (#374d42) +U 9 (#35d761) +L 3 (#1a1ad2) +U 2 (#357863) +L 5 (#124822) +U 5 (#02f933) +L 3 (#09dcf2) +U 3 (#51fde3) +L 8 (#09dcf0) +U 7 (#41c033) +L 6 (#1ddaf2) +U 7 (#15c193) +L 3 (#609412) +U 7 (#0a4e23) +L 8 (#2d99f2) +U 5 (#01ac13) \ No newline at end of file diff --git a/day-18/src/bin/part1.rs b/day-18/src/bin/part1.rs new file mode 100644 index 0000000..0c2f629 --- /dev/null +++ b/day-18/src/bin/part1.rs @@ -0,0 +1,124 @@ +fn main() { + println!("{}", part1(include_str!("./input.txt"))); +} + +fn part1(input: &str) -> i32 { + let instructions = input + .lines() + .map(|line| Instruction::try_from(line).expect("invalid instruction")) + .collect::>(); + + let (corners, length) = + instructions + .iter() + .fold((vec![(0, 0)], 0), |(mut corners, length), instruction| { + let last_corner = corners.last().unwrap(); + let new_corner = match instruction.direction { + Direction::Up => (last_corner.0, last_corner.1 - instruction.distance), + Direction::Down => (last_corner.0, last_corner.1 + instruction.distance), + Direction::Left => (last_corner.0 - instruction.distance, last_corner.1), + Direction::Right => (last_corner.0 + instruction.distance, last_corner.1), + }; + corners.push(new_corner); + (corners, length + instruction.distance) + }); + + // shoelace formula with edges also du out + corners + .iter() + .zip(&corners[1..]) + .map(|(v1, v2)| (v1.0 - v2.0) * (v1.1 + v2.1)) + .sum::() + .abs() + / 2 + + length / 2 + + 1 +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct Instruction { + direction: Direction, + distance: i32, + color: u32, +} +impl TryFrom<&str> for Instruction { + type Error = &'static str; + + fn try_from(s: &str) -> Result { + let mut parts = s.split_whitespace(); + let direction = + Direction::try_from(parts.next().expect("no direction").chars().next().unwrap()) + .expect("invalid direction"); + let distance = parts + .next() + .expect("no distance") + .parse::() + .expect("invalid distance"); + let color = u32::from_str_radix( + parts + .next() + .expect("no color") + .trim_start_matches("(#") + .trim_end_matches(')'), + 16, + ) + .expect("invalid color"); + Ok(Self { + direction, + distance, + color, + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Direction { + Up, + Down, + Left, + Right, +} +impl TryFrom for Direction { + type Error = &'static str; + + fn try_from(c: char) -> Result { + match c { + 'U' => Ok(Self::Up), + 'D' => Ok(Self::Down), + 'L' => Ok(Self::Left), + 'R' => Ok(Self::Right), + _ => Err("invalid direction"), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn test_part1() { + assert_eq!( + part1(indoc!( + " + R 6 (#70c710) + D 5 (#0dc571) + L 2 (#5713f0) + D 2 (#d2c081) + R 2 (#59c680) + D 2 (#411b91) + L 5 (#8ceee2) + U 2 (#caa173) + L 1 (#1b58a2) + U 2 (#caa171) + R 2 (#7807d2) + U 3 (#a77fa3) + L 2 (#015232) + U 2 (#7a21e3) + " + )), + 62 + ); + } +} diff --git a/day-18/src/bin/part2.rs b/day-18/src/bin/part2.rs new file mode 100644 index 0000000..12eae14 --- /dev/null +++ b/day-18/src/bin/part2.rs @@ -0,0 +1,119 @@ +fn main() { + println!("{}", part2(include_str!("./input.txt"))); +} + +fn part2(input: &str) -> i64 { + let instructions = input + .lines() + .map(|line| Instruction::try_from(line).expect("invalid instruction")) + .collect::>(); + + let (corners, length) = + instructions + .iter() + .fold((vec![(0, 0)], 0), |(mut corners, length), instruction| { + let last_corner = corners.last().unwrap(); + let new_corner = match instruction.direction { + Direction::Up => (last_corner.0, last_corner.1 - instruction.distance), + Direction::Down => (last_corner.0, last_corner.1 + instruction.distance), + Direction::Left => (last_corner.0 - instruction.distance, last_corner.1), + Direction::Right => (last_corner.0 + instruction.distance, last_corner.1), + }; + corners.push(new_corner); + (corners, length + instruction.distance) + }); + + // shoelace formula with edges also du out + corners + .iter() + .zip(&corners[1..]) + .map(|(v1, v2)| (v1.0 - v2.0) * (v1.1 + v2.1)) + .sum::() + .abs() + / 2 + + length / 2 + + 1 +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +struct Instruction { + direction: Direction, + distance: i64, +} +impl TryFrom<&str> for Instruction { + type Error = &'static str; + + fn try_from(s: &str) -> Result { + let mut parts = s.split_whitespace(); + let hex = parts + .nth(2) + .expect("no color") + .trim_start_matches("(#") + .trim_end_matches(')'); + let distance = i64::from_str_radix(&hex[0..5], 16).map_err(|_| "invalid distance")?; + let direction = match hex.chars().nth(5).ok_or("no direction")? { + '0' => Direction::Right, + '1' => Direction::Down, + '2' => Direction::Left, + '3' => Direction::Up, + _ => return Err("invalid direction"), + }; + + Ok(Self { + direction, + distance, + }) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Direction { + Up, + Down, + Left, + Right, +} +impl TryFrom for Direction { + type Error = &'static str; + + fn try_from(c: char) -> Result { + match c { + 'U' => Ok(Self::Up), + 'D' => Ok(Self::Down), + 'L' => Ok(Self::Left), + 'R' => Ok(Self::Right), + _ => Err("invalid direction"), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + + #[test] + fn test_part2() { + assert_eq!( + part2(indoc!( + " + R 6 (#70c710) + D 5 (#0dc571) + L 2 (#5713f0) + D 2 (#d2c081) + R 2 (#59c680) + D 2 (#411b91) + L 5 (#8ceee2) + U 2 (#caa173) + L 1 (#1b58a2) + U 2 (#caa171) + R 2 (#7807d2) + U 3 (#a77fa3) + L 2 (#015232) + U 2 (#7a21e3) + " + )), + 952408144115 + ); + } +}