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::*; }