From a32452d1387b672c28220fa47232854326b6db56 Mon Sep 17 00:00:00 2001 From: Joscha Date: Mon, 12 Dec 2022 11:38:24 +0100 Subject: [PATCH] [rs] Solve 2022_12 part 1 --- inputs/2022/2022_12.input | 41 ++++++ inputs/2022/2022_12.solution | 2 + rs/src/main.rs | 1 + rs/src/y2022.rs | 1 + rs/src/y2022/d12.rs | 188 ++++++++++++++++++++++++++++ sample_inputs/2022/2022_12.input | 5 + sample_inputs/2022/2022_12.solution | 2 + 7 files changed, 240 insertions(+) create mode 100644 inputs/2022/2022_12.input create mode 100644 inputs/2022/2022_12.solution create mode 100644 rs/src/y2022/d12.rs create mode 100644 sample_inputs/2022/2022_12.input create mode 100644 sample_inputs/2022/2022_12.solution diff --git a/inputs/2022/2022_12.input b/inputs/2022/2022_12.input new file mode 100644 index 0000000..3bff85e --- /dev/null +++ b/inputs/2022/2022_12.input @@ -0,0 +1,41 @@ +abaaaaacaaaacccccccccaaaaaaccccccccccccccccccccccccccccccccccaaaaaa +abaaaaacaaaaccccaaaaaaaaaacccccccccccccccccccccccccccccccccccaaaaaa +abaaacccaaaaccccaaaaaaaaaaacccaacccccccccccaacccccccccccccccccaaaaa +abaaaacccaacccccaaaaaaaaaaaaaaaaacccccccccccacccccccccccccccccccaaa +abacaacccccccccccaaaaaaaaaaaaaaaaccccccccccaacccccccccccccccccccaaa +abcccacccccccccccaaaaaaaccaaaaaaaccccccccccclllcccccacccccccccccaac +abccccccccccccccccaaaaaccccccccccccccccccclllllllcccccccccccccccccc +abaaacccccccccccccaaaaaccccccccccccccccaakklllllllcccccccccaacccccc +abaaacccccccccccacccaaaccccccccccccccccakkklpppllllccddaaacaacccccc +abaaacccaaacccccaacaaaccccccccccccccccckkkkpppppllllcddddaaaacccccc +abaacccaaaacccccaaaaaccccccccccccccccckkkkpppppppllmmddddddaaaacccc +abaaaccaaaaccccccaaaaaacaaacccccccccckkkkpppuuuppplmmmmdddddaaacccc +abaaacccaaaccccaaaaaaaacaaaaccccccckkkkkoppuuuuuppqmmmmmmdddddacccc +abcccccccccccccaaaaaaaacaaaacccccjkkkkkooppuuuuuuqqqmmmmmmmddddcccc +abccccccccccccccccaaccccaaaccccjjjjkoooooouuuxuuuqqqqqqmmmmmddecccc +abacaaccccccccccccaacccccccccccjjjjoooooouuuxxxuvvqqqqqqqmmmeeecccc +abaaaacccccccacccaccccccccccccjjjjoootuuuuuuxxxyvvvvvqqqqmmmeeecccc +abaaaaacccccaaacaaacccccccccccjjjoooottuuuuuxxyyvvvvvvvqqmnneeecccc +abaaaaaccaaaaaaaaaaccccccccaccjjjooottttxxxxxxyyyyyyvvvqqnnneeecccc +abaaaccccaaaaaaaaaacccccccaaccjjjoootttxxxxxxxyyyyyyvvqqqnnneeecccc +SbcaaccccaaaaaaaaaaccccaaaaacajjjnnntttxxxxEzzzyyyyvvvrrqnnneeccccc +abcccccccaaaaaaaaaaacccaaaaaaaajjjnnntttxxxxyyyyyvvvvrrrnnneeeccccc +abcccccccaaaaaaaaaaacccccaaaaccjjjnnnnttttxxyyyyywvvrrrnnneeecccccc +abcccccccccaaaaaaccaccccaaaaaccciiinnnnttxxyyyyyyywwrrnnnneeecccccc +abccccccccccccaaacccccccaacaaaccciiinnnttxxyywwyyywwrrnnnffeccccccc +abccccccccccccaaacccccccaccaaaccciiinnnttwwwwwwwwwwwrrrnnfffccccccc +abccccccccccccccccccccccccccccccciiinnnttwwwwsswwwwwrrrnnfffccccccc +abaaaccaaccccccccccccccccccccccccciinnnttswwwssswwwwrrroofffacccccc +abaaccaaaaaacccccccccccccccccaaacciinnntssssssssssrrrrooofffacccccc +abaccccaaaaacccccccaaacccccccaaaaciinnnssssssmmssssrrrooofffacccccc +abaacaaaaaaacccccccaaaaccccccaaaaciiinmmmssmmmmmoosroooooffaaaacccc +abaaaaaaaaaaaccccccaaaaccccccaaacciiimmmmmmmmmmmoooooooofffaaaacccc +abcaaaaaaaaaaccccccaaaaccccccccccccihhmmmmmmmhggoooooooffffaaaccccc +abcccccaaacaccccccccaaccccccccccccchhhhhhhhhhhggggggggggffaaacccccc +abaccccaacccccccccccaaaccccccccccccchhhhhhhhhhgggggggggggcaaacccccc +abaaaccccaccccccccccaaaacccaacccccccchhhhhhhaaaaaggggggcccccccccccc +abaaaccccaaacaaaccccaaaacaaaacccccccccccccccaaaacccccccccccccccaaac +abaacccccaaaaaaaccccaaaaaaaaacccccccccccccccaaacccccccccccccccccaaa +abaaaccccaaaaaaccccaaaaaaaaccccccccccccccccccaacccccccccccccccccaaa +abccccccaaaaaaaaaaaaaaaaaaacccccccccccccccccaaccccccccccccccccaaaaa +abcccccaaaaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccccaaaaaa diff --git a/inputs/2022/2022_12.solution b/inputs/2022/2022_12.solution new file mode 100644 index 0000000..11cc47d --- /dev/null +++ b/inputs/2022/2022_12.solution @@ -0,0 +1,2 @@ +Part 1: 383 +Part 2: ??? diff --git a/rs/src/main.rs b/rs/src/main.rs index 308e879..ec02d99 100644 --- a/rs/src/main.rs +++ b/rs/src/main.rs @@ -62,6 +62,7 @@ days! { Y2022D09: "2022_09" => y2022::d09::solve, Y2022D10: "2022_10" => y2022::d10::solve, Y2022D11: "2022_11" => y2022::d11::solve, + Y2022D12: "2022_12" => y2022::d12::solve, } #[derive(Parser)] diff --git a/rs/src/y2022.rs b/rs/src/y2022.rs index a68a352..759a49d 100644 --- a/rs/src/y2022.rs +++ b/rs/src/y2022.rs @@ -9,3 +9,4 @@ pub mod d08; pub mod d09; pub mod d10; pub mod d11; +pub mod d12; diff --git a/rs/src/y2022/d12.rs b/rs/src/y2022/d12.rs new file mode 100644 index 0000000..faf0add --- /dev/null +++ b/rs/src/y2022/d12.rs @@ -0,0 +1,188 @@ +use std::collections::BinaryHeap; + +#[derive(Debug)] +struct Grid { + width: usize, + height: usize, + cells: Vec, +} + +impl Grid { + fn new(width: usize, height: usize, initial_value: T) -> Self + where + T: Clone, + { + Self { + width, + height, + cells: vec![initial_value; width * height], + } + } + + fn index(&self, x: usize, y: usize) -> Option { + if x >= self.width || y >= self.height { + None + } else { + Some(y * self.width + x) + } + } + + fn at(&self, x: usize, y: usize) -> Option<&T> { + Some(&self.cells[self.index(x, y)?]) + } + + fn at_mut(&mut self, x: usize, y: usize) -> Option<&mut T> { + let index = self.index(x, y)?; + Some(&mut self.cells[index]) + } + + fn indexi(&self, x: i32, y: i32) -> Option { + let width = self.width as i32; + let height = self.height as i32; + if x < 0 || x >= width || y < 0 || y >= height { + None + } else { + Some((y * width + x) as usize) + } + } + + fn ati(&self, x: i32, y: i32) -> Option<&T> { + Some(&self.cells[self.indexi(x, y)?]) + } + + fn ati_mut(&mut self, x: i32, y: i32) -> Option<&mut T> { + let index = self.indexi(x, y)?; + Some(&mut self.cells[index]) + } +} + +#[derive(Clone, Copy, Default, PartialEq, Eq)] +struct Candidate { + cost: usize, + pos: (i32, i32), + prev: (i32, i32), +} + +impl Ord for Candidate { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + (other.cost) + .cmp(&self.cost) + .then_with(|| self.pos.cmp(&other.pos)) + .then_with(|| self.prev.cmp(&other.prev)) + } +} + +impl PartialOrd for Candidate { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[derive(Debug, Clone, Copy)] +struct Step { + cost: usize, + prev: (i32, i32), +} + +impl Step { + fn empty() -> Self { + Self { + cost: usize::MAX, + prev: (-1, -1), + } + } +} + +fn neighbours(grid: &Grid, pos: (i32, i32)) -> Vec<(i32, i32)> { + let h = *grid.ati(pos.0, pos.1).unwrap(); + + let mut result = vec![]; + let potential_neighbours = [ + (pos.0 - 1, pos.1), + (pos.0 + 1, pos.1), + (pos.0, pos.1 - 1), + (pos.0, pos.1 + 1), + ]; + for npos in potential_neighbours { + if let Some(nh) = grid.ati(npos.0, npos.1) { + if *nh <= h + 1 { + result.push(npos); + } + } + } + result +} + +fn dijkstra(grid: &Grid, start: (i32, i32), end: (i32, i32)) -> Grid { + let mut steps = Grid::new(grid.width, grid.height, Step::empty()); + + let mut heap = BinaryHeap::new(); + heap.push(Candidate { + cost: 0, + pos: start, + prev: start, + }); + + while let Some(Candidate { cost, pos, prev }) = heap.pop() { + let mut current = steps.ati_mut(pos.0, pos.1).unwrap(); + if pos == end { + current.cost = cost; + current.prev = prev; + break; + } else if cost < current.cost { + current.cost = cost; + current.prev = prev; + + for neighbour in neighbours(grid, pos) { + heap.push(Candidate { + cost: cost + 1, + pos: neighbour, + prev: pos, + }) + } + } + } + + steps +} + +fn path_length(steps: &Grid, start: (i32, i32), end: (i32, i32)) -> usize { + let mut pos = end; + let mut length = 0; + while pos != start { + pos = steps.ati(pos.0, pos.1).unwrap().prev; + length += 1; + } + length +} + +pub fn solve(input: String) { + let width = input.lines().next().unwrap().len(); + let height = input.lines().count(); + + let mut start = (0, 0); + let mut end = (0, 0); + let mut grid = Grid::new(width, height, 0); + for (y, line) in input.lines().enumerate() { + for (x, c) in line.chars().enumerate() { + let c = match c { + 'S' => { + start = (x, y); + 'a' + } + 'E' => { + end = (x, y); + 'z' + } + _ => c, + }; + *grid.at_mut(x, y).unwrap() = c as u32 - 'a' as u32; + } + } + + let starti = (start.0 as i32, start.1 as i32); + let endi = (end.0 as i32, end.1 as i32); + let steps = dijkstra(&grid, starti, endi); + let part1 = path_length(&steps, starti, endi); + println!("Part 1: {part1}"); +} diff --git a/sample_inputs/2022/2022_12.input b/sample_inputs/2022/2022_12.input new file mode 100644 index 0000000..86e9cac --- /dev/null +++ b/sample_inputs/2022/2022_12.input @@ -0,0 +1,5 @@ +Sabqponm +abcryxxl +accszExk +acctuvwj +abdefghi diff --git a/sample_inputs/2022/2022_12.solution b/sample_inputs/2022/2022_12.solution new file mode 100644 index 0000000..a6f74f1 --- /dev/null +++ b/sample_inputs/2022/2022_12.solution @@ -0,0 +1,2 @@ +Part 1: 31 +Part 2: ???