From 4f10c7fb5e01583bf3b494f965e2cfff444479d8 Mon Sep 17 00:00:00 2001 From: Sebastian Tobie Date: Mon, 16 Dec 2024 20:40:41 +0100 Subject: [PATCH] solved day 16 part 1 --- examples/2024/16.txt | 1 + examples/2024/16a.txt | 15 +++ examples/2024/16b.txt | 17 +++ examples/2024/16c.txt | 27 +++++ examples/2024/README:md | 4 + src/bin/2024/15.rs | 18 +--- src/bin/2024/16.rs | 100 ++++++++++++++++++ .../kartesian/external_traits.rs | 4 +- src/coordinate_systems/kartesian/map.rs | 15 +++ src/coordinate_systems/kartesian/test.rs | 2 - 10 files changed, 183 insertions(+), 20 deletions(-) create mode 120000 examples/2024/16.txt create mode 100644 examples/2024/16a.txt create mode 100644 examples/2024/16b.txt create mode 100644 examples/2024/16c.txt create mode 100644 examples/2024/README:md create mode 100644 src/bin/2024/16.rs diff --git a/examples/2024/16.txt b/examples/2024/16.txt new file mode 120000 index 0000000..e1560e5 --- /dev/null +++ b/examples/2024/16.txt @@ -0,0 +1 @@ +16c.txt \ No newline at end of file diff --git a/examples/2024/16a.txt b/examples/2024/16a.txt new file mode 100644 index 0000000..2c21676 --- /dev/null +++ b/examples/2024/16a.txt @@ -0,0 +1,15 @@ +############### +#.......#....E# +#.#.###.#.###.# +#.....#.#...#.# +#.###.#####.#.# +#.#.#.......#.# +#.#.#####.###.# +#...........#.# +###.#.#####.#.# +#...#.....#.#.# +#.#.#.###.#.#.# +#.....#...#.#.# +#.###.#.#.#.#.# +#S..#.....#...# +############### diff --git a/examples/2024/16b.txt b/examples/2024/16b.txt new file mode 100644 index 0000000..bc61c57 --- /dev/null +++ b/examples/2024/16b.txt @@ -0,0 +1,17 @@ +################# +#...#...#...#..E# +#.#.#.#.#.#.#.#.# +#.#.#.#...#...#.# +#.#.#.#.###.#.#.# +#...#.#.#.....#.# +#.#.#.#.#.#####.# +#.#...#.#.#.....# +#.#.#####.#.###.# +#.#.#.......#...# +#.#.###.#####.### +#.#.#...#.....#.# +#.#.#.#####.###.# +#.#.#.........#.# +#.#.#.#########.# +#S#.............# +################# diff --git a/examples/2024/16c.txt b/examples/2024/16c.txt new file mode 100644 index 0000000..6f77c91 --- /dev/null +++ b/examples/2024/16c.txt @@ -0,0 +1,27 @@ +########################### +#######################..E# +######################..#.# +#####################..##.# +####################..###.# +###################..##...# +##################..###.### +#################..####...# +################..#######.# +###############..##.......# +##############..###.####### +#############..####.......# +############..###########.# +###########..##...........# +##########..###.########### +#########..####...........# +########..###############.# +#######..##...............# +######..###.############### +#####..####...............# +####..###################.# +###..##...................# +##..###.################### +#..####...................# +#.#######################.# +#S........................# +########################### \ No newline at end of file diff --git a/examples/2024/README:md b/examples/2024/README:md new file mode 100644 index 0000000..b16ca79 --- /dev/null +++ b/examples/2024/README:md @@ -0,0 +1,4 @@ +# Examples + +# 16c +Thanks to Thanks to https://www.reddit.com/r/adventofcode/comments/1hfhgl1/2024_day_16_part_1_alternate_test_case/ \ No newline at end of file diff --git a/src/bin/2024/15.rs b/src/bin/2024/15.rs index b16047a..05f07a7 100644 --- a/src/bin/2024/15.rs +++ b/src/bin/2024/15.rs @@ -1,4 +1,5 @@ use advent_of_code::{ + find_character, strings::{convert_to_array, line_to_char}, Kartesian, KartesianDirection, Map, }; @@ -30,21 +31,6 @@ fn instructions_to_dir(instructions: &str) -> Vec { 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; @@ -63,7 +49,7 @@ 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 position = find_character(&map, ROBOT); let mut new; for direction in directions { new = position.move_dir(direction.vector(), direction).unwrap(); diff --git a/src/bin/2024/16.rs b/src/bin/2024/16.rs new file mode 100644 index 0000000..8885e3e --- /dev/null +++ b/src/bin/2024/16.rs @@ -0,0 +1,100 @@ +use std::{cmp::Ordering, collections::HashMap, u32}; + +use advent_of_code::{ + find_character, + strings::{convert_to_array, line_to_char}, + Kartesian, KartesianDirection, Map, KD, +}; +#[allow(unused_imports)] +use advent_of_code_macros::{include_data, include_example}; + +include_data!(DATA 2024 16); + +const START: Option = Some('S'); +const WALL: Option = Some('#'); +const END: Option = Some('E'); +const SPACE: Option = Some('.'); + +fn new_score(old_score: u32, old: KD, new: KD) -> u32 { + old_score + + if new == old { + 1 + } else if old == new.neg() { + 2001 + } else { + 1001 + } +} + +fn sorter(a: &(Kartesian, KartesianDirection, u32, Kartesian), b: &(Kartesian, KartesianDirection, u32, Kartesian)) -> Ordering { + a.2.cmp(&b.2).reverse() +} + +fn search_end(map: &Map, startpos: Kartesian, last_dir: KartesianDirection) -> u32 { + let mut posmap: HashMap, u32> = HashMap::new(); + let mut branches = Vec::with_capacity(200); + branches.push((startpos, last_dir, 0, startpos)); + let mut vmap = map.clone(); + let mut best = u32::MAX; + loop { + let (newpos, old_dir, score, oldpos) = match branches.pop() { + Some(b) => b, + None => break, + }; + if !posmap.contains_key(&newpos) { + posmap.insert(newpos, score); + } else { + if score > *posmap.get(&newpos).unwrap() { + continue; + } + posmap.insert(newpos, score); + } + println!("moved {} with increased score {}", old_dir, score); + vmap.set( + newpos, + match old_dir { + KartesianDirection::Left => '←', + KartesianDirection::Top => '↑', + KartesianDirection::Right => '→', + KartesianDirection::Bottom => '↓', + _ => unreachable!(), + }, + ); + for dir in KD::iter(false, false, true) { + let after_move = newpos.move_dir(dir.vector(), dir).unwrap(); + match map.get(after_move) { + WALL => {}, + END => { + if best > new_score(score, old_dir, dir) { + best = new_score(score, old_dir, dir); + } + break; + }, + SPACE | START => { + let added = new_score(score, old_dir, dir); + branches.push((after_move, dir, added, newpos)); + }, + _ => unreachable!(), + } + } + branches.sort_by(sorter); + } + print!("{}", vmap); + best +} + +fn main() { + let map = Map::from(convert_to_array::<_, _, '\n'>(DATA, line_to_char)); + //println!("Startmap: \n{}", map); + let deer = find_character(&map, 'S'); + let best = search_end(&map, deer, KartesianDirection::Right); + println!( + "Best Score is: {}", + best + ) +} + +#[cfg(test)] +mod test { + use super::*; +} diff --git a/src/coordinate_systems/kartesian/external_traits.rs b/src/coordinate_systems/kartesian/external_traits.rs index 3c90d20..92da19e 100644 --- a/src/coordinate_systems/kartesian/external_traits.rs +++ b/src/coordinate_systems/kartesian/external_traits.rs @@ -108,12 +108,12 @@ impl Display for Map { for v in row.iter() { v.fmt(f)? } - for _ in row.len()..=self.maximum.y { + for _ in row.len()..self.maximum.y { T::default().fmt(f)? } println!() } - for _ in self.data.len()..=self.maximum.x { + for _ in self.data.len()..self.maximum.x { for _ in 0..self.maximum.y { T::default().fmt(f)? } diff --git a/src/coordinate_systems/kartesian/map.rs b/src/coordinate_systems/kartesian/map.rs index 9785c76..7178a85 100644 --- a/src/coordinate_systems/kartesian/map.rs +++ b/src/coordinate_systems/kartesian/map.rs @@ -135,3 +135,18 @@ impl From>> for Map { } } } + +pub fn find_character(map: &Map, character: T) -> 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(character) { + return coord; + } + } + } + unreachable!("This function does not expect an non-existing character"); +} diff --git a/src/coordinate_systems/kartesian/test.rs b/src/coordinate_systems/kartesian/test.rs index 11afaf5..966c884 100644 --- a/src/coordinate_systems/kartesian/test.rs +++ b/src/coordinate_systems/kartesian/test.rs @@ -88,7 +88,6 @@ fn diff_dir() { #[test] fn moving_wrapping() { - /* let max: Kartesian = Kartesian::new(10, 10); let mut pos = Kartesian::new(0, 0); let velocity = Velocity::new(1, 1, KartesianDirection::BottomRight); @@ -98,7 +97,6 @@ fn moving_wrapping() { pos = pos.wrapping_move_velocity(velocity, max); } assert_eq!(pos, Kartesian::new(0, 0)); - */ let max = Kartesian::::new(7, 11); assert_eq!(Kartesian::new(2, 0).wrapping_move_velocity(Velocity::new(1, 3, KartesianDirection::TopLeft), max), Kartesian::new(1, 9)); assert_eq!(Kartesian::new(4, 2).wrapping_move_velocity(Velocity::new(3, 2, KartesianDirection::TopRight), max), Kartesian::new(1, 4))