diff --git a/y2024/resources/6_input.txt b/y2024/resources/6_input.txt new file mode 100644 index 0000000..13453bc --- /dev/null +++ b/y2024/resources/6_input.txt @@ -0,0 +1,130 @@ +.........................#...........#.#...#...............#..............##.....................#...........#..#.........#....... +.....................#.................#.......#.........................#...........#.#.......#.................................. +.........#...........#........#.........#.........#...........#........................................#.........................# +.......#.........................#...........................#.............#...................................................... +..................#................##...............#.#.....................##............#....................................... +......#...#................#..................................................................#....#.#............................ +.......##................#........#..#.......#......................................#........#............#......###..........#... +.....................#....................................................#...........#..#...#..........................#......... +...........#....#...........................#.#...............#..#....................................#..............#......#..... +.....#........##...............#.......#..#..............................................#..........................#............. +.#.........#.#...........................#..........................#......................#...........#........#................. +.................................................................#..#.#.......#..#................................................ +...............................................#.......#...................#....................#................................. +.......#......#......#......................#...............................#.....##........#...........#......#.................. +........................................................................................................#.....#.#................. +..#...............................#.#..................................#.............#............................................ +..............#..........................................#.....#.....#..........................#....#.........#.................. +...................................#........................................#................#...........##.....#....#............ +.#.....................................#.......#........................#...................##............#....................... +.#..................#...........#...........................................................................................#..... +........................#...................................................##.................................#..#..........##... +........#............................#.......#...........................#.#...#...................................#.....#........ +...............................#............#.....#......................#.......#...#........................#................... +.........#.............#.................................................#.......................................#....#........... +...................................................................#...#.................................#...................#.... +...#.....................#...#...............#..................................................#...#...#......................... +...................#........#....#....#..#..#...................#.........#..................#..#....#.......#.#.................# +..............................#........................................#......#.....#..............##................#............ +............#..#.............#.......#........................................................##........#.....#................... +.....#.............................................................#...#.#.#.............................#..#.#...........#....... +.......#....#............................................#.................................#...................................#.. +..#.................#.......#..........................#........................................#...............#..............#.. +....#.#...................#............................#..#....................................................................... +.......................#...............#..............#......#......................#.....................#..............#........ +.#..........#.......................................................................#....................................#........ +.#.......#..................................................................#..................................................... +..................................................#.............#.............................................#................#.# +.......................#......#....#................#......................................................#.......#.........#.... +..........................#.#........................................................#......#................................#.... +....................................................................#...............................#............................. +..#...........#..............................#..#....#............................#...............##..............#...#...#...#..# +...................................#................................................................#....#...................#.... +..#....#........#..##....#........................#...#...................................#....................................... +...................#................................................................................................#............. +.......#........#................#...#.......................................................................#.................... +..............#....................#..........................##.........#.....................................#.................. +.........................................................................#.................#........................#............. +.............................#..........#.......................................................#......................#.......... +............###....................................................................#.......................#...................... +........#........#...........#.............................#....................#..........#.........................#.#.....#.... +.........................................................................................................#..#..................... +#.#.....#..........................................................#.....................#........................................ +........##..........#....................................................#..#........#.......#........#................#.......... +.............................................#..........................#.........#........................#...................... +...........................##.............#........................#.#........................#..#................#.....#........# +#...#..............................................#........#...................................................#................. +.............#................#............................#............#......................................................... +#..........................#............#.....................#.....#.................#......#...##...#.............#.#........... +.....................#...#..#....#...................................#....................#..............#........#............... +.......................#.................#...........#....#.......#...........................................#..#................ +.........#...........#.#.........#.........................#.....#................................................................ +....................#........#...................................................................#............#..#.#.#............ +..........#.......................#.......................#....................................................................... +......................................#......#............................#..............................................#........ +.....................#...#.................#.............................#....#................................................... +..............##...................................................................#......................................##...... +.....#....#...............................................#.......#.##........#.#.............#...............#................... +....................................#......................#........#.......................................................#..... +.....#.........................................#.....................#.............#.................#..................#......... +................................#.........#..#............................................#.........................#............. +....#.#.....................#......#...................................#..........................................#..#.....#...#.. +.........##.......................#..........................................#.........................#...##..................... +...............................................................#................................................................#. +............#.........................................##.......................................#.................................. +.............................#..............................#..................#.........#.....#.................................. +..........................................................#...#.....#..................#................................#......... +......#...................#.........................................................................................#............. +#...............................#...........................#..................................................................... +.......#........#.................................................#.......................................................#....... +.#......................................................#..............#..................................#...........#........... +.............#..#.#.......................#..........#......#.##.........................................................#..#..... +.......#...............#........#......................................................................#..#...........#........... +............#.........................................#................................................#...................#...... +............#...........................................#.#.......#....................................#.......................... +...........................................#.........................................................#..............#............. +..................#..#....................................................#..................#.................................... +..#........................#........#............................................................................................. +.............#........#......................#.......................................#...#....#............................#...... +............#.......#.............#...#...........#.#.................................#.................##........................ +.....................................................................................#.........#.......................#.....#.... +.................#................................#..#....#......#..........................................#.....#............... +..#...............................#........................................................#.......#...#............#............. +#.........#..#..#.....................................#....................................#................#.................#... +.......................#..#...#............................................................................#..#.....#.......##.... +..........#............#.......................#.........................^......#.#...................................#........... +...##........................##..........#..........#.................#...............#...........#.....##........................ +..............#............#..........................#....#...........#......#......#......................#..................... +......#.....#....................................................#............#.#......................................#.......... +......#.............................#......................#...............................#........#............................. +.#..........#.............................................#.............................................#......................... +...............................##................................................................................................. +.....................#................................................#...............#............#...............#.....#.....#.. +..................#...........................................................................#...........#...................#... +##..............................#.#...#.#...............................#...........#.#...................#....................... +......................#.........#...................................#.................#........................................... +.......................#............................................................................#.........##...........#...... +.....................................................................#.......#.....#.......................................#...... +#....................................#........#.#.................................................................##.....#........ +..............#..............................#......#..........###.........#................#..............#..................#... +..................................#..............................#.................##.............................#...#........... +...............#......#........................#....#........#............#.........#..........#..............#......#............ +...#...........#........#...#...........................#.............#.....................................#..................... +..............###............#...........................................................#.............#.........##..#............ +............#................................................#.......#..................#....#.................................... +.........#.#...#.....#...........................#.....##......#.....................#..#........#......#......................... +.#....#.......#.......................#.................................................................#.......#..............#.. +...................#................................................................#.............#...#...........#.........#..... +.......#.#.......#.......................#....#.....#...............#...#.....#...........................................#....... +.......#........#...........................................#...........#.........................#....#.......#.................. +..................................#.#.................#.#............................................#...........#....#........... +....##......#.............#...................................#...#.........#...........................#......#.................. +.........................#......#....#...#........................................................................................ +...#...............#............................................................................#...........................#..... +....##.#..............................................#............#................#................................#......#..... +.........#...........................................#...#.......##..............................#................................ +..................#..........#......#.......#......................................#........#...............#......#...........##. +........................................#......#..........#......................................................................# +..............#...#...................#.....#..........................................................#..............#......#.... +...#........#........................#...#................#........#.............................##..........................#.... +............#............................#.#........................#.................................#..........................# diff --git a/y2024/src/bin/d6.rs b/y2024/src/bin/d6.rs new file mode 100644 index 0000000..2c9390d --- /dev/null +++ b/y2024/src/bin/d6.rs @@ -0,0 +1,20 @@ +use std::fs; + +use y2024::days::d6; + +fn main() { + part1(); + part2(); +} + +fn part1() { + let root = env!("CARGO_MANIFEST_DIR"); + let content = fs::read_to_string(format!("{root}/resources/6_input.txt")).unwrap(); + println!("{}", d6::process_part1(&content)); +} + +fn part2() { + let root = env!("CARGO_MANIFEST_DIR"); + let content = fs::read_to_string(format!("{root}/resources/6_input.txt")).unwrap(); + println!("{}", d6::process_part2(&content)); +} diff --git a/y2024/src/days/d6.rs b/y2024/src/days/d6.rs new file mode 100644 index 0000000..a4062ba --- /dev/null +++ b/y2024/src/days/d6.rs @@ -0,0 +1,331 @@ +use std::{collections::HashSet, error::Error, fmt::Display}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum GuardDirection { + Up, + Down, + Left, + Right, +} + +impl GuardDirection { + fn turn_right(&mut self) { + *self = match self { + GuardDirection::Up => GuardDirection::Right, + GuardDirection::Down => GuardDirection::Left, + GuardDirection::Left => GuardDirection::Up, + GuardDirection::Right => GuardDirection::Down, + }; + } +} + +impl From for char { + fn from(value: GuardDirection) -> Self { + match value { + GuardDirection::Up => '^', + GuardDirection::Down => 'v', + GuardDirection::Left => '<', + GuardDirection::Right => '>', + } + } +} + +impl TryFrom for GuardDirection { + type Error = Box; + + fn try_from(value: char) -> std::result::Result> { + match value { + '^' => Ok(Self::Up), + 'v' => Ok(Self::Down), + '<' => Ok(Self::Left), + '>' => Ok(Self::Right), + _ => Err(Box::from(format!("{value} is not a valid direction"))), + } + } +} + +impl Display for GuardDirection { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GuardDirection::Up => write!(f, "^"), + GuardDirection::Down => write!(f, "v"), + GuardDirection::Left => write!(f, "<"), + GuardDirection::Right => write!(f, ">"), + } + } +} + +pub fn process_part1(input: &str) -> i32 { + let grid = input + .lines() + .map(|line| line.chars().collect::>()) + .collect::>>(); + get_visited_positions(grid, true).len() as i32 +} + +fn get_visited_positions(grid: Vec>, initial: bool) -> HashSet<(i32, i32)> { + let width = grid[1].len() as i32; + let height = grid.len() as i32; + let mut crates: Vec<(i32, i32)> = Vec::new(); + let mut guard_position = (0, 0); + let mut guard_direction = GuardDirection::Up; + for (row, line) in grid.into_iter().enumerate() { + for (col, chara) in line.into_iter().enumerate() { + if chara == '#' { + crates.push((col as i32, row as i32)); + } + if chara == '.' { + continue; + } + if GuardDirection::try_from(chara).is_ok() { + guard_position = (col as i32, row as i32); + guard_direction = GuardDirection::try_from(chara).unwrap(); + } + } + } + let mut visited_positions = HashSet::new(); + if initial { + visited_positions.insert(guard_position); + } + loop { + match guard_direction { + GuardDirection::Up => { + let mut closest = (guard_position.0, -1); + crates.iter().for_each(|&crate_pos| { + if guard_position.0 == crate_pos.0 + && guard_position.1 > crate_pos.1 + && guard_position.1 - crate_pos.1 < guard_position.1 - closest.1 + { + closest = crate_pos; + } + }); + for idx in ((closest.1 + 1)..guard_position.1).rev() { + visited_positions.insert((guard_position.0, idx)); + if idx == 0 { + return visited_positions; + } + } + guard_position.1 = closest.1 + 1; + guard_direction.turn_right(); + } + GuardDirection::Down => { + let mut closest = (guard_position.0, height); + crates.iter().for_each(|&crate_pos| { + if guard_position.0 == crate_pos.0 + && guard_position.1 < crate_pos.1 + && crate_pos.1 - guard_position.1 < closest.1 - guard_position.1 + { + closest = crate_pos; + } + }); + for idx in (guard_position.1 + 1)..closest.1 { + visited_positions.insert((guard_position.0, idx)); + if idx == height - 1 { + return visited_positions; + } + } + guard_position.1 = closest.1 - 1; + guard_direction.turn_right(); + } + GuardDirection::Left => { + let mut closest = (-1, guard_position.1); + crates.iter().for_each(|&crate_pos| { + if guard_position.1 == crate_pos.1 + && guard_position.0 > crate_pos.0 + && guard_position.0 - crate_pos.0 < guard_position.0 - closest.0 + { + closest = crate_pos; + } + }); + for idx in ((closest.0 + 1)..guard_position.0).rev() { + visited_positions.insert((idx, guard_position.1)); + if idx == 0 { + return visited_positions; + } + } + guard_position.0 = closest.0 + 1; + guard_direction.turn_right(); + } + GuardDirection::Right => { + let mut closest = (width, guard_position.1); + crates.iter().for_each(|&crate_pos| { + if guard_position.1 == crate_pos.1 + && guard_position.0 < crate_pos.0 + && crate_pos.0 - guard_position.0 < closest.0 - guard_position.0 + { + closest = crate_pos; + } + }); + for idx in (guard_position.0 + 1)..closest.0 { + visited_positions.insert((idx, guard_position.1)); + if idx == width - 1 { + return visited_positions; + } + } + guard_position.0 = closest.0 - 1; + guard_direction.turn_right(); + } + }; + } +} + +// 1424 +pub fn process_part2(input: &str) -> i32 { + let grid = input + .lines() + .map(|line| line.chars().collect::>()) + .collect::>>(); + let width = grid[1].len() as i32; + let height = grid.len() as i32; + let mut crates: Vec<(i32, i32)> = Vec::new(); + let possible_obstacles: Vec<(i32, i32)> = Vec::from_iter(get_visited_positions(grid, false)); + let mut initial_guard_position = (0, 0); + let mut initial_guard_direction = GuardDirection::Up; + for (row, line) in input.lines().enumerate() { + for (col, chara) in line.chars().enumerate() { + if chara == '#' { + crates.push((col as i32, row as i32)); + } + if chara == '.' { + continue; + } + if GuardDirection::try_from(chara).is_ok() { + initial_guard_position = (col as i32, row as i32); + initial_guard_direction = GuardDirection::try_from(chara).unwrap(); + } + } + } + let mut loops = 0; + for possible_obstacle in possible_obstacles { + let mut visited_obstacles = HashSet::new(); + crates.push(possible_obstacle); + let mut guard_position = initial_guard_position; + let mut guard_direction = initial_guard_direction; + 'loop_finder: loop { + match guard_direction { + GuardDirection::Up => { + let mut closest = (guard_position.0, -1); + crates.iter().for_each(|&crate_pos| { + if guard_position.0 == crate_pos.0 + && guard_position.1 > crate_pos.1 + && guard_position.1 - crate_pos.1 < guard_position.1 - closest.1 + { + closest = crate_pos; + } + }); + guard_position.1 = closest.1 + 1; + if closest.1 == -1 { + break 'loop_finder; + } + if visited_obstacles + .contains(&((guard_position.0, closest.1 + 1), guard_direction)) + { + loops += 1; + break 'loop_finder; + } + visited_obstacles.insert(((guard_position.0, closest.1 + 1), guard_direction)); + guard_direction.turn_right(); + } + GuardDirection::Down => { + let mut closest = (guard_position.0, height); + crates.iter().for_each(|&crate_pos| { + if guard_position.0 == crate_pos.0 + && guard_position.1 < crate_pos.1 + && crate_pos.1 - guard_position.1 < closest.1 - guard_position.1 + { + closest = crate_pos; + } + }); + guard_position.1 = closest.1 - 1; + if closest.1 == height { + break 'loop_finder; + } + if visited_obstacles + .contains(&((guard_position.0, closest.1 - 1), guard_direction)) + { + loops += 1; + break 'loop_finder; + } + visited_obstacles.insert(((guard_position.0, closest.1 - 1), guard_direction)); + guard_direction.turn_right(); + } + GuardDirection::Left => { + let mut closest = (-1, guard_position.1); + crates.iter().for_each(|&crate_pos| { + if guard_position.1 == crate_pos.1 + && guard_position.0 > crate_pos.0 + && guard_position.0 - crate_pos.0 < guard_position.0 - closest.0 + { + closest = crate_pos; + } + }); + guard_position.0 = closest.0 + 1; + if closest.0 == -1 { + break 'loop_finder; + } + if visited_obstacles + .contains(&((closest.0 + 1, guard_position.1), guard_direction)) + { + loops += 1; + break 'loop_finder; + } + visited_obstacles.insert(((closest.0 + 1, guard_position.1), guard_direction)); + guard_direction.turn_right(); + } + GuardDirection::Right => { + let mut closest = (width, guard_position.1); + crates.iter().for_each(|&crate_pos| { + if guard_position.1 == crate_pos.1 + && guard_position.0 < crate_pos.0 + && crate_pos.0 - guard_position.0 < closest.0 - guard_position.0 + { + closest = crate_pos; + } + }); + guard_position.0 = closest.0 - 1; + if closest.0 == width { + break 'loop_finder; + } + if visited_obstacles + .contains(&((closest.0 - 1, guard_position.1), guard_direction)) + { + loops += 1; + break 'loop_finder; + } + visited_obstacles.insert(((closest.0 - 1, guard_position.1), guard_direction)); + guard_direction.turn_right(); + } + }; + } + crates.pop(); + } + loops +} + +#[cfg(test)] +mod tests { + use super::*; + + const INPUT: &str = "....#..... +.........# +.......... +..#....... +.......#.. +.......... +.#..^..... +........#. +#......... +......#..."; + + #[test] + fn part1() { + let result = process_part1(INPUT); + assert_eq!(result, 41); + } + + #[test] + fn part2() { + let result = process_part2(INPUT); + assert_eq!(result, 6); + } +} diff --git a/y2024/src/days/mod.rs b/y2024/src/days/mod.rs index 5b5d285..6401cf3 100644 --- a/y2024/src/days/mod.rs +++ b/y2024/src/days/mod.rs @@ -7,3 +7,5 @@ pub mod d3; pub mod d4; pub mod d5; + +pub mod d6;