Add solution for 2022 day 12

This commit is contained in:
Patrick Auernig 2022-12-14 19:01:37 +01:00
parent 273a54b4ca
commit c48a7913f5
11 changed files with 318 additions and 2 deletions

46
2022/Cargo.lock generated
View File

@ -55,12 +55,48 @@ dependencies = [
"itertools",
]
[[package]]
name = "aoc-2022-12"
version = "0.1.0"
dependencies = [
"itertools",
"petgraph",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "indexmap"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.10.5"
@ -69,3 +105,13 @@ checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "petgraph"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143"
dependencies = [
"fixedbitset",
"indexmap",
]

View File

@ -11,6 +11,7 @@ members = [
"./day-09",
"./day-10",
"./day-11",
"./day-12",
]

View File

@ -15,7 +15,7 @@
| [09] | ✓ | ✓ | [Rust] |
| [10] | ✓ | ✓ | [Rust] |
| [11] | ✓ | | [Rust] |
| [12] | | | |
| [12] | ✓ | ✓ | [Rust] |
| [13] | | | |
| [14] | | | |
| [15] | | | |

14
2022/day-12/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "aoc-2022-12"
version = "0.1.0"
edition = "2021"
[lib]
test = false
doctest = false
[dependencies]
petgraph = "0.6.2"
itertools = "0.10"

5
2022/day-12/Justfile Normal file
View File

@ -0,0 +1,5 @@
@part PART INPUT_FILE="inputs/puzzle.txt":
cargo --quiet run --bin part_{{PART}} -- {{INPUT_FILE}}
clean:
cargo clean

View File

@ -0,0 +1,41 @@
abcccccccccaaaaaaaaaaccccccccccccaaaaaaaaccaaccccccccccccccccccccccccccccccccccccccccccccaaaaaa
abccccccccccaaaaaaaaaccccccccccccaaaaaaaaaaaacccccccccccaacccacccccccccccccccccccccccccccaaaaaa
abcccccccccccaaaaaaacccccccccccccaaaaaaaaaaaaaacccccccccaaacaacccccccccaaaccccccccccccccccaaaaa
abccccccccccaaaaaaccccccccccccccaaaaaaaaaaaaaaaccccccccccaaaaaccccccccccaaacccccccccccccccccaaa
abccccccccccaaaaaaaccccccccccccaaaaaaaaaaaaaacccccccccccaaaaaacccccccccaaaacccccccccccccccccaac
abaaccaaccccaaccaaaccccccccaaaaaaaaaaaaaaacaaccccccccccaaaaaaaacccccccccaaalcccccccccccccccaaac
abaaaaaacccccccccaaccccccccaaaaaacccaaaacccaaccccccccccaaaaaaaaccccccccalllllllcccccccccccccccc
abaaaaaacccccccaaacccccccccaaaaccccccaaaccccaaaaacccccccccaacccccccaaaakllllllllcccccccaacccccc
abaaaaaacccccccaaaacccccccccaacccccccaaaccccaaaaacccccccccaacccccccaakkklllpllllccccacaaacccccc
abaaaaaaaccccccaaaaccccaaccccccccccccccccccaaaaaaccccccccccccccccccckkkkpppppplllcccaaaaaaacccc
abaaaaaaacaaaccaaaaccaaaaaaccccccccccccccccaaaaaacccccccaaaccccckkkkkkkpppppppplllcddaaaaaacccc
abcaaaacccaacccccccccaaaaaacccccaaaccccccccaaaaaacccccccaaaaccjkkkkkkkpppppuppplmmdddddaaaccccc
abccaaaaaaaaaccccccccaaaaaaccccaaaaaacccccccaaacccccccccaaaajjjkkkkkrpppuuuuupppmmmdddddacccccc
abccccaaaaaaaacccccccaaaaacccccaaaaaacccccccccccccccccccaaacjjjjrrrrrrppuuuuupqqmmmmmddddaccccc
abccccaaaaaaaaacccccccaaaacccccaaaaaaccccccccccccccccccccccjjjrrrrrrrrpuuuxuvvqqqmmmmmddddccccc
abccccaaaaaaaaacccccccccccccccccaaaaaccccaacccaccccccccaaccjjjrrrruuuuuuuxxyvvqqqqqmmmmmdddcccc
abccccaaaaaaaacccccccccaaaccccccaacaaccccaaacaacccaaacaaaccjjjrrrtuuuuuuuxxyvvvqqqqqmmmmdddcccc
abccaaaaaaaacccccccccccaaaaaccccccccccccccaaaaacccaaaaaaaccjjjrrttttxxxxxxyyvvvvvqqqqmmmmdeeccc
abccaaaccaaaccccccccaacaaaaacccccccccccccaaaaaacccaaaaaacccjjjrrtttxxxxxxxyyvvvvvvvqqqmmmeeeccc
abaaaaaaaaaacccaaaccaaaaaaaaaaaccaaaccccaaaaaaaacccaaaaaaaajjjqqrttxxxxxxxyyyyyyvvvqqqnnneeeccc
SbaaaaaaaaccccaaaaccaaaaaaaaaaaaaaaaacccaaaaaaaaccaaaaaaaaacjjjqqtttxxxxEzzyyyyvvvvqqqnnneeeccc
abcaaaaaacccccaaaaccccaaaaaaaccaaaaaaccccccaaccccaaaaaaaaaaciiiqqqtttxxxyyyyyyvvvvrrrnnneeecccc
abcaaaaaacccccaaaacccaaaaaaaaccaaaaaaccccccaaccccaaacaaacccciiiqqqqttxxyyyyyywvvvrrrnnneeeecccc
abcaaaaaaccccccccccccaaaaaaaaacaaaaacccccccccccccccccaaaccccciiiqqtttxxyyyyyywwrrrrnnnneeeccccc
abcaaacaacccccaacccccaaaaaaaaacaaaaacccccccccccccccccaaaccccciiiqqttxxxywwyyywwrrrnnnneeecccccc
abccccccccaaacaaccccccccccacccccccccccccccccccccccccccccccccciiqqqttxxwwwwwwywwrrrnnneeeccccccc
abccaacccccaaaaaccccccccccccccccccccccccccccccccccccccccaacaaiiqqqttwwwwsswwwwwrrrnnfffeccccccc
abaaaaccccccaaaaaacccccccccccccccccccccccccccccaaaccccccaaaaaiiqqqttssssssswwwwrrronfffaccccccc
abaaaaaacccaaaaaaacccccccccccccccccccccccccccaaaaaacccccaaaaaiiqqqssssssssssswrrrooofffaaaacccc
abaaaaaaccaaaaaacccccccccccccccccccccccccccccaaaaaacccccaaaaaiiqqqppssspppssssrrrooofffaaaacccc
abaaaaaaccaacaaacccccccccccccccccccccccccccccaaaaaacccccaaaaaiihpppppppppppossrrooofffaaaaacccc
abaaaaccccccccaacccccccccccccccccccccccccccccaaaaaccccccccaaahhhhppppppppppoooooooofffaaaaccccc
abaaaaccccccccccaacccccccccccccccccaaacccccccaaaaacccccccccccchhhhhhhhhhggpoooooooffffaaaaccccc
abccaacccccccacaaaccccccccccccccccaaaaacccccccccccccccccccccccchhhhhhhhhggggoooooffffaacaaacccc
abccccccccccaaaaacaaccccccccccccccaaaaaccccccccccccccccccccccccchhhhhhhhggggggggggffcaacccccccc
abccccccccccaaaaaaaaccccccccccccccaaaacccaacccccccccccaccccccccccccccaaaaaggggggggfcccccccccccc
abccccccccccccaaaaaccccaacccccccccaaaacaaaaccccccccaaaaccccccccccccccaaaacaaagggggcccccccccaccc
abcccccccccccaaaaacccccaacccccccccaaaaaaaaaccccccccaaaaaaccccccccccccaaaccaaaacccccccccccccaaac
abcccccccccccaacaaccaaaaaaaacccaaaaaaaaaaaccccccccccaaaaccccccccccccccaccccaaacccccccccccccaaaa
abccccccccccccccaaccaaaaaaaaccaaaaaaaaaaaccccccccccaaaaacccccccccccccccccccccacccccccccccccaaaa
abccccccccccccccccccccaaaaacccaaaaaaaaaaaacccccccccaacaacccccccccccccccccccccccccccccccccaaaaaa

View File

@ -0,0 +1,5 @@
Sabqponm
abcryxxl
accszExk
acctuvwj
abdefghi

View File

@ -0,0 +1,41 @@
use std::{env, io};
use aoc_2022_12::{parse_input, Graph};
use petgraph::algo::dijkstra;
fn main() -> io::Result<()> {
let infile_path = env::args().nth(1).expect("input file");
let result = solve(&infile_path)?;
println!("{result}");
Ok(())
}
fn solve(path: &str) -> io::Result<i32> {
let (start, end, points) = parse_input(path)?;
let graph = Graph::from_edges(points);
let result = dijkstra(&graph, start, Some(end), |_| 1);
Ok(result[&end])
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn sample() {
let result = solve("inputs/test.txt").unwrap();
assert_eq!(31, result)
}
#[test]
fn puzzle() {
let result = solve("inputs/puzzle.txt").unwrap();
assert_eq!(420, result);
}
}

View File

@ -0,0 +1,54 @@
use std::{env, io};
use aoc_2022_12::{parse_input, Graph};
use itertools::Itertools;
use petgraph::algo::dijkstra;
fn main() -> io::Result<()> {
let infile_path = env::args().nth(1).expect("input file");
let result = solve(&infile_path)?;
println!("{result}");
Ok(())
}
fn solve(path: &str) -> io::Result<i32> {
let (_, end, points) = parse_input(path)?;
let potential_starting_points = points
.iter()
.filter_map(|(a, _)| if a.2 == 1 { Some(*a) } else { None })
.unique()
.collect::<Vec<_>>();
let graph = Graph::from_edges(points);
let result = potential_starting_points
.into_iter()
.filter_map(|start| {
let result = dijkstra(&graph, start, Some(end), |_| 1);
result.get(&end).copied()
})
.min()
.unwrap();
Ok(result)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn sample() {
let result = solve("inputs/test.txt").unwrap();
assert_eq!(29, result)
}
#[test]
fn puzzle() {
let result = solve("inputs/puzzle.txt").unwrap();
assert_eq!(414, result);
}
}

109
2022/day-12/src/lib.rs Normal file
View File

@ -0,0 +1,109 @@
use std::{
collections::HashMap,
fs::File,
io::{self, BufRead, BufReader},
iter,
path::Path,
};
use petgraph::prelude::DiGraphMap;
pub type Graph = DiGraphMap<PointWithHeight, ()>;
type PointWithHeight = (i32, i32, i32);
pub struct HeightMap {
items: HashMap<(i32, i32), i32>,
width: i32,
height: i32,
}
impl HeightMap {
pub fn new() -> Self {
Self {
items: HashMap::new(),
width: 0,
height: 0,
}
}
}
pub fn parse_input<P>(
path: P,
) -> io::Result<(
PointWithHeight,
PointWithHeight,
Vec<(PointWithHeight, PointWithHeight)>,
)>
where
P: AsRef<Path>,
{
let file = File::open(path)?;
let mut height_map = HeightMap::new();
let mut start_point = None;
let mut end_point = None;
for (line_idx, line) in BufReader::new(file).lines().enumerate() {
let line = line?;
for (cell_idx, cell) in line.chars().enumerate() {
height_map.width = (cell_idx + 1) as i32;
let point = (line_idx as i32, cell_idx as i32);
let height = if cell == 'S' {
start_point = Some((point.0, point.1, 1));
1
} else if cell == 'E' {
end_point = Some((point.0, point.1, 26));
26
} else {
(cell as u8 - 96).into()
};
height_map.items.insert(point, height);
}
height_map.height += 1
}
let edges = build_edges(&height_map);
let start_point = start_point.expect("no start point");
let end_point = end_point.expect("no end point");
Ok((start_point, end_point, edges))
}
fn build_edges(map: &HeightMap) -> Vec<(PointWithHeight, PointWithHeight)> {
map.items
.keys()
.flat_map(|point @ (x, y)| {
let neighbors =
[(-1, 0), (0, 1), (1, 0), (0, -1)]
.iter()
.filter_map(move |(nx, ny)| {
let dx = x + nx;
let dy = y + ny;
let inside_bounds =
(0..map.height).contains(&dx) && (0..map.width).contains(&dy);
if inside_bounds {
Some((dx, dy))
} else {
None
}
});
iter::repeat(point).zip(neighbors).filter_map(|(a, b)| {
let height_self = map.items[&(a.0, a.1)];
let height_neighbor = map.items[&(b.0, b.1)];
if height_self + 1 >= height_neighbor {
Some(((a.0, a.1, height_self), (b.0, b.1, height_neighbor)))
} else {
None
}
})
})
.collect()
}

View File

@ -9,4 +9,4 @@
- [2019](2019/README.md) (0% completed)
- [2020](2020/README.md) (20% completed)
- [2021](2021/README.md) (68% completed)
- [2022](2022/README.md) (42% completed)
- [2022](2022/README.md) (46% completed)