diff --git a/18/Cargo.lock b/18/Cargo.lock new file mode 100644 index 0000000..4c9e552 --- /dev/null +++ b/18/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day18" +version = "0.1.0" +dependencies = [ + "itertools", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] diff --git a/18/Cargo.toml b/18/Cargo.toml new file mode 100644 index 0000000..4d457a8 --- /dev/null +++ b/18/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day18" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.12.0" diff --git a/18/input b/18/input new file mode 100644 index 0000000..f27e001 --- /dev/null +++ b/18/input @@ -0,0 +1,640 @@ +L 4 (#248a72) +U 3 (#295c13) +L 4 (#49e802) +U 5 (#5ff8b3) +R 3 (#0df642) +U 2 (#15b973) +R 5 (#6cfb92) +U 11 (#4e3cd3) +L 4 (#422dd0) +D 5 (#303fe3) +L 7 (#6225e0) +D 2 (#58bd63) +L 9 (#6225e2) +D 8 (#2b1703) +L 6 (#422dd2) +D 9 (#2eb9b3) +L 2 (#10f270) +D 10 (#0677b3) +L 4 (#190450) +U 11 (#55b4e3) +L 4 (#361732) +U 3 (#034663) +L 4 (#37f902) +U 6 (#19bb73) +R 8 (#6e1030) +U 8 (#4cad93) +L 4 (#2509d0) +U 6 (#1e1e61) +L 5 (#3d3b90) +U 8 (#28ec81) +L 2 (#3f9200) +U 5 (#437871) +L 6 (#174bc0) +D 5 (#3b58a1) +L 11 (#064a60) +U 5 (#539da3) +L 4 (#1ea0d0) +D 7 (#1909b3) +L 2 (#296a52) +D 9 (#6780c3) +L 3 (#296a50) +U 11 (#356893) +L 2 (#0eb430) +U 5 (#019203) +L 5 (#4eea10) +U 4 (#436533) +L 4 (#20aeb0) +U 4 (#2fb883) +L 6 (#5046c0) +U 11 (#392293) +R 8 (#2567a0) +U 3 (#57ee03) +R 12 (#270540) +U 2 (#358173) +R 6 (#289e40) +U 2 (#77b991) +R 4 (#016c10) +U 11 (#351091) +R 2 (#714f90) +U 6 (#4add71) +L 11 (#00eab0) +D 5 (#2f8361) +L 8 (#192200) +U 5 (#1416c1) +L 13 (#775d30) +U 3 (#3d3d63) +L 8 (#6e4710) +U 3 (#28cfd3) +L 8 (#389880) +U 5 (#28cfd1) +L 7 (#4cd750) +D 5 (#1d56e3) +L 3 (#2789e2) +D 5 (#5d7573) +R 9 (#1b1372) +D 5 (#1965a3) +R 4 (#111052) +D 2 (#5a2861) +R 10 (#37f1c2) +D 3 (#0b7ad1) +R 5 (#012162) +U 5 (#226f43) +R 4 (#583cd2) +D 5 (#4333f3) +R 5 (#0eb952) +D 3 (#22a273) +L 2 (#34c5d0) +D 3 (#355f11) +L 5 (#13a460) +D 4 (#355f13) +L 6 (#3e2900) +U 4 (#28d423) +L 8 (#042432) +D 3 (#4378f3) +L 6 (#18a200) +D 5 (#16a843) +L 5 (#18a202) +D 7 (#46fdd3) +L 5 (#2a4802) +D 5 (#2a4d23) +L 5 (#6049d2) +D 4 (#0a4023) +L 4 (#09afb2) +U 4 (#687713) +L 5 (#4b85f2) +D 4 (#0e1a53) +L 8 (#331b60) +U 6 (#270d83) +L 6 (#331b62) +U 6 (#25dba3) +L 6 (#412e82) +D 6 (#5e2e73) +L 8 (#1de802) +U 6 (#1e7143) +L 4 (#4e7e82) +U 3 (#160d63) +L 5 (#19d230) +U 3 (#36a4a3) +R 3 (#19d232) +U 6 (#4c63b3) +R 10 (#0d2862) +U 5 (#0ec351) +R 11 (#593c62) +U 6 (#12de21) +R 2 (#08d482) +U 4 (#277081) +R 3 (#10eee0) +U 4 (#382b91) +L 4 (#512200) +U 7 (#1279f1) +L 3 (#229312) +U 6 (#422721) +R 6 (#71ddd2) +U 6 (#093871) +R 13 (#0d5622) +D 5 (#093873) +R 7 (#4c34e2) +U 6 (#5b1743) +R 2 (#4779a2) +D 6 (#1cc6e3) +R 7 (#3c13a0) +U 5 (#3b60f3) +R 4 (#3c13a2) +U 9 (#229f83) +R 3 (#0a6ff2) +D 2 (#06d231) +R 8 (#0298b2) +D 11 (#4eb6a1) +R 7 (#0298b0) +U 8 (#438ce1) +R 7 (#0e69e2) +U 5 (#2d3e73) +R 8 (#40b2c2) +U 6 (#64cb53) +L 2 (#40b2c0) +U 3 (#0215c3) +L 3 (#2cbf42) +U 4 (#00c523) +L 7 (#1fc3d2) +D 4 (#68a633) +L 5 (#1fc3d0) +U 5 (#149853) +L 5 (#2cbf40) +U 9 (#0b9613) +L 3 (#1e7f00) +U 8 (#2fc533) +L 7 (#3d7180) +U 3 (#33f3a3) +R 9 (#66d340) +U 2 (#0fa1f1) +R 4 (#0546c0) +D 6 (#4c00b3) +R 8 (#483b50) +U 6 (#4c00b1) +R 4 (#2fc7c0) +U 2 (#0fa1f3) +R 7 (#377280) +U 6 (#200c43) +R 5 (#429ef0) +U 3 (#3a90f1) +R 5 (#226142) +U 4 (#2740c1) +R 5 (#41ac62) +U 3 (#275423) +R 2 (#3ba072) +U 11 (#275421) +R 4 (#27ea92) +D 8 (#402001) +R 2 (#3456c0) +D 6 (#5a4541) +R 3 (#4d1400) +U 4 (#5a4543) +R 6 (#462de0) +U 8 (#3fcdb1) +R 6 (#1f2d90) +U 6 (#4e7851) +R 3 (#41eb30) +D 6 (#4e7853) +R 4 (#1aa1c0) +D 10 (#0a4073) +R 6 (#2134b2) +D 7 (#164e43) +R 4 (#200c72) +D 5 (#3beca3) +R 6 (#7445e0) +U 3 (#2cda83) +R 4 (#7445e2) +U 3 (#475553) +L 5 (#200c70) +U 10 (#23fb33) +R 5 (#2134b0) +U 7 (#3c98d3) +L 4 (#4cfc80) +U 5 (#0f0e71) +R 8 (#3c1d22) +U 10 (#23a311) +R 6 (#05da32) +D 5 (#6229c1) +R 5 (#41f750) +D 8 (#1f4191) +R 3 (#3530f0) +D 13 (#4d3941) +R 3 (#6215e0) +D 9 (#2fe911) +R 6 (#05cf90) +U 4 (#25c901) +R 2 (#335232) +U 12 (#271371) +R 2 (#335230) +U 5 (#2bd1d1) +L 9 (#1ffad0) +U 6 (#6f6bc1) +R 9 (#099600) +U 5 (#13bee1) +R 3 (#5aa820) +U 3 (#3546c1) +R 6 (#4dd5f0) +D 11 (#495be1) +R 6 (#60c8e0) +U 11 (#4bd201) +R 4 (#367f30) +D 4 (#43dbc1) +R 6 (#4bb740) +U 12 (#07ce11) +R 6 (#4b4d70) +D 12 (#3e29e1) +R 5 (#313fc0) +U 4 (#293d51) +R 4 (#1b4860) +U 11 (#514571) +R 4 (#5c11a2) +U 4 (#444841) +R 8 (#5c11a0) +U 2 (#3e6c51) +R 11 (#16dab0) +U 7 (#26baf1) +R 2 (#32e240) +U 5 (#26baf3) +R 6 (#2f0a70) +U 6 (#11a821) +R 3 (#527fc0) +U 7 (#468b31) +R 6 (#0641a0) +U 10 (#20f351) +R 7 (#547a90) +U 12 (#1dbf11) +R 2 (#17d0d2) +U 10 (#159981) +R 6 (#634e12) +U 5 (#4ff021) +R 10 (#006122) +D 6 (#6589a3) +R 3 (#1a74f2) +D 2 (#19b911) +R 12 (#3ed5f2) +D 5 (#28ab31) +R 3 (#09dd82) +D 5 (#614c01) +R 6 (#284d32) +D 9 (#06b521) +R 8 (#4dfad2) +D 7 (#5b0f61) +R 2 (#0fff22) +D 5 (#1e6ff1) +R 2 (#47b352) +D 9 (#29c291) +R 5 (#352ef2) +D 3 (#042d11) +R 4 (#262542) +D 7 (#042d13) +R 4 (#21e8f2) +D 3 (#18cc21) +R 3 (#16ed70) +U 9 (#270ea1) +R 7 (#4391e0) +U 9 (#270ea3) +R 4 (#22bdd0) +D 3 (#3b72b1) +R 7 (#1fd4b2) +D 8 (#01bfe1) +L 7 (#3d18a2) +D 7 (#20dac1) +R 4 (#67d990) +D 4 (#1acd93) +L 7 (#017410) +D 2 (#6e4923) +L 7 (#10bdd0) +D 13 (#0650b3) +L 2 (#072660) +U 13 (#221151) +L 6 (#41d720) +D 3 (#5bc831) +L 4 (#252450) +D 9 (#118de1) +R 6 (#05b1d0) +D 4 (#247721) +R 9 (#2b6b10) +U 4 (#60da41) +R 10 (#470c42) +D 3 (#4fdc91) +R 2 (#470c40) +D 8 (#189db1) +L 5 (#4a1f70) +D 7 (#07e141) +L 3 (#2524b0) +D 5 (#2a6ce1) +L 11 (#1a2e50) +D 2 (#4f08c1) +L 3 (#3b7ec0) +D 9 (#65e011) +L 8 (#24b9a0) +D 6 (#196c61) +L 5 (#540b20) +D 6 (#243801) +L 2 (#397ce0) +D 3 (#411a41) +L 12 (#397ce2) +D 2 (#526d51) +L 2 (#5b5810) +D 5 (#2e96d3) +L 8 (#6c4f80) +U 6 (#274453) +L 3 (#077010) +U 5 (#37f603) +R 5 (#73bf92) +U 4 (#29ee73) +R 11 (#5ffd40) +U 5 (#3e12d3) +L 4 (#4b4e32) +U 12 (#114e01) +L 2 (#45d0b2) +U 4 (#114e03) +L 6 (#4b8b02) +U 9 (#3eff03) +L 4 (#6968d0) +U 4 (#3d4d33) +L 6 (#1dd0e0) +D 2 (#436023) +L 9 (#58b812) +D 6 (#423003) +L 7 (#2e81a2) +D 3 (#3d9e13) +L 11 (#305450) +D 6 (#2667f3) +L 7 (#3a8470) +D 8 (#293191) +R 3 (#207ee0) +D 4 (#293193) +R 3 (#2c4360) +D 4 (#2667f1) +R 7 (#250ee0) +U 4 (#70e1c3) +R 4 (#2907d0) +D 6 (#0b69a1) +R 6 (#3babc0) +D 6 (#7698c3) +R 2 (#2752c0) +D 3 (#7698c1) +L 4 (#2dc550) +D 11 (#4ec121) +L 8 (#199d00) +U 11 (#33f261) +L 7 (#3b4e30) +D 5 (#24e991) +L 6 (#0aaeb2) +U 9 (#15a993) +L 5 (#59ed02) +U 2 (#15a991) +L 5 (#2c0432) +U 10 (#337e81) +L 7 (#248670) +D 2 (#511d31) +L 3 (#52ebc0) +D 13 (#511d33) +L 4 (#192db0) +D 7 (#3dcf11) +L 2 (#285030) +D 3 (#15acc1) +L 6 (#3a6c70) +D 5 (#36f281) +L 4 (#44fd02) +U 5 (#4e8821) +L 4 (#473972) +U 5 (#2ab9f1) +L 8 (#60aaa0) +U 5 (#35c651) +L 3 (#4736b2) +U 10 (#4741d1) +L 3 (#1973f2) +U 5 (#1b5031) +L 3 (#3c6532) +D 5 (#49bd31) +L 4 (#5e3f60) +D 3 (#4a2011) +L 4 (#2ba190) +D 6 (#4a2013) +L 3 (#653430) +D 7 (#10dda1) +L 11 (#2532d2) +D 3 (#675311) +L 4 (#27d642) +D 6 (#02cae1) +L 10 (#466652) +D 7 (#34cef3) +R 3 (#263692) +D 7 (#34cef1) +R 8 (#2c59d2) +D 5 (#31afe1) +L 8 (#091562) +D 5 (#12c861) +R 4 (#47a772) +D 5 (#68a5b1) +L 7 (#1f79a2) +D 4 (#3b3c13) +R 10 (#0e7122) +D 4 (#087363) +R 4 (#3e26c2) +U 13 (#4953f3) +R 3 (#5ac862) +U 3 (#4953f1) +R 3 (#13cfe2) +D 5 (#087361) +R 11 (#57f7a2) +D 4 (#3b3c11) +L 11 (#6dcb32) +D 7 (#35e653) +R 6 (#525282) +D 5 (#3dac93) +R 9 (#377082) +D 6 (#2afda1) +R 10 (#3e6422) +D 10 (#220471) +R 10 (#37ebf2) +D 2 (#4d0213) +R 5 (#2fa2f2) +D 4 (#30df53) +R 5 (#617e00) +U 6 (#536393) +R 5 (#496510) +D 6 (#5f6733) +R 4 (#3bf9b0) +D 3 (#5f6731) +R 4 (#48d940) +D 3 (#35a5d3) +R 4 (#284a82) +D 9 (#445b23) +L 4 (#2535c2) +D 4 (#3f8b43) +R 2 (#41a002) +D 7 (#20b143) +R 3 (#63ae42) +U 8 (#328b03) +R 9 (#383210) +U 3 (#1ce143) +R 7 (#383212) +U 6 (#2ed603) +R 5 (#00c512) +U 6 (#6dea43) +R 6 (#00c510) +U 7 (#0f0643) +R 3 (#4292a2) +U 7 (#684961) +R 3 (#03de80) +U 5 (#46e0b1) +R 6 (#3d4ae2) +D 5 (#1d5fc1) +R 7 (#3d4ae0) +U 13 (#470ab1) +R 5 (#03de82) +U 4 (#282c71) +R 6 (#5520f2) +D 5 (#2f0981) +R 2 (#5520f0) +D 12 (#4081a1) +R 6 (#22a272) +U 5 (#284c53) +R 8 (#081202) +D 5 (#0b7831) +R 4 (#3e4552) +D 13 (#0b7833) +R 5 (#38e092) +U 11 (#284c51) +R 2 (#550082) +U 2 (#175033) +R 6 (#036dc2) +D 3 (#068791) +R 9 (#3ff6f2) +D 5 (#4a5783) +R 13 (#4d5f92) +D 6 (#3e3423) +L 12 (#4f62d2) +D 7 (#5e4363) +L 3 (#0f7032) +U 7 (#285261) +L 12 (#4ea392) +D 5 (#4c2dc1) +L 4 (#0d2822) +D 5 (#4c2dc3) +R 9 (#518da2) +D 2 (#41b3b1) +R 7 (#023270) +D 3 (#13d6e1) +R 11 (#0874c0) +D 3 (#2026c1) +R 4 (#68f3a0) +D 7 (#2026c3) +L 8 (#208470) +D 4 (#09bd81) +L 3 (#193a10) +D 7 (#5f3491) +L 4 (#08cad2) +D 10 (#068793) +L 10 (#48acb2) +D 4 (#20e341) +L 7 (#6137a2) +D 8 (#20e343) +L 7 (#0bf292) +D 7 (#5b5f13) +L 8 (#2b2532) +D 3 (#034073) +L 5 (#3c7bb2) +D 11 (#09c643) +L 3 (#0d6e52) +U 3 (#569d23) +L 5 (#63fed0) +U 4 (#162193) +L 4 (#2eb310) +U 3 (#655e23) +L 10 (#42f8e0) +U 4 (#341983) +R 14 (#3dbbc0) +U 5 (#551b13) +L 5 (#2a94f0) +U 6 (#05ae53) +L 2 (#09db90) +U 5 (#2c9e13) +L 8 (#4c6d10) +D 10 (#40ffb3) +L 3 (#306c30) +D 2 (#338911) +L 6 (#4bed00) +D 7 (#338913) +R 7 (#12aae0) +D 4 (#459613) +L 7 (#75d3a2) +D 7 (#37ad61) +L 6 (#6dcf92) +D 4 (#3b7703) +R 9 (#0ee2b2) +D 4 (#514c13) +R 6 (#0ee2b0) +D 3 (#2863b3) +L 8 (#52eee2) +D 8 (#2fc771) +L 7 (#5be782) +D 4 (#2f39a1) +L 6 (#5be780) +U 4 (#5625b1) +L 2 (#5588c2) +U 14 (#37ad63) +L 3 (#0681e2) +U 4 (#085481) +L 3 (#037432) +U 12 (#31ed51) +L 4 (#6791e2) +D 5 (#3546d3) +L 6 (#4419e2) +D 10 (#3546d1) +L 4 (#2c1a72) +D 10 (#5bead1) +L 3 (#3b3252) +D 9 (#3390c1) +L 3 (#1d78c2) +D 5 (#488d71) +R 10 (#244042) +D 2 (#10d1e1) +R 5 (#3fd582) +D 5 (#5025a1) +L 3 (#381b70) +D 11 (#771831) +L 7 (#2abf50) +U 11 (#17be81) +L 5 (#1eb3c0) +D 5 (#3d9c61) +L 5 (#5f4de2) +D 8 (#278361) +L 2 (#2b95b2) +D 9 (#2cb0b1) +L 4 (#4a0182) +D 6 (#2c6bb3) +L 2 (#499642) +D 5 (#4c76d3) +L 8 (#2fe412) +U 9 (#07b893) +L 2 (#236d52) +U 8 (#3956a3) +L 7 (#34f252) +U 3 (#52bbf1) +L 7 (#189470) +U 4 (#54b661) +L 9 (#189472) +U 7 (#0110f1) +L 3 (#409bf2) +U 3 (#46d3e3) +L 5 (#4c0f82) +U 11 (#215e73) +L 4 (#4c0f80) +U 7 (#4050f3) +L 9 (#39b192) +U 7 (#28b043) +L 3 (#011270) +U 7 (#1f6693) +R 7 (#73c390) +U 2 (#2c4113) +R 5 (#0321c0) +U 8 (#2f2903) +L 12 (#5ab560) +U 3 (#4dd983) +L 6 (#38b7d2) +U 12 (#03c8c3) diff --git a/18/src/main.rs b/18/src/main.rs new file mode 100644 index 0000000..eb6a54d --- /dev/null +++ b/18/src/main.rs @@ -0,0 +1,312 @@ +use itertools::Itertools; +use std::collections::{HashMap, LinkedList}; +use std::fmt::{Display, Write}; +use std::fs::File; +use std::io::{BufRead, BufReader, Lines}; +use std::ops::Range; +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()); +} + +// DATA + +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +enum Direction { + Left, + Right, + Up, + Down, +} + +impl Direction { + const fn all() -> &'static [Self; 4] { + &[ + Direction::Left, + Direction::Right, + Direction::Up, + Direction::Down, + ] + } + const fn opposite(&self) -> Self { + match self { + Direction::Left => Direction::Right, + Direction::Right => Direction::Left, + Direction::Up => Direction::Down, + Direction::Down => Direction::Up, + } + } + const fn offset(&self) -> (isize, isize) { + match self { + Direction::Left => (-1, 0), + Direction::Right => (1, 0), + Direction::Up => (0, -1), + Direction::Down => (0, 1), + } + } +} + +impl From<&str> for Direction { + fn from(s: &str) -> Self { + match s { + "L" => Direction::Left, + "R" => Direction::Right, + "U" => Direction::Up, + "D" => Direction::Down, + s => panic!("{} is not a valid direction", s), + } + } +} + +impl From<&Direction> for char { + fn from(dir: &Direction) -> Self { + match dir { + Direction::Left => '←', + Direction::Right => '→', + Direction::Up => '↑', + Direction::Down => '↓', + } + } +} + +#[derive(Debug, Clone)] +struct DigInstruction { + dir: Direction, + count: usize, + color: String, +} + +impl From<&str> for DigInstruction { + fn from(s: &str) -> Self { + let mut parts = s.split_ascii_whitespace(); + let (dir, count, color) = ( + parts.next().unwrap(), + parts.next().unwrap(), + parts.next().unwrap(), + ); + Self { + dir: dir.into(), + count: count.parse().unwrap(), + color: color.into(), + } + } +} + +#[derive(Debug)] +struct DigPlan { + instructions: Vec, +} + +#[derive(Debug, Clone)] +struct DigTile { + position: Position, + depth: usize, + color: String, +} + +impl Default for DigTile { + fn default() -> Self { + Self { + position: (0, 0), + depth: 0, + color: "000000".into(), + } + } +} + +type Position = (isize, isize); + +#[derive(Debug)] +struct DigHole { + tiles_loop: LinkedList, + tiles_map: HashMap, + x_range: Range, + y_range: Range, +} + +impl DigHole { + fn new() -> Self { + DigHole { + tiles_loop: LinkedList::new(), + tiles_map: HashMap::new(), + x_range: 0..0, + y_range: 0..0, + } + } + fn pos_offset(&self, pos: Position, offset: (isize, isize)) -> Position { + (pos.0 + offset.0, pos.1 + offset.1) + } + fn run_plan(&mut self, plan: &DigPlan) { + // start position is 1m deep + let mut cur_pos = (0, 0); + let (mut max_x, mut max_y) = (0, 0); + + self.tiles_loop.push_back(DigTile { + position: cur_pos, + depth: 1, + color: "000000".into(), + }); + for i in &plan.instructions { + println!("instruction: {:?}", i); + for _ in 0..i.count { + println!(" cur_pos: {:?}", cur_pos); + cur_pos = (cur_pos.0 + i.dir.offset().0, cur_pos.1 + i.dir.offset().1); + (max_x, max_y) = ( + std::cmp::max(cur_pos.0, max_x), + std::cmp::max(cur_pos.1, max_y), + ); + self.tiles_loop.push_back(DigTile { + position: cur_pos, + depth: 1, + color: i.color.to_owned(), + }); + } + } + // 2d vec dimension is (max_x+1, max_y+1) + for tile in &self.tiles_loop { + self.x_range.start = std::cmp::min(self.x_range.start, tile.position.0); + self.x_range.end = std::cmp::max(self.x_range.end, tile.position.0 + 1); + self.y_range.start = std::cmp::min(self.y_range.start, tile.position.1); + self.y_range.end = std::cmp::max(self.y_range.end, tile.position.1 + 1); + self.tiles_map.insert(tile.position, tile.clone()); + } + println!("{}", self); + self.fill_at(self.find_first_inside().unwrap()); + } + fn fill_at(&mut self, pos: Position) { + println!("filling at {:?}", pos); + let mut to_fill = vec![pos]; + + while let Some(fill_pos) = to_fill.pop() { + if self.tiles_map.contains_key(&fill_pos) { + continue; + } else { + self.tiles_map.insert( + fill_pos, + DigTile { + position: fill_pos, + depth: 1, + color: "000000".to_owned(), + }, + ); + } + for new_pos in Direction::all() + .iter() + .map(|dir| self.pos_offset(fill_pos, dir.offset())) + .filter(|pos| !self.tiles_map.contains_key(&pos)) + { + to_fill.push(new_pos); + } + } + } + fn find_first_inside(&self) -> Option { + for y in self.y_range.clone() { + let mut inside = false; + for x in self.x_range.clone() { + if self.tiles_map.contains_key(&(x, y)) && (!self.tiles_map.contains_key(&(x - 1, y)) || !self.tiles_map.contains_key(&(x+1, y))) + { + inside = !inside; + } + if inside && !self.tiles_map.contains_key(&(x, y)) { + return Some((x as isize, y as isize)); + }; + } + } + None + } +} + +impl Display for DigHole { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for y in self.y_range.clone() { + for x in self.x_range.clone() { + f.write_char(if (x, y) == (133, -267) { + '*' + } else if self.tiles_map.contains_key(&(x, y)) { + '#' + } else { + '.' + })?; + } + writeln!(f)?; + } + Ok(()) + } +} + +impl From> for DigPlan { + fn from(lines: Lines) -> Self { + Self { + instructions: lines + .map(|line| DigInstruction::from(line.unwrap().as_str())) + .collect(), + } + } +} + +// PROBLEM 1 solution + +fn problem1(input: Lines) -> u64 { + let plan = DigPlan::from(input); + println!("{:?}", plan); + let mut dig = DigHole::new(); + dig.run_plan(&plan); + println!("{}", dig); + dig.tiles_map.iter().count() as u64 +} + +// PROBLEM 2 solution +fn problem2(input: Lines) -> u64 { + 0 +} + +#[cfg(test)] +mod tests { + use crate::*; + use std::io::Cursor; + + const EXAMPLE: &str = &"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)"; + + #[test] + fn problem1_example() { + let c = Cursor::new(EXAMPLE); + assert_eq!(problem1(c.lines()), 62); + } + + #[test] + fn problem2_example() { + let c = Cursor::new(EXAMPLE); + assert_eq!(problem2(c.lines()), 0); + } +}