diff --git a/rust/2023/input/2023/day18.txt b/rust/2023/input/2023/day18.txt new file mode 100644 index 0000000..f27e001 --- /dev/null +++ b/rust/2023/input/2023/day18.txt @@ -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/rust/2023/src/day_18.rs b/rust/2023/src/day_18.rs new file mode 100644 index 0000000..ec87c1a --- /dev/null +++ b/rust/2023/src/day_18.rs @@ -0,0 +1,153 @@ +//! Day 18 + +use crate::{ + grid::Grid, + point::{Point, DOWN, LEFT, RIGHT, UP}, +}; + +#[derive(Debug)] +pub struct Input { + dig_plan: Vec, +} + +#[derive(Debug)] +enum Direction { + Up(i32), + Down(i32), + Left(i32), + Right(i32), +} + +#[aoc_generator(day18)] +pub fn input_generator(input: &str) -> Input { + let dig_plan = input + .lines() + .map(|line| { + let data = line.split_whitespace().collect::>(); + let distance = data[1].parse::().unwrap(); + + let direction = match data[0] { + "U" => Direction::Up(distance), + "D" => Direction::Down(distance), + "L" => Direction::Left(distance), + "R" => Direction::Right(distance), + _ => panic!("Invalid direction"), + }; + + direction + }) + .collect::>(); + + Input { dig_plan } +} + +/* Part One +* +*/ +// Your puzzle answer was +#[doc = r#"``` +use advent_of_code_2023::day_18::*; +let data = include_str!("../input/2023/day18.txt"); +assert_eq!(solve_part_01(&input_generator(data)), 1013); +```"#] +#[aoc(day18, part1)] +pub fn solve_part_01(input: &Input) -> i32 { + let mut grid = Grid::new(1000, 1000, vec![b'.'; 1000 * 1000]); + let mut position = Point::new(grid.width / 2, grid.height / 2); + let mut area = 0; + let determinant = |a: Point, b: Point| a.x * b.y - a.y * b.x; + + for direction in &input.dig_plan { + match direction { + Direction::Right(distance) => { + for x in position.x + 1..=position.x + *distance { + grid.data[(x + position.y * grid.width) as usize] = b'#'; + } + + let next_position = position + RIGHT * *distance; + area += determinant(position, next_position); + position = next_position; + } + Direction::Left(distance) => { + for x in (position.x - *distance..=position.x).rev() { + grid.data[(x + position.y * grid.width) as usize] = b'#'; + } + + let next_position = position + LEFT * *distance; + area += determinant(position, next_position); + position = next_position; + } + Direction::Up(distance) => { + for y in (position.y - *distance..=position.y).rev() { + grid.data[(position.x + y * grid.width) as usize] = b'#'; + } + + let next_position = position + UP * *distance; + area += determinant(position, next_position); + position = next_position; + } + Direction::Down(distance) => { + for y in position.y..=position.y + *distance { + grid.data[(position.x + y * grid.width) as usize] = b'#'; + } + + let next_position = position + DOWN * *distance; + area += determinant(position, next_position); + position = next_position; + } + } + } + + // Find the number of boundary points + let boundary = grid.find_all(b'#').len() as i32; + // Similar to day 10 + // The Shoelace formula is used to calculate the area of a polygon with points. + // Make use of Pick's theorem to find the number of interior points + let interior_points = area.abs() / 2 - boundary / 2 + 1; + + boundary + interior_points +} + +/* Part Two +* +* Find the maximum number of energized tiles after firing the beam +* inwards from all edges of the grid. +* +*/ +#[doc = r#"``` +use advent_of_code_2023::day_18::*; +let data = include_str!("../input/2023/day18.txt"); +assert_eq!(solve_part_02(&input_generator(data)), 1215); +```"#] +#[aoc(day18, part2)] +pub fn solve_part_02(_input: &Input) -> u32 { + todo!() +} + +#[cfg(test)] +mod tests { + use super::*; + use rstest::rstest; + + #[rstest] + #[case( + "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 + )] + fn sample_01(#[case] input: &str, #[case] expected: i32) { + assert_eq!(solve_part_01(&input_generator(input)), expected); + } +} diff --git a/rust/2023/src/grid.rs b/rust/2023/src/grid.rs index 31e52e9..0b09fe7 100644 --- a/rust/2023/src/grid.rs +++ b/rust/2023/src/grid.rs @@ -30,6 +30,14 @@ impl + Copy> From<&str> for Grid { } impl Grid { + pub fn new(width: i32, height: i32, data: Vec) -> Self { + Grid { + width, + height, + data, + } + } + /// Find _one_ point that has the given value in the grid. /// /// # Example diff --git a/rust/2023/src/lib.rs b/rust/2023/src/lib.rs index e05a40e..ae1495a 100644 --- a/rust/2023/src/lib.rs +++ b/rust/2023/src/lib.rs @@ -25,5 +25,6 @@ pub mod day_14; pub mod day_15; pub mod day_16; pub mod day_17; +pub mod day_18; aoc_lib! { year = 2023 } diff --git a/rust/2023/src/point.rs b/rust/2023/src/point.rs index 585b994..4576885 100644 --- a/rust/2023/src/point.rs +++ b/rust/2023/src/point.rs @@ -13,7 +13,7 @@ use std::{ fmt::Display, - ops::{Add, AddAssign}, + ops::{Add, AddAssign, Mul}, }; #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Ord, PartialOrd)] @@ -58,6 +58,14 @@ impl AddAssign for Point { } } +impl Mul for Point { + type Output = Point; + + fn mul(self, rhs: i32) -> Self { + Point::new(self.x * rhs, self.y * rhs) + } +} + impl Display for Point { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Point { x, y } = self;