2024-12-15 14:38:50 +01:00
|
|
|
use advent_of_code::{
|
2024-12-16 20:40:41 +01:00
|
|
|
find_character,
|
2024-12-15 14:38:50 +01:00
|
|
|
strings::{convert_to_array, line_to_char},
|
|
|
|
Kartesian, KartesianDirection, Map,
|
|
|
|
};
|
2024-12-19 17:12:39 +01:00
|
|
|
use advent_of_code_macros::include_aoc;
|
2024-12-15 14:38:50 +01:00
|
|
|
use log::debug;
|
|
|
|
|
2024-12-19 17:12:39 +01:00
|
|
|
include_aoc!(DATA 2024 15);
|
2024-12-15 14:38:50 +01:00
|
|
|
|
|
|
|
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);
|
2024-12-16 20:40:41 +01:00
|
|
|
let mut position = find_character(&map, ROBOT);
|
2024-12-15 14:38:50 +01:00
|
|
|
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::*;
|
|
|
|
}
|