retroactive, to derust my rust

day10 part2

+97 -10
+7
input/day10_simple.test.txt
··· 1 + ..90..9 2 + ...1.98 3 + ...2..7 4 + 6543456 5 + 765.987 6 + 876.... 7 + 987....
+7
input/day10_simple2.test.txt
··· 1 + .....0. 2 + ..4321. 3 + ..5..2. 4 + ..6543. 5 + ..7..4. 6 + ..8765. 7 + ..9....
+25 -3
src/day10.rs
··· 1 - use crate::spatial::{Point, adjacent_cardinal, adjacent_cardinal_points, all_coords, flood}; 1 + use itertools::Itertools; 2 + 3 + use crate::spatial::{ 4 + Point, adjacent_cardinal, adjacent_cardinal_points, all_coords, flood, paths_to_each_point, 5 + print_grid, 6 + }; 2 7 use std::collections::{BTreeSet, HashMap}; 3 8 4 9 pub fn day10_part1(input: &str) -> String { ··· 13 18 } 14 19 15 20 pub fn day10_part2(input: &str) -> String { 16 - todo!() 21 + let topomap = parse(input); 22 + let digraph = topomap_to_digraph(&topomap); 23 + let ratings = all_coords(topomap[0].len(), topomap.len()) 24 + .filter(|pt| topomap[pt.row][pt.col] == 0) 25 + .map(|pt| paths_to_each_point(&digraph, pt)) 26 + .filter(|grid| { 27 + all_coords(topomap[0].len(), topomap.len()) 28 + .any(|pt| topomap[pt.row][pt.col] == 9 && !grid[pt.row][pt.col].is_empty()) 29 + }) 30 + .map(|grid| { 31 + all_coords(topomap[0].len(), topomap.len()) 32 + .filter(|pt| topomap[pt.row][pt.col] == 9) 33 + .map(|pt| grid[pt.row][pt.col].len()) 34 + .sum::<usize>() 35 + }) 36 + .collect_vec(); 37 + dbg!(&ratings); 38 + ratings.iter().sum::<usize>().to_string() 17 39 } 18 40 19 41 fn parse(input: &str) -> Vec<Vec<u8>> { ··· 21 43 .lines() 22 44 .map(|line| { 23 45 line.chars() 24 - .map(|c| c.to_digit(10).unwrap() as u8) 46 + .map(|c| c.to_digit(10).unwrap_or(11) as u8) 25 47 .collect() 26 48 }) 27 49 .collect()
+11 -7
src/lib.rs
··· 359 359 let result = day10::day10_part1(include_str!("../input/day10.txt")); 360 360 assert_eq!(result, "820"); 361 361 } 362 - // #[test] 363 - // fn day10_part2_test() { 364 - // let test_result = day10::day10_part2(include_str!("../input/day10.test.txt")); 365 - // assert_eq!(test_result, "2858"); 366 - // // let result = day10::day10_part2(include_str!("../input/day10.txt")); 367 - // // assert_eq!(result, "6476642796832"); 368 - // } 362 + #[test] 363 + fn day10_part2_test() { 364 + let test_result = day10::day10_part2(include_str!("../input/day10_simple2.test.txt")); 365 + assert_eq!(test_result, "3"); 366 + let test_result = day10::day10_part2(include_str!("../input/day10_simple.test.txt")); 367 + assert_eq!(test_result, "13"); 368 + let test_result = day10::day10_part2(include_str!("../input/day10.test.txt")); 369 + assert_eq!(test_result, "81"); 370 + let result = day10::day10_part2(include_str!("../input/day10.txt")); 371 + assert_eq!(result, "1786"); 372 + } 369 373 370 374 #[test] 371 375 fn day9_part1_test() {
+47
src/spatial.rs
··· 7 7 pub row: usize, 8 8 pub col: usize, 9 9 } 10 + 11 + impl ToString for Point { 12 + fn to_string(&self) -> String { 13 + format!("({}, {})", self.row, self.col) 14 + } 15 + } 16 + 10 17 pub fn all_coords(width: usize, height: usize) -> impl Iterator<Item = Point> { 11 18 (0..height) 12 19 .cartesian_product(0..width) ··· 69 76 70 77 reachable 71 78 } 79 + 80 + //2d spatial dag 81 + pub fn paths_to_each_point( 82 + digraph: &[Vec<Vec<Point>>], 83 + start: Point, 84 + ) -> Vec<Vec<BTreeSet<Vec<Point>>>> { 85 + let mut paths_to_each_point = vec![vec![BTreeSet::new(); digraph.len()]; digraph[0].len()]; 86 + paths_to_each_point[start.row][start.col] = BTreeSet::from_iter([vec![start]]); 87 + let mut frontier = BTreeSet::from_iter([start]); 88 + 89 + while let Some(cursor) = frontier.pop_first() { 90 + println!("cursor is at ({}, {})", cursor.row, cursor.col); 91 + for point in &digraph[cursor.row][cursor.col] { 92 + println!("dealing with adjacent point ({}, {})", point.row, point.col); 93 + frontier.insert(*point); 94 + println!( 95 + "frontier now has {} points: {}", 96 + frontier.len(), 97 + frontier.iter().map(|pt| pt.to_string()).join(", ") 98 + ); 99 + let paths_to_new_point = paths_to_each_point[cursor.row][cursor.col].clone(); 100 + for mut path in paths_to_new_point { 101 + path.push(*point); 102 + paths_to_each_point[point.row][point.col].insert(path); 103 + } 104 + } 105 + } 106 + 107 + dbg!(paths_to_each_point.len()); 108 + paths_to_each_point 109 + } 110 + 111 + pub fn print_grid<T: ToString>(paths: Vec<Vec<T>>) -> Vec<Vec<T>> { 112 + let s = paths 113 + .iter() 114 + .map(|row| row.iter().map(|count| count.to_string()).join("")) 115 + .join("\n"); 116 + println!("{s}\n"); 117 + paths 118 + }