This commit is contained in:
JonOfUs 2022-12-12 19:33:05 +01:00
parent 39dbb4bcc7
commit 5406f765fd
3 changed files with 176 additions and 1 deletions

41
res/12/input.txt Normal file
View 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
View 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
}

View file

@ -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();
}