From da257be7a7f697f00e07a96bfcc78a115dfbfd7c Mon Sep 17 00:00:00 2001 From: Dory Date: Sun, 17 Mar 2024 16:31:00 -0700 Subject: [PATCH] d12p2 --- day12/src/main.rs | 13 +++++--- day12/src/main1.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 day12/src/main1.rs diff --git a/day12/src/main.rs b/day12/src/main.rs index c04f988..91b52bf 100644 --- a/day12/src/main.rs +++ b/day12/src/main.rs @@ -12,14 +12,15 @@ fn main() { let file = File::open(&env::args().nth(1).unwrap()).unwrap(); let mut map: Vec> = 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 = 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 { diff --git a/day12/src/main1.rs b/day12/src/main1.rs new file mode 100644 index 0000000..c04f988 --- /dev/null +++ b/day12/src/main1.rs @@ -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>, 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::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 = 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> = (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); +} +