From 68767c83aefbe90b1b5a64a1348ef995b68543a4 Mon Sep 17 00:00:00 2001 From: Sebastian Tobie Date: Sun, 15 Dec 2024 14:38:50 +0100 Subject: [PATCH] solved part one of day 15 --- examples/2024/15.txt | 10 +++ src/bin/2024/15.rs | 104 ++++++++++++++++++++++++ src/coordinate_systems/kartesian/map.rs | 4 + 3 files changed, 118 insertions(+) create mode 100644 examples/2024/15.txt create mode 100644 src/bin/2024/15.rs diff --git a/examples/2024/15.txt b/examples/2024/15.txt new file mode 100644 index 0000000..c6138ff --- /dev/null +++ b/examples/2024/15.txt @@ -0,0 +1,10 @@ +######## +#..O.O.# +##@.O..# +#...O..# +#.#.O..# +#...O..# +#......# +######## + +<^^>>>vv>v<< \ No newline at end of file diff --git a/src/bin/2024/15.rs b/src/bin/2024/15.rs new file mode 100644 index 0000000..b16047a --- /dev/null +++ b/src/bin/2024/15.rs @@ -0,0 +1,104 @@ +use advent_of_code::{ + strings::{convert_to_array, line_to_char}, + Kartesian, KartesianDirection, Map, +}; +#[allow(unused_imports)] +use advent_of_code_macros::{include_data, include_example}; +use log::debug; + +include_data!(DATA 2024 15); + +const WALL: char = '#'; +const ROBOT: char = '@'; +const CRATE: char = 'O'; +const SPACE: char = '.'; + +fn instructions_to_dir(instructions: &str) -> Vec { + let mut dirs = Vec::with_capacity(instructions.len()); + for char in instructions.chars() { + if char == '\n' { + continue; + } + dirs.push(match char { + '<' => KartesianDirection::Left, + '^' => KartesianDirection::Top, + '>' => KartesianDirection::Right, + 'v' => KartesianDirection::Bottom, + _ => unreachable!(), + }) + } + dirs +} + +fn get_position(map: &Map) -> Kartesian { + let maximum = map.size(); + let mut coord = Kartesian::new(0, 0); + for x in 1..maximum.x - 1 { + for y in 1..maximum.y - 1 { + coord.x = x; + coord.y = y; + if map.get(coord) == Some(ROBOT) { + return coord; + } + } + } + unreachable!() +} + +fn calc_sum(map: &Map) -> usize { + let maximum = map.size(); + let mut sum = 0; + for x in 1..maximum.x - 1 { + for y in 1..maximum.y - 1 { + if map.get(Kartesian::new(x, y)) == Some(CRATE) { + println!("found crate on {}:{}", x, y); + sum += 100 * x + y + } + } + } + sum +} + +fn main() { + let (maze, instructions): (&str, &str) = DATA.split_once("\n\n").unwrap(); + let mut map = Map::from(convert_to_array::<_, _, '\n'>(maze, line_to_char)); + let directions = instructions_to_dir(instructions); + let mut position = get_position(&map); + let mut new; + for direction in directions { + new = position.move_dir(direction.vector(), direction).unwrap(); + match map.get(new) { + Some(SPACE) => { + map.set(position, SPACE); + map.set(new, ROBOT); + position = new; + }, + Some(CRATE) => { + debug!("Trying to move crate to {} on position {}", direction, new); + let mut skip = new; + while map.get(skip) == Some(CRATE) { + skip = skip.move_dir(direction.vector(), direction).unwrap(); + debug!("Object on {} is {:?}", skip, map.get(skip)); + } + match map.get(skip) { + Some(WALL) => {}, + Some(SPACE) => { + map.set(skip, CRATE); + map.set(new, ROBOT); + map.set(position, SPACE); + position = new; + }, + _ => {}, + } + }, + Some(WALL) => {}, + _ => {}, + } + } + println!("Sum of ocordinates is {}", calc_sum(&map)); +} + +#[cfg(test)] +mod test { + use super::*; +} diff --git a/src/coordinate_systems/kartesian/map.rs b/src/coordinate_systems/kartesian/map.rs index 0bcd555..9785c76 100644 --- a/src/coordinate_systems/kartesian/map.rs +++ b/src/coordinate_systems/kartesian/map.rs @@ -17,6 +17,10 @@ impl Map { } } + pub fn size(&self) -> Kartesian { + self.maximum + } + /// returns true if coordinates are outside of bounds #[inline] fn outside(&self, coord: Kartesian) -> bool {