2022 - Day 12
This commit is contained in:
parent
8ab48001ea
commit
9a495ccd77
41
2022/input/12/input
Normal file
41
2022/input/12/input
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
abcccccccccccaaaaacccccccaaaaaaccccccccccccccccccccccccccccccccaaaaaaaaaaaaaacccccccccccccccccccaaaaaacccccccacccccccccaaccaaccccccccccccccccccccccccccccccaaaaaa
|
||||||
|
abcccccccccccaaaaaaacccccaaaaaaccccccccaaccccccccccaaaaccccccccaaaaaaaaaaaaaccccccccccccccccccccaaaaaaccccaaaacccccccccaaaaaaccccccccccccccccccccccccccccccccaaaa
|
||||||
|
abccccccccccaaaaaaaacccccaaaaaccccccccaaaacccccccccaaaacccccccccccaaaaaaacccccccccccccccccccccccaaaaacccccaaaaaaccccccccaaaaacccccccccccaaaccccccccccccccccccaaaa
|
||||||
|
abccccccccccaaaaaaaaccccccaaaaacccccccaaaacccccccccaaaacccccaaaccccaaaaaaccccccccccccccccccccccccaaaaacccccaaaaacccccccaaaaaacccccccccccaaaacccccccccccccccccaaaa
|
||||||
|
abccccccccccaaaaaaccccccccaaaaacccccccaaaaccccccccccaaacccccaaaaccaaaaaaaacccccccccccccccccccccccaaaaaccccaaaaacccccccaaaaaaaaccccccccccaaaaccaaccccccccccccaaaaa
|
||||||
|
abcccccccccccccaaaccccccccccccccccccccccccccccccccccccccccccaaaaccaaaaaaaaccccccccccccccccccccccccccccccccaccaaccccaaaaaaaaaaacccccccccccaaaaaaccccccccccccccaccc
|
||||||
|
abcacccccccccccccaaaccccccccccccccaaacccccccccccccccccccccccaaaccaaaacccaaacccccccccccccccccccccccaacccccccccccccccaaacccaaccccccccccccccaaaalllllccccccccccccccc
|
||||||
|
abaacccccccccccccaaaaaacccccccccccaaaccccccccccccccccccccccccccccaaaccccaaaccccccccccccccccccccccaaccccccccccccccccaaaaaaaaccccccccccccccckklllllllccccaaaccccccc
|
||||||
|
abaaaaacccccccccaaaaaaacccccccccaaaaaaaacccccaacccccccccccccccccccccccccaaaccccccccaacccccccccaaaaacaacaacaacccccaaaaaaaaccccccccccccaaakkkkllllllllcccaaaccccccc
|
||||||
|
abaaaaaccccccccaaaaaaaacccccccccaaaaaaaacccccaaaaaacccccccccccccccccccccaaaccccccaaaacacccccccaaaaaaaacaaaaaccccaaaaaaaaaccccccccckkkkkkkkkklsssslllcccaaaaaacccc
|
||||||
|
abaaaccccccccccaaaaaaacccccccccccaaaaacccccccaaaaaaccccccccccccccccccaaaaaaaaccccaaaaaacccccccccaaaaacaaaaacccccaaaaaaaacccaaaccjjkkkkkkkkkssssssslllcccaaaaacccc
|
||||||
|
abaaaccccccccccccaaaaaacccccaacccaaaaaaccccaaaaaaaccaaaccccccccccccccaaaaaaaacccccaaaacccccccccaaaaaccaaaaaacccccccaaaaaaccaaaajjjjkkkkkkssssssssslllcddaaaaccccc
|
||||||
|
abcaaacccccccccccaaaaaacaaacaacccaaaaaaccccaaaaaaaaaaaaaaccccccccccccccaaaaaccccccaaaaccccaaaaaaacaaacccaaaaaaacccaaaaaaaccaaajjjjrrrrrrssssuuuussqmmddddaaaccccc
|
||||||
|
abccaacccccccccccaaccccccaaaaacccaaaccaccccaaaaaaaaaaaaaacccccccccccccaaaaaacccccaacaaccccaaaaacccaaccccacccaaaaaaaaaccaaccaaajjjrrrrrrrrssuuuuuvqqmmmdddaaaccccc
|
||||||
|
abccccccccaaccccccccccccccaaaaaacccccccccccccaaaaaaaaaaaccccccccccccccaaaaaacccccccccccccaaaaaaccccccccccccaaaaaaaaaacccccccccjjjrrruuuuuuuuuuuvvqqmmmmddddaccccc
|
||||||
|
abaacccccaaaaccccccccccccaaaaaaacccccccccccccaacccccaaaaacccccccccccccaccaaacccccccccccccaaaaaacccccccccccaaaaaaaaccccccccccccjjjrrruuuuuuuuxyyvvqqqmmmddddcccccc
|
||||||
|
abaacccccaaaacccccccccccaaaaaaccccccccaaccccccccacccaaaaacccccccccccccccccccccccccccccccccaaaaacccccccccccaaaaaaacccccccccccccjjjrrttuxxxxuxxyyvvqqqqmmmmddddcccc
|
||||||
|
abaacccccaaaacccccccccccaacaaacccccaaaaacccaaaaaaaccccccccccccccccccccccccccccccccccccccccaaacccccccccccccccaaaaaaccccccccccccjjjrrtttxxxxxxyyyvvqqqqqmmmmdddcccc
|
||||||
|
abacccccccccccccccccccccccccaaccccccaaaaaccaaaaaaaccccccccaaccccccccccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccccccjjjqrrttxxxxxxyyyvvvvqqqqmmmdddcccc
|
||||||
|
abccccccccccccccccccccccccccccccccccaaaaaccaaaaaaacccccccaaaccccccccccaaaccccccccccccccccccaaaccccccccccccccaaccccccccccaaccccjjjqqqtttxxxxxyyyyyvvvqqqqmmmeeeccc
|
||||||
|
SbaaccccccaccaaacccccccccccccccccccaaaaacccaaaaaaaaccccaaaaaaaacccccccaaacaaccccccccccccccaaaaaaccccccccccccccccccccccaaaaaaccciiiqqqttxxxxEzyyyyyvvvqqqnnneeeccc
|
||||||
|
abaaccccccaaaaaaccccccccccccccccccccccaaccaaaaaaaaaacccaaaaaaaacccccaaaaaaaaccccccccccccccaaaaaaccccccccccccccccccccccaaaaaaccciiiqqtttxxxyyyyyyyvvvvqqqnnneeeccc
|
||||||
|
abaaaaacccaaaaaaccccccccccccccccccccccccccaaaaaaaaaaccccaaaaaaccccccaaaaaaaaccccccccccccccaaaaaacccccccccccccccccccccccaaaaacciiiqqqttxxyyyyyyywvvvvrrrqnnneeeccc
|
||||||
|
abaaaaacccaaaaaaaccccccccaaaccccccccccccccaacaaaccccccccaaaaaaccccccaaaaaaaccccccccccccccccaaaaaccccccccccccccccccccccaaaaaccciiiqqtttxxxyyyyywwwvrrrrrnnneeecccc
|
||||||
|
abaaaccccaaaaaaaaccccccccaaaacccccccccccccccccaaccccccccaaaaaaccccccccaaaaaccccccccccccccccaacaaccccccccccccccccccccccaaaaaccciiqqqttxxxwwwwyyywwrrrrnnnnneeecccc
|
||||||
|
abaaaccccaaaaaaaaccccccccaaaacccccaaaaacccccccaaccccccccaaccaacccccccaaacaaacccccccccccccccccccccccccccccccccccccccccccccccccciiqqqtttwwwwwwywwwrrrrnnnnneeeccccc
|
||||||
|
abcaaaccccccaaaccccccccccaaaccccccaaaaacccccccccccccaaaaccccccccccccccaacccccccccccccccccccccccccccccccaaaacccccccccccccccccciiiqqqtttssssswwwwwrrrnnnneeeecccccc
|
||||||
|
abccaaccccccaaaccccccccccccccccccaaaaaacccccccccccccaaaaccccccccccccccccccccccccccccccccccccccccccccccaaaaacccccccccccccccccciiiqqqqtssssssswwwwrronnnfeeeacccccc
|
||||||
|
abcccccccccccccccccccccccccccccccaaaaaacccccccccccccaaaaccccccccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccccccccccciiiiqqppssssssswwwwrroonfffeaacccccc
|
||||||
|
abcccccccccccccccccccccccccccccccaaaaaacaaaccccccccccaacccccccccccccccccccccccccccccccccaaacccccccccccaaaaaaccccccccccccccccccihhpppppppppsssssrrroonfffaaaaacccc
|
||||||
|
abcccccccccccccccccccccccccccccccccaacccaaaaacccccccccccccccccccccccccccccccccccccccccccaaaaaaccccccccaaaaaccccccccccccccccccchhhhppppppppppssssrooofffaaaaaacccc
|
||||||
|
abccccccccaaaccccccccccccccccccccccccccaaaaacccccccccccccccccccccccccccccccccccccaccccaaaaaaaaccccccccccaaacccccccccccccccccccchhhhhhhhhpppposssoooofffaaaaaccccc
|
||||||
|
abccccccccaaaacccccaaccccccccccccccccccaaaaaccccccccccccccccccccccccaaccccccccccaaccccaaaaaaaacccccccccccccccccccccccccccccccccchhhhhhhhhgppooooooofffaaaaacccccc
|
||||||
|
abaaccccccaaaacccccaacaaccccccccccccccccaaaaacccccccccccccccaacaaccaaaaaaccccaaaaacaacaaaaaaacccccccccccccccccccccccccccccccccccccchhhhhhgggooooooffffaaaaaaccccc
|
||||||
|
abaaacccccaaaacccccaaaaaccccccccccccccccaaccccccccccccccccccaaaaaccaaaaaaccccaaaaaaaacccaaaaaccccccccccccccccccccccccaaacaacccccccccccccgggggooooffffccccaacccccc
|
||||||
|
abaaaccccccccccccaaaaaaccccaaccccccccccccccccccaaacccccccccccaaaaaaaaaaaacaacccaaaaaccccaacaaacccccccccccccccccccccccaaaaaaccccccccccccccaggggggggfffcccccccccccc
|
||||||
|
abaaaccccccccccccaaaaaaaacaaaaccccccccaaaccccccaaaacccccccccaaaaaaaaaaaaaaaaccaaaaacccccaaaaaccccccccccccccaaccccccccaaaaaaccccccccccccccaagggggggfccccccccccccca
|
||||||
|
abaacccccccccccccaccaaaaacaaaaccccccccaaaccccccaaaacccccccccaaaaccaaaaaaaaaaccaacaaaccccccaaaccccccccccccaaaaaacccccaaaaaaacccccccccccccaaaaccggggcccccccccccccaa
|
||||||
|
abaacccccccccccccccaaacaccaaaacccccaaaaaaaaccccaaaccccccccccccaaccaaaaaaaacccccccaacccccaacaaaaacccccccccaaaaaacccccaaaaaaaaccccccccccccaaaccccccccccccccccaaacaa
|
||||||
|
abcccccccccccccccccaaccccccccccccccaaaaaaaaccccccccccccccccccccaaaaaaaaaaaccccccccccccccaaaaaaaacccccccccaaaaaacccccaaaaaaaaccccccccccccacaccccccccccccccccaaaaaa
|
||||||
|
abccccccccccccccccccccccccccccccccccaaaaaacccccccccccccccccccccaaaaaaaaaaaaccccccccccccccaaaaaaccccccccccaaaaaccccccccaaacccccccccccccccccccccccccccccccccccaaaaa
|
5
2022/input/12/test-1
Normal file
5
2022/input/12/test-1
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
Sabqponm
|
||||||
|
abcryxxl
|
||||||
|
accszExk
|
||||||
|
acctuvwj
|
||||||
|
abdefghi
|
219
2022/src/bin/day12.rs
Normal file
219
2022/src/bin/day12.rs
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
#![feature(test)]
|
||||||
|
use core::fmt;
|
||||||
|
use std::{str::FromStr, cmp::{max, min}};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use aoc::Solver;
|
||||||
|
|
||||||
|
// -- Runners --
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
Day::solve()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_test1() -> Result<()> {
|
||||||
|
Day::test(Day::part1, "test-1", 31)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn part1_solution() -> Result<()> {
|
||||||
|
Day::test(Day::part1, "input", 481)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn part2_test1() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "test-1", 29)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn part2_solution() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "input", 480)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmarks
|
||||||
|
extern crate test;
|
||||||
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
|
fn part1_bench(b: &mut test::Bencher) {
|
||||||
|
Day::benchmark(Day::part1, b)
|
||||||
|
}
|
||||||
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
|
fn part2_bench(b: &mut test::Bencher) {
|
||||||
|
Day::benchmark(Day::part2, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
struct Position {
|
||||||
|
x: isize,
|
||||||
|
y: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Node {
|
||||||
|
height: u32,
|
||||||
|
visited: bool,
|
||||||
|
distance: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Hill {
|
||||||
|
nodes: Vec<Vec<Node>>,
|
||||||
|
size: (isize, isize),
|
||||||
|
start: Position,
|
||||||
|
end: Position,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Hill {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
for line in self.nodes.iter() {
|
||||||
|
for node in line {
|
||||||
|
if node.distance == u32::MAX {
|
||||||
|
write!(f, "[--.]")?;
|
||||||
|
} else {
|
||||||
|
let mut v = '.';
|
||||||
|
if node.visited {
|
||||||
|
v = 'v';
|
||||||
|
}
|
||||||
|
write!(f, "[{:>2}{}]", node.distance, v)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeln!(f, "")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Hill {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
|
|
||||||
|
let mut start = Position{x: 0, y: 0};
|
||||||
|
let mut end = Position{x: 0, y: 0};
|
||||||
|
|
||||||
|
let mut xmax = 0;
|
||||||
|
let mut ymax = 0;
|
||||||
|
|
||||||
|
let nodes = input
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(y, line)| {
|
||||||
|
ymax = max(ymax, y+1);
|
||||||
|
line
|
||||||
|
.chars()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(x, mut letter)| {
|
||||||
|
xmax = max(xmax, x+1);
|
||||||
|
if letter == 'S' {
|
||||||
|
start = Position{x: x as isize, y: y as isize};
|
||||||
|
letter = 'a';
|
||||||
|
} else if letter == 'E' {
|
||||||
|
end = Position{x: x as isize, y: y as isize};
|
||||||
|
letter = 'z';
|
||||||
|
}
|
||||||
|
let height = convert_height(letter);
|
||||||
|
Node {height, visited: false, distance: u32::MAX}
|
||||||
|
}).collect()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
Ok(Self { nodes, size: (xmax as isize, ymax as isize), start, end })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hill {
|
||||||
|
fn dijkstra<T: Fn(u32, u32) -> bool>(&mut self, f: T) {
|
||||||
|
let mut unvisited = (0..self.size.1).flat_map(|y| (0..self.size.0).map(move |x| Position{ x, y })).collect::<Vec<_>>();
|
||||||
|
let mut current = self.start;
|
||||||
|
self.nodes[current.y as usize][current.x as usize].distance = 0;
|
||||||
|
loop {
|
||||||
|
let mut neighbours = vec![
|
||||||
|
Position{x: current.x, y: current.y-1}, // Up
|
||||||
|
Position{x: current.x-1, y: current.y}, // Left
|
||||||
|
Position{x: current.x, y: current.y+1}, // Down
|
||||||
|
Position{x: current.x+1, y: current.y}, // Right
|
||||||
|
];
|
||||||
|
|
||||||
|
let height = self.nodes[current.y as usize][current.x as usize].height;
|
||||||
|
|
||||||
|
// We only want to update valid neighbours that have not been visited yet
|
||||||
|
neighbours.retain(|n| {
|
||||||
|
n.x >= 0 && n.x < self.size.0 && n.y >= 0 && n.y < self.size.1 && !self.nodes[n.y as usize][n.x as usize].visited && f(height, self.nodes[n.y as usize][n.x as usize].height)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the distance of all the neighbours
|
||||||
|
let distance = self.nodes[current.y as usize][current.x as usize].distance;
|
||||||
|
for n in neighbours.iter() {
|
||||||
|
let node = &mut self.nodes[n.y as usize][n.x as usize];
|
||||||
|
node.distance = min(node.distance, distance+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark current node as visited and remove it from the list of unvisited nodes
|
||||||
|
self.nodes[current.y as usize][current.x as usize].visited = true;
|
||||||
|
unvisited.retain(|p| *p != current);
|
||||||
|
|
||||||
|
// We have visited all the nodes, so we are done
|
||||||
|
if unvisited.len() == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next position we are going to visit, this will be the node with the lowest
|
||||||
|
// distance value
|
||||||
|
current = *unvisited.iter().reduce(|s, p| {
|
||||||
|
if self.nodes[p.y as usize][p.x as usize].distance < self.nodes[s.y as usize][s.x as usize].distance {
|
||||||
|
p
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}).unwrap();
|
||||||
|
|
||||||
|
// Remaining nodes are unreachable, we are done
|
||||||
|
if self.nodes[current.y as usize][current.x as usize].distance == u32::MAX {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step_required(&self, position: Position) -> u32 {
|
||||||
|
self.nodes[position.y as usize][position.x as usize].distance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_height(letter: char) -> u32 {
|
||||||
|
(letter as u8 - b'a') as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Solution --
|
||||||
|
pub struct Day;
|
||||||
|
impl aoc::Solver for Day {
|
||||||
|
type Output1 = u32;
|
||||||
|
type Output2 = u32;
|
||||||
|
|
||||||
|
fn day() -> u8 {
|
||||||
|
12
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> Self::Output1 {
|
||||||
|
let mut hill = Hill::from_str(input).unwrap();
|
||||||
|
// We can go down as many as we want, but only one up
|
||||||
|
hill.dijkstra(|current, neighbour| neighbour <= current+1);
|
||||||
|
hill.step_required(hill.end)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> Self::Output2 {
|
||||||
|
let mut hill = Hill::from_str(input).unwrap();
|
||||||
|
|
||||||
|
// We now want to start from the end position
|
||||||
|
std::mem::swap(&mut hill.start, &mut hill.end);
|
||||||
|
|
||||||
|
// We are now starting from the end, so we need to flip the condition around
|
||||||
|
// We can go up as many as we want, but we can only go down one
|
||||||
|
hill.dijkstra(|current, neighbour| neighbour+1 >= current);
|
||||||
|
|
||||||
|
hill.nodes.iter().flatten().filter(|node| node.height == 0).fold(u32::MAX, |acc, node| min(acc, node.distance))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user