adventofcode/days/2024/15.rs

89 Zeilen
2,6 KiB
Rust

use advent_of_code::{
find_character,
strings::{convert_to_array, line_to_char},
Kartesian, KartesianDirection, Map,
};
use advent_of_code_macros::include_aoc;
use log::debug;
include_aoc!(DATA 2024 15);
const WALL: char = '#';
const ROBOT: char = '@';
const CRATE: char = 'O';
const SPACE: char = '.';
fn instructions_to_dir(instructions: &str) -> Vec<KartesianDirection> {
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 calc_sum(map: &Map<char>) -> 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 = find_character(&map, ROBOT);
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::*;
}