use std::collections::HashMap; use std::time::Instant; use nom::{ bytes::streaming::tag, character::complete::{self, multispace1}, multi::separated_list1, IResult, }; use pathfinding::prelude::dijkstra; fn parse_input(input: &str) -> IResult<&str, Vec>> { let (input, matrix) = separated_list1(multispace1, separated_list1(tag(","), complete::u32))(input)?; Ok((input, matrix)) } fn main() { println!("Hello, this is Patrick"); let now = Instant::now(); let input_text = include_str!("../matrix.txt"); let (_input, matrix) = parse_input(input_text).unwrap(); let l = matrix[0].len(); let mut points: HashMap<(i32, i32), u32> = HashMap::new(); for (row_index, row) in matrix.into_iter().enumerate() { for (column_index, cell) in row.into_iter().enumerate() { points.insert((column_index as i32, row_index as i32), cell); } } let minimal_path: Option<(Vec<(i32, i32)>, u32)> = dijkstra( &(i32::MAX, i32::MAX), |&(column, row)| match (column, row) { (i32::MAX, i32::MAX) => (0..l as i32) .collect::>() .into_iter() .filter_map(|row_number| points.get_key_value(&(0, row_number))) .map(|(&coords, &cost)| (coords, cost)) .collect::>(), (column, row) => vec![(column, row - 1), (column, row + 1), (column + 1, row)] .into_iter() .filter_map(|coords| points.get_key_value(&coords)) .map(|(&coords, &cost)| (coords, cost)) .collect(), }, |&(column, _)| column == l as i32 - 1, ); println!("The minimal path is: {}", minimal_path.unwrap().1); println!("Executed in {:?}", now.elapsed()); }