Advertisement
qzazwxsx

Untitled

Dec 10th, 2023
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.03 KB | Source Code | 0 0
  1. use crate::{Solution, SolutionPair};
  2. use std::collections::HashMap;
  3. ///////////////////////////////////////////////////////////////////////////////
  4.  
  5. fn find_index(vec_str: Vec<&str>, target_char: char) -> (i64, i64) {
  6.     for (index, &s) in vec_str.iter().enumerate() {
  7.         if let Some(pos) = s.find(target_char) {
  8.             return (pos as i64, index as i64);
  9.         }
  10.     }
  11.     return (-1, -1)
  12. }
  13.  
  14. fn get_nearby_indices(current: (i64, i64), data: Vec<&str>) -> Vec<(i64, i64)> {
  15.     let mut ret_vec: Vec<(i64, i64)> = vec![];
  16.     if current.0 > 0 {
  17.         ret_vec.push((current.0 - 1, current.1));
  18.     }
  19.     if current.1 > 0 {
  20.         ret_vec.push((current.0, current.1 - 1));
  21.     }
  22.     if current.0 < data[0].len() as i64 - 1 {
  23.         ret_vec.push((current.0 + 1, current.1));
  24.     }
  25.     if current.1 < data.len() as i64 - 1 {
  26.         ret_vec.push((current.0, current.1 + 1));
  27.     }
  28.     return ret_vec
  29. }
  30.  
  31. fn get_char_at_index(data: Vec<&str>, idx: (i64, i64)) -> &str {
  32.     let idx_x = idx.0 as usize;
  33.     let idx_y = idx.1 as usize;
  34.     return &data[idx_y][idx_x..idx_x + 1]
  35. }
  36.  
  37. fn char_to_delta_idx(c: &str) -> Vec<(i64 , i64)> {
  38.     return match c {
  39.         "|" => vec![(0,  1),  ( 0, -1)],
  40.         "-" => vec![(1,  0),  (-1,  0)],
  41.         "L" => vec![(0, -1),  ( 1,  0)],
  42.         "J" => vec![(0, -1),  (-1,  0)],
  43.         "7" => vec![(-1, 0),  ( 0,  1)],
  44.         "F" => vec![(1,  0),  ( 0,  1)],
  45.         _ =>   vec![(0,  0)]
  46.     };
  47. }
  48.  
  49. fn get_deltas_connect_start(data: Vec<&str>) -> Vec<(i64, i64)> {
  50.     let start_idx = find_index(data.clone(), 'S');
  51.     let mut ret_vec: Vec<(i64, i64)> = vec![];
  52.     for idx in get_nearby_indices(start_idx, data.clone()) {
  53.         let c = get_char_at_index(data.clone(), idx);
  54.         let deltas = char_to_delta_idx(c);
  55.         for delta in deltas {
  56.             if idx.0 + delta.0 == start_idx.0 && idx.1 + delta.1 == start_idx.1 {
  57.                 ret_vec.push(delta);
  58.                 break;
  59.             }
  60.         }
  61.     }
  62.     return ret_vec
  63. }
  64.  
  65. fn get_pipes_connect_start(data: Vec<&str>) -> Vec<(i64, i64)> {
  66.     let start_idx = find_index(data.clone(), 'S');
  67.     return get_deltas_connect_start(data)
  68.         .iter()
  69.         .map(|i| (start_idx.0 + i.0, start_idx.1 + i.1))
  70.         .collect();
  71. }
  72.  
  73. fn get_next(current: (i64, i64), previous: (i64, i64), data: Vec<&str>) -> (i64, i64) {
  74.     let deltas = char_to_delta_idx(get_char_at_index(data, current));
  75.     for delta in deltas {
  76.         if !(current.0 + delta.0 == previous.0 && current.1 + delta.1 == previous.1) {
  77.             return (current.0 + delta.0, current.1 + delta.1)
  78.         }
  79.     }
  80.     return previous; // TODO: invent better error state?
  81. }
  82.  
  83.  
  84. pub fn solve(input: std::str::Lines<'_>) -> SolutionPair {
  85.  
  86.    let lines: Vec<&str> = input.collect();
  87.  
  88.    let start = find_index(lines.clone(), 'S');
  89.    let edge_start = vec![
  90.            vec![(0,   1),  ( 0, -1)],
  91.            vec![(0,  -1),  ( 1,  0)],
  92.            vec![(0,  -1),  (-1,  0)]
  93.        ].contains(&get_deltas_connect_start(lines.clone()));
  94.  
  95.    let mut prev = start;
  96.    let mut curr = get_pipes_connect_start(lines.clone())[0];
  97.    let mut count = 0;
  98.    let mut all_tiles: HashMap<(i64, i64), bool> = HashMap::from([(curr, true)]);
  99.    while curr != start {
  100.        let cpy = get_next(curr, prev, lines.clone());
  101.        prev = curr;
  102.        curr = cpy;
  103.        count += 1;
  104.        all_tiles.insert(curr, true);
  105.    }
  106.  
  107.    let mut innercount: u64 = 0;
  108.    for (y, line) in lines.iter().enumerate() {
  109.        let cy = y as i64;
  110.        let mut is_odd_pipe_char_count = false;
  111.        for (x, c) in line.chars().enumerate() {
  112.            let cx = x as i64;
  113.            let contains = all_tiles.contains_key(&(cx, cy));
  114.            if ("|JL".contains(c) || (c == 'S' && edge_start)) && contains {
  115.                is_odd_pipe_char_count = !is_odd_pipe_char_count;
  116.            }
  117.            innercount += (is_odd_pipe_char_count && !contains) as u64;
  118.        }
  119.    }
  120.  
  121.    (Solution::from((count + 1) >> 1), Solution::from(innercount))
  122. }
  123.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement