Advertisement
Guest User

Untitled

a guest
Dec 3rd, 2023
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.12 KB | Software | 0 0
  1. use std::collections::{BTreeMap, HashSet, VecDeque};
  2.  
  3. fn main() {
  4.     let input = include_str!("../../input.txt");
  5.     let grid = get_grid(input);
  6.     let count = count_part_numbers(grid);
  7.  
  8.     println!("{count}")
  9. }
  10.  
  11. fn count_part_numbers(grid: BTreeMap<(i32, i32), Component>) -> u32 {
  12.     let neighbors = [
  13.         (-1, -1),
  14.         (-1, 0),
  15.         (-1, 1),
  16.         (0, 1),
  17.         (1, 1),
  18.         (1, 0),
  19.         (1, -1),
  20.         (0, -1),
  21.     ];
  22.  
  23.     let mut visited: HashSet<(i32, i32)> = HashSet::new();
  24.     let mut part_numbers: Vec<u32> = Vec::new();
  25.     for ((r, c), comp) in grid.iter() {
  26.         if let Component::Symbol = comp {
  27.             for (dx, dy) in neighbors {
  28.                 let (x, y) = (r + dx, c + dy);
  29.                 if visited.contains(&(x, y)) {
  30.                     continue;
  31.                 }
  32.  
  33.                 let neighbor = grid.get(&(x, y));
  34.                 if let Some(&Component::Value(_)) = neighbor {
  35.                     let num = capture_number((x, y), &grid, &mut visited);
  36.                     part_numbers.push(num)
  37.                 }
  38.             }
  39.         }
  40.     }
  41.  
  42.     part_numbers.into_iter().sum()
  43. }
  44.  
  45. pub fn capture_number(
  46.     (r, c): (i32, i32),
  47.     grid: &BTreeMap<(i32, i32), Component>,
  48.     visited: &mut HashSet<(i32, i32)>,
  49. ) -> u32 {
  50.     let mut number: VecDeque<char> = VecDeque::new();
  51.  
  52.     // insert current
  53.     if let Some(&Component::Value(val)) = grid.get(&(r, c)) {
  54.         number.push_back(val);
  55.         visited.insert((r, c));
  56.     }
  57.     // collect leftward
  58.     for i in (0..c).rev() {
  59.         if let Some(&Component::Value(val)) = grid.get(&(r, i)) {
  60.             number.push_front(val);
  61.             visited.insert((r, i));
  62.         } else {
  63.             break;
  64.         }
  65.     }
  66.     // collect rightward
  67.     for i in c + 1.. {
  68.         if let Some(&Component::Value(val)) = grid.get(&(r, i)) {
  69.             number.push_back(val);
  70.             visited.insert((r, i));
  71.         } else {
  72.             break;
  73.         }
  74.     }
  75.  
  76.     number
  77.         .into_iter()
  78.         .collect::<String>()
  79.         .parse::<u32>()
  80.         .unwrap()
  81. }
  82.  
  83. #[derive(Debug)]
  84. pub enum Component {
  85.     Value(char),
  86.     Symbol,
  87.     None,
  88. }
  89.  
  90. impl From<char> for Component {
  91.     fn from(value: char) -> Self {
  92.         if value.is_ascii_digit() {
  93.             return Self::Value(value);
  94.         }
  95.  
  96.         match value {
  97.             '.' => Self::None,
  98.             _ => Self::Symbol,
  99.         }
  100.     }
  101. }
  102.  
  103. pub fn get_grid(input: &str) -> BTreeMap<(i32, i32), Component> {
  104.     input
  105.         .lines()
  106.         .enumerate()
  107.         .flat_map(|(r, line)| {
  108.             line.chars()
  109.                 .enumerate()
  110.                 .map(move |(c, char)| ((r as i32, c as i32), char.into()))
  111.         })
  112.         .collect()
  113. }
  114.  
  115. #[cfg(test)]
  116. mod tests {
  117.     use super::*;
  118.  
  119.     #[test]
  120.     fn test_get() {
  121.         let schematic = "467..114..
  122. ...*......
  123. ..35..633.
  124. ......#...
  125. 617*......
  126. .....+.58.
  127. ..592.....
  128. ......755.
  129. ...$.*....
  130. .664.598..";
  131.         let grid = get_grid(schematic);
  132.         let res = count_part_numbers(grid);
  133.         assert_eq!(res, 4361);
  134.     }
  135. }
  136.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement