Add solution for 2022 day 12
This commit is contained in:
parent
273a54b4ca
commit
c48a7913f5
46
2022/Cargo.lock
generated
46
2022/Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
@ -11,6 +11,7 @@ members = [
|
||||
"./day-09",
|
||||
"./day-10",
|
||||
"./day-11",
|
||||
"./day-12",
|
||||
]
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
| [09] | ✓ | ✓ | [Rust] |
|
||||
| [10] | ✓ | ✓ | [Rust] |
|
||||
| [11] | ✓ | | [Rust] |
|
||||
| [12] | | | |
|
||||
| [12] | ✓ | ✓ | [Rust] |
|
||||
| [13] | | | |
|
||||
| [14] | | | |
|
||||
| [15] | | | |
|
||||
|
14
2022/day-12/Cargo.toml
Normal file
14
2022/day-12/Cargo.toml
Normal 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
5
2022/day-12/Justfile
Normal file
@ -0,0 +1,5 @@
|
||||
@part PART INPUT_FILE="inputs/puzzle.txt":
|
||||
cargo --quiet run --bin part_{{PART}} -- {{INPUT_FILE}}
|
||||
|
||||
clean:
|
||||
cargo clean
|
41
2022/day-12/inputs/puzzle.txt
Normal file
41
2022/day-12/inputs/puzzle.txt
Normal 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
|
5
2022/day-12/inputs/test.txt
Normal file
5
2022/day-12/inputs/test.txt
Normal file
@ -0,0 +1,5 @@
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
41
2022/day-12/src/bin/part_one.rs
Normal file
41
2022/day-12/src/bin/part_one.rs
Normal 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);
|
||||
}
|
||||
}
|
54
2022/day-12/src/bin/part_two.rs
Normal file
54
2022/day-12/src/bin/part_two.rs
Normal 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
109
2022/day-12/src/lib.rs
Normal 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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user