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;
|
||||
|
||||
fn main() {
|
||||
days::d11::solve()
|
||||
days::d12::solve()
|
||||
//_all_days()
|
||||
}
|
||||
|
||||
|
@ -26,4 +26,8 @@ fn _all_days() {
|
|||
days::d09::solve();
|
||||
println!("\nDay 10");
|
||||
days::d10::solve();
|
||||
println!("\nDay 11");
|
||||
days::d11::solve();
|
||||
println!("\nDay 12");
|
||||
days::d12::solve();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue