Day 12
This commit is contained in:
parent
39dbb4bcc7
commit
5406f765fd
3 changed files with 176 additions and 1 deletions
41
res/12/input.txt
Normal file
41
res/12/input.txt
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
abccccccccccccccccccaaaaaaaaacccccccccccccccccccccccccccccccccccccaaaa
|
||||||
|
abcccccccccccccccaaaaaaaaaaacccccccccccccccccccccccccccccccccccccaaaaa
|
||||||
|
abcaaccaacccccccccaaaaaaaaaacccccccccccccccccccccaaacccccccccccccaaaaa
|
||||||
|
abcaaaaaaccccccccaaaaaaaaaaaaacccccccccccccccccccaacccccccccccccaaaaaa
|
||||||
|
abcaaaaaacccaaacccccaaaaaaaaaaaccccccccccccccccccaaaccccccccccccccccaa
|
||||||
|
abaaaaaaacccaaaaccccaaaaaacaaaacccccccccccaaaacjjjacccccccccccccccccca
|
||||||
|
abaaaaaaaaccaaaaccccaaaaaaccccccaccccccccccaajjjjjkkcccccccccccccccccc
|
||||||
|
abaaaaaaaaccaaacccccccaaaccccccaaccccccccccajjjjjjkkkaaacccaaaccaccccc
|
||||||
|
abccaaacccccccccccccccaaccccaaaaaaaacccccccjjjjoookkkkaacccaaaaaaccccc
|
||||||
|
abcccaacccccccccccccccccccccaaaaaaaaccccccjjjjoooookkkkcccccaaaaaccccc
|
||||||
|
abcccccccaacccccccccccccccccccaaaacccccccijjjoooooookkkkccaaaaaaaccccc
|
||||||
|
abccaaccaaaccccccccccccccccccaaaaacccccciijjooouuuoppkkkkkaaaaaaaacccc
|
||||||
|
abccaaaaaaaccccccccccaaaaacccaacaaaccciiiiiooouuuuupppkkklllaaaaaacccc
|
||||||
|
abccaaaaaacccccccccccaaaaacccacccaaciiiiiiqooouuuuuupppkllllllacaccccc
|
||||||
|
abcccaaaaaaaacccccccaaaaaaccccaacaiiiiiqqqqoouuuxuuupppppplllllccccccc
|
||||||
|
abccaaaaaaaaaccaaaccaaaaaaccccaaaaiiiiqqqqqqttuxxxuuuppppppplllccccccc
|
||||||
|
abccaaaaaaaacccaaaaaaaaaaacccaaaahiiiqqqttttttuxxxxuuuvvpppplllccccccc
|
||||||
|
abcaaaaaaacccaaaaaaaaaaacccccaaaahhhqqqqtttttttxxxxuuvvvvvqqlllccccccc
|
||||||
|
abcccccaaaccaaaaaaaaaccccccccacaahhhqqqttttxxxxxxxyyyyyvvvqqlllccccccc
|
||||||
|
abcccccaaaccaaaaaaaacccccccccccaahhhqqqtttxxxxxxxyyyyyyvvqqqlllccccccc
|
||||||
|
SbcccccccccccaaaaaaaaaccccccccccchhhqqqtttxxxxEzzzyyyyvvvqqqmmlccccccc
|
||||||
|
abcccccccccccaaaaaaaacccaacccccccchhhppptttxxxxyyyyyvvvvqqqmmmcccccccc
|
||||||
|
abccccccccccaaaaaaaaaaccaacccccccchhhpppptttsxxyyyyyvvvqqqmmmccccccccc
|
||||||
|
abcaacccccccaaaaaaacaaaaaaccccccccchhhppppsswwyyyyyyyvvqqmmmmccccccccc
|
||||||
|
abaaaacccccccaccaaaccaaaaaaacccccccchhhpppsswwyywwyyyvvqqmmmddcccccccc
|
||||||
|
abaaaaccccccccccaaaccaaaaaaacccccccchhhpppsswwwwwwwwwvvqqqmmdddccccccc
|
||||||
|
abaaaacccccccccaaaccaaaaaaccccccccccgggpppsswwwwrrwwwwvrqqmmdddccccccc
|
||||||
|
abccccccaaaaaccaaaacaaaaaaccccccaacccggpppssswwsrrrwwwvrrqmmdddacccccc
|
||||||
|
abccccccaaaaaccaaaacccccaaccccaaaaaacggpppssssssrrrrrrrrrnmmdddaaccccc
|
||||||
|
abcccccaaaaaaccaaaccccccccccccaaaaaacggppossssssoorrrrrrrnnmdddacccccc
|
||||||
|
abcccccaaaaaaccccccccaaaaccccccaaaaacgggoooossoooonnnrrnnnnmddaaaacccc
|
||||||
|
abccccccaaaaaccccccccaaaacccccaaaaaccgggoooooooooonnnnnnnnndddaaaacccc
|
||||||
|
abccccccaaaccccccccccaaaacccccaaaaacccgggoooooooffennnnnnnedddaaaacccc
|
||||||
|
abcccccccccccccccccccaaacccccccaacccccggggffffffffeeeeeeeeeedaaacccccc
|
||||||
|
abccccccccccccccccccaaacccccaccaaccccccggfffffffffeeeeeeeeeecaaacccccc
|
||||||
|
abccccccccccccccccccaaaacccaaaaaaaaaccccfffffffaaaaaeeeeeecccccccccccc
|
||||||
|
abccccccccaacaaccccaaaaaacaaaaaaaaaaccccccccccaaaccaaaaccccccccccccccc
|
||||||
|
abccccccccaaaaacccaaaaaaaaaaacaaaaccccccccccccaaaccccaaccccccccccaaaca
|
||||||
|
abcccccccaaaaaccccaaaaaaaaaaacaaaaacccccccccccaaaccccccccccccccccaaaaa
|
||||||
|
abcccccccaaaaaacccaaaaaaaaaacaaaaaacccccccccccaaccccccccccccccccccaaaa
|
||||||
|
abcccccccccaaaaccaaaaaaaaaaaaaaccaaccccccccccccccccccccccccccccccaaaaa
|
130
src/days/d12.rs
Normal file
130
src/days/d12.rs
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
use std::{fs, collections::{HashMap, HashSet}};
|
||||||
|
|
||||||
|
pub fn solve() {
|
||||||
|
let path = "res/12/input.txt";
|
||||||
|
|
||||||
|
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
|
||||||
|
|
||||||
|
let lines: Vec<&str> = contents
|
||||||
|
.lines()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Build grid
|
||||||
|
let mut start = (0, 0);
|
||||||
|
let mut end = (0, 0);
|
||||||
|
let grid: Vec<Vec<u32>> = lines.iter().enumerate().map(|(y, line)| {
|
||||||
|
line.chars().enumerate().map(|(x, c)|
|
||||||
|
match c {
|
||||||
|
'S' => {
|
||||||
|
start = (x as u32, y as u32);
|
||||||
|
return char_to_numeric('a')
|
||||||
|
|
||||||
|
},
|
||||||
|
'E' => {
|
||||||
|
end = (x as u32, y as u32);
|
||||||
|
return char_to_numeric('z')
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return char_to_numeric(c)
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
// Build adjacent lists
|
||||||
|
let mut adjacents = HashMap::<(u32,u32),Vec<(u32,u32)>>::new();
|
||||||
|
|
||||||
|
grid.iter()
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(y, line)| {
|
||||||
|
line.iter()
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(x, height)| {
|
||||||
|
adjacents.insert((x as u32, y as u32), Vec::<(u32,u32)>::new());
|
||||||
|
// top
|
||||||
|
if y != 0 && grid[y-1][x] <= height+1 {
|
||||||
|
adjacents.get_mut(&(x as u32, y as u32)).unwrap().push((x as u32, (y-1) as u32))
|
||||||
|
}
|
||||||
|
// bot
|
||||||
|
if y != grid.len()-1 && grid[y+1][x] <= height+1 {
|
||||||
|
adjacents.get_mut(&(x as u32, y as u32)).unwrap().push((x as u32, (y+1) as u32))
|
||||||
|
}
|
||||||
|
//left
|
||||||
|
if x != 0 && grid[y][x-1] <= height+1 {
|
||||||
|
adjacents.get_mut(&(x as u32, y as u32)).unwrap().push(((x-1) as u32, y as u32))
|
||||||
|
}
|
||||||
|
// right
|
||||||
|
if x != grid[0].len()-1 && grid[y][x+1] <= height+1 {
|
||||||
|
adjacents.get_mut(&(x as u32, y as u32)).unwrap().push(((x+1) as u32, y as u32))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// task 1 - find min distance between start and end
|
||||||
|
let res = bfs(start, end, &adjacents);
|
||||||
|
|
||||||
|
println!("Result 1: {res}");
|
||||||
|
|
||||||
|
// task 2 - find min distance for each node with height 1, select min
|
||||||
|
let mut distances = Vec::<i32>::new();
|
||||||
|
grid.iter()
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(y, line)| {
|
||||||
|
line.iter()
|
||||||
|
.enumerate()
|
||||||
|
.for_each(|(x, height)| {
|
||||||
|
if *height == 1 {
|
||||||
|
distances.push(
|
||||||
|
bfs((x as u32, y as u32), end, &adjacents)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
let res = *distances.iter()
|
||||||
|
.filter(|dist| **dist != -1)
|
||||||
|
.min()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("Result 2: {res}")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maps lowercase chars to 1..=26
|
||||||
|
fn char_to_numeric(c: char) -> u32 {
|
||||||
|
(c as u32) - ('a' as u32) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runs a Breadth-first search on the given graph and returns the minimal steps necessary to reach end from start, -1 if not reachable
|
||||||
|
fn bfs(start: (u32,u32), end: (u32,u32), adjacents: &HashMap<(u32,u32),Vec<(u32,u32)>>) -> i32 {
|
||||||
|
let mut queue = Vec::<(u32,u32)>::new();
|
||||||
|
let mut seen_nodes = HashSet::<(u32,u32)>::new();
|
||||||
|
let mut predecessor = HashMap::<(u32,u32),(u32,u32)>::new();
|
||||||
|
queue.push(start);
|
||||||
|
seen_nodes.insert(start);
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let node = queue.remove(0);
|
||||||
|
if node == end {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
adjacents.get(&node).unwrap()
|
||||||
|
.iter()
|
||||||
|
.for_each(|child| {
|
||||||
|
if !seen_nodes.contains(child) {
|
||||||
|
queue.push(*child);
|
||||||
|
seen_nodes.insert(*child);
|
||||||
|
predecessor.insert(*child, node);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// if end is reachable, it now is in predecessor
|
||||||
|
let mut res = 0; // steps
|
||||||
|
let mut node = end;
|
||||||
|
while node != start {
|
||||||
|
node = match predecessor.get(&node) {
|
||||||
|
Some(n) => *n,
|
||||||
|
None => return -1 // return -1 if end not reachable
|
||||||
|
};
|
||||||
|
res += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
pub mod days;
|
pub mod days;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
days::d11::solve()
|
days::d12::solve()
|
||||||
//_all_days()
|
//_all_days()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,4 +26,8 @@ fn _all_days() {
|
||||||
days::d09::solve();
|
days::d09::solve();
|
||||||
println!("\nDay 10");
|
println!("\nDay 10");
|
||||||
days::d10::solve();
|
days::d10::solve();
|
||||||
|
println!("\nDay 11");
|
||||||
|
days::d11::solve();
|
||||||
|
println!("\nDay 12");
|
||||||
|
days::d12::solve();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue