Advertisement
JohanLiebert_

AOC 15

Dec 17th, 2022 (edited)
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.84 KB | None | 0 0
  1. use std::collections::{HashMap, HashSet};
  2.  
  3. use crate::helper::read_input;
  4. use regex::Regex;
  5.  
  6. fn parse_input(test: bool) -> (HashMap<(i64, i64), (i64, i64)>, HashSet<(i64, i64)>, i64, i64) {
  7.     let mut map = HashMap::new();
  8.  
  9.     let file = read_input(15, test);
  10.     let (mut min_left, mut max_right) = (i64::MAX, 0);
  11.  
  12.     let mut unique_beacons = HashSet::new();
  13.  
  14.     let pattern =
  15.         Regex::new(r#".*x=([-]*[\d]+).*y=([-]*[\d]+).*x=([-]*[\d]+).*y=([-]*[\d]+)"#).unwrap();
  16.  
  17.     for line in file.split("\n") {
  18.         for capture in pattern.captures_iter(line) {
  19.             let sensor_x = capture.get(1).unwrap();
  20.             let sensor_y = capture.get(2).unwrap();
  21.             let beacon_x = capture.get(3).unwrap();
  22.             let beacon_y = capture.get(4).unwrap();
  23.  
  24.             let sensor_x = &line[sensor_x.start()..sensor_x.end()];
  25.             let sensor_y = &line[sensor_y.start()..sensor_y.end()];
  26.             let beacon_x = &line[beacon_x.start()..beacon_x.end()];
  27.             let beacon_y = &line[beacon_y.start()..beacon_y.end()];
  28.  
  29.             let sensor_x = sensor_x.parse::<i64>().unwrap();
  30.             let sensor_y = sensor_y.parse::<i64>().unwrap();
  31.             let beacon_x = beacon_x.parse::<i64>().unwrap();
  32.             let beacon_y = beacon_y.parse::<i64>().unwrap();
  33.  
  34.             min_left = if sensor_x.min(beacon_x) < min_left {
  35.                 sensor_x.min(beacon_x)
  36.             } else {
  37.                 min_left
  38.             };
  39.             max_right = if sensor_x.max(beacon_x) > max_right {
  40.                 sensor_x.max(beacon_x)
  41.             } else {
  42.                 max_right
  43.             };
  44.  
  45.             unique_beacons.insert((beacon_x, beacon_y));
  46.             map.insert((sensor_x, sensor_y), (beacon_x, beacon_y));
  47.         }
  48.     }
  49.  
  50.     (map, unique_beacons, min_left, max_right)
  51. }
  52.  
  53. fn get_neighbors(x: i64, y: i64, row_to_check: i64) -> Vec<(i64, i64)> {
  54.     let mut neighbors = vec![];
  55.  
  56.     let row_adders: [i32; 3] = [1, 0, -1];
  57.     let col_adders: Vec<Vec<i32>> = vec![vec![-1, 0, 1], vec![-1, 1], vec![-1, 0, -1]];
  58.  
  59.     for i in 0..row_adders.len() {
  60.         let ra = row_adders[i];
  61.  
  62.         for ca in &col_adders[i] {
  63.             let neighbor_y = y + ra as i64;
  64.             let neighbor_x = x + *ca as i64;
  65.  
  66.             if y < row_to_check {
  67.                 if neighbor_y >= y {
  68.                     neighbors.push((neighbor_x, neighbor_y));
  69.                 }
  70.             } else {
  71.                 if neighbor_y <= y {
  72.                     neighbors.push((neighbor_x, neighbor_y));
  73.                 }
  74.             }
  75.         }
  76.     }
  77.  
  78.     neighbors
  79. }
  80.  
  81. fn dist(pt1: &(i64, i64), pt2: &(i64, i64)) -> f64 {
  82.     let (sx, sy) = pt1;
  83.     let (bx, by) = pt2;
  84.  
  85.     (((sx - bx).pow(2) + (sy - by).pow(2)) as f64).sqrt()
  86. }
  87.  
  88. pub fn part1(test: bool) {
  89.     let (sensor_beacon_map, unique_beacons, min_left, max_right) = parse_input(test);
  90.  
  91.     let row_to_check = if test { 10 } else { 2_000_000 };
  92.  
  93.     let mut visited = HashSet::new();
  94.     let mut total = 0;
  95.  
  96.     for (sensor, beacon) in &sensor_beacon_map {
  97.         let closest_distance = dist(sensor, beacon);
  98.  
  99.         let min_sensor_dist_to_row = dist(sensor, &(sensor.0, row_to_check));
  100.  
  101.         if min_sensor_dist_to_row > closest_distance {
  102.             continue;
  103.         }
  104.  
  105.         for x in min_left..max_right + 1 {
  106.             let point = (x, row_to_check);
  107.  
  108.             // measure the distance of every beacon from every point on this line
  109.             let point_dist_from_sensor = dist(sensor, &point);
  110.  
  111.             if point_dist_from_sensor <= closest_distance && visited.get(&point).is_none() {
  112.                 visited.insert(point);
  113.                 total += 1;
  114.             }
  115.         }
  116.     }
  117.  
  118.     for (_, by) in unique_beacons {
  119.         if by == row_to_check {
  120.             total -= 1;
  121.         }
  122.     }
  123.  
  124.     println!("{}", total);
  125. }
  126.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement