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