d12p2
This commit is contained in:
		| @@ -12,14 +12,15 @@ fn main() { | ||||
|     let file = File::open(&env::args().nth(1).unwrap()).unwrap(); | ||||
|     let mut map: Vec<Vec<i64>> = Vec::new(); | ||||
|     let mut queue = BinaryHeap::new(); | ||||
|     let (mut start, mut end) = ((0, 0), (0, 0)); | ||||
|     let mut end = (0, 0); | ||||
|     let mut starts: Vec<(usize, usize)> = Vec::new(); | ||||
|  | ||||
|     // parse input | ||||
|     for (i, line) in io::BufReader::new(file).lines().flatten().enumerate() { | ||||
|         let mut row: Vec<i64> = Vec::new(); | ||||
|         for (j, c) in line.chars().enumerate() { | ||||
|             match c { | ||||
|                 'S' => { start = (i, j); row.push('a' as i64); }, | ||||
|                 'S' | 'a' => { starts.push((i, j)); row.push('a' as i64); }, | ||||
|                 'E' => { end = (i, j); row.push('z' as i64); }, | ||||
|                 c => row.push(c as i64), | ||||
|             } | ||||
| @@ -35,9 +36,11 @@ fn main() { | ||||
|                     get(&map, end) - get(&map, (i, j)))) | ||||
|             .collect()) | ||||
|         .collect(); | ||||
|          | ||||
|     queue.push((-heur[start.0][start.1], start)); | ||||
|     costs[start.0][start.1] = 0; | ||||
|  | ||||
|     for start in starts.iter() { | ||||
|         queue.push((-heur[start.0][start.1], *start)); | ||||
|         costs[start.0][start.1] = 0; | ||||
|     } | ||||
|  | ||||
|     // A* | ||||
|     let answer = loop { | ||||
|   | ||||
							
								
								
									
										83
									
								
								day12/src/main1.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								day12/src/main1.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| use std::env; | ||||
| use std::fs::File; | ||||
| use std::io::{self, BufRead}; | ||||
| use std::collections::BinaryHeap; | ||||
| use std::cmp::max; | ||||
|  | ||||
| fn get(map: &Vec<Vec<i64>>, coord: (usize, usize)) -> i64 { | ||||
|     map[coord.0 as usize][coord.1 as usize] | ||||
| } | ||||
|  | ||||
| fn main() { | ||||
|     let file = File::open(&env::args().nth(1).unwrap()).unwrap(); | ||||
|     let mut map: Vec<Vec<i64>> = Vec::new(); | ||||
|     let mut queue = BinaryHeap::new(); | ||||
|     let (mut start, mut end) = ((0, 0), (0, 0)); | ||||
|  | ||||
|     // parse input | ||||
|     for (i, line) in io::BufReader::new(file).lines().flatten().enumerate() { | ||||
|         let mut row: Vec<i64> = Vec::new(); | ||||
|         for (j, c) in line.chars().enumerate() { | ||||
|             match c { | ||||
|                 'S' => { start = (i, j); row.push('a' as i64); }, | ||||
|                 'E' => { end = (i, j); row.push('z' as i64); }, | ||||
|                 c => row.push(c as i64), | ||||
|             } | ||||
|         } | ||||
|         map.push(row); | ||||
|     } | ||||
|     let (height, width) = (map.len(), map[0].len()); | ||||
|     let mut costs = vec![vec![i64::MAX; width]; height]; | ||||
|     let heur: Vec<Vec<i64>> = (0..height) | ||||
|         .map(|i| (0..width) | ||||
|             .map(|j| | ||||
|                 max((i.abs_diff(end.0) + j.abs_diff(end.1)) as i64, | ||||
|                     get(&map, end) - get(&map, (i, j)))) | ||||
|             .collect()) | ||||
|         .collect(); | ||||
|          | ||||
|     queue.push((-heur[start.0][start.1], start)); | ||||
|     costs[start.0][start.1] = 0; | ||||
|  | ||||
|     // A* | ||||
|     let answer = loop { | ||||
|         // no route | ||||
|         if queue.is_empty() { | ||||
|             break None; | ||||
|         } | ||||
|  | ||||
|         let (_, (i, j)) = queue.pop().unwrap(); | ||||
|         let cost = get(&costs, (i, j)); | ||||
|  | ||||
|         // found destination | ||||
|         if (i, j) == end { | ||||
|             break Some(cost); | ||||
|         } | ||||
|  | ||||
|         // handle neighbors | ||||
|         let neighbors = [ | ||||
|             (i as i64, (j as i64) - 1), | ||||
|             (i as i64, (j as i64) + 1), | ||||
|             ((i as i64) - 1, j as i64), | ||||
|             ((i as i64) + 1, j as i64)]; | ||||
|         for (nexti, nextj) in neighbors { | ||||
|             if nexti < 0 || nextj < 0 | ||||
|                 || nexti >= height as i64 || nextj >= width as i64 | ||||
|                 || map[nexti as usize][nextj as usize] > map[i][j] + 1 | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|             let nexti: usize = nexti as usize; | ||||
|             let nextj: usize = nextj as usize; | ||||
|             let new_cost = cost + 1; | ||||
|             if new_cost < costs[nexti][nextj] { | ||||
|                 costs[nexti][nextj] = new_cost; | ||||
|                 queue.retain(|(_, (ri, rj))| *ri != nexti || *rj != nextj); | ||||
|                 queue.push((-new_cost - heur[nexti][nextj], (nexti, nextj))); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     println!("= {:?}", answer); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user