Advertisement
nairby

AOC 2023 Day 11

Dec 11th, 2023
1,355
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.71 KB | None | 0 0
  1. use std::env;
  2. use std::io::{self, prelude::*, BufReader};
  3. use std::fs::File;
  4.  
  5. use point2d::point2d::Point2D;
  6.  
  7. extern crate itertools;
  8. use itertools::Itertools;
  9.  
  10. // Expand map, where times parameter is the column multiplier
  11. // eg. expanding the map doubles (times=2) the width of empty space
  12. fn expand_map(map: &Vec<Point2D>, times: i64) -> Vec<Point2D> {
  13.     let xmax = map.iter().map(|pt| pt.x).max().unwrap();
  14.     let ymax = map.iter().map(|pt| pt.y).max().unwrap();
  15.  
  16.     // Determine which rows and columns to expand
  17.     let expanded_rows: Vec<_> =
  18.         (0..=ymax)
  19.         .into_iter()
  20.         .filter(|y| {
  21.             (0..=xmax).into_iter().all(|x| !map.contains(&Point2D { x: x, y: *y}))
  22.         })
  23.         .collect();
  24.     let expanded_cols: Vec<_> =
  25.         (0..=xmax)
  26.         .into_iter()
  27.         .filter(|x| {
  28.             (0..=ymax).into_iter().all(|y| !map.contains(&Point2D { x: *x, y: y}))
  29.         })
  30.         .collect();
  31.  
  32.     // Generate expanded map
  33.     let mut new_map = map.clone();
  34.     for y in (0..=ymax).rev() {
  35.         if expanded_rows.contains(&y) {
  36.             for g in &mut new_map {
  37.                 if g.y > y { g.y += times-1 }
  38.             }
  39.         }
  40.     }
  41.     for x in (0..=xmax).rev() {
  42.         if expanded_cols.contains(&x) {
  43.             for g in &mut new_map {
  44.                 if g.x > x { g.x += times-1 }
  45.             }
  46.         }
  47.     }
  48.     new_map
  49. }
  50.  
  51. fn distance(one: &Point2D, other: &Point2D) -> i64 {
  52.     (one.x - other.x).abs() + (one.y - other.y).abs()
  53. }
  54.  
  55. fn distance_sum(galaxies: &Vec<Point2D>) -> i64 {
  56.     galaxies
  57.         .iter()
  58.         .combinations(2)
  59.         .map(|g| distance(g[0],g[1]))
  60.         .sum::<i64>()
  61. }
  62.  
  63. fn solve(input: &str) -> io::Result<()> {
  64.     let file = File::open(input).expect("Input file not found.");
  65.     let reader = BufReader::new(file);
  66.  
  67.     // Input
  68.     let input: Vec<String> = match reader.lines().collect() {
  69.         Err(err) => panic!("Unknown error reading input: {err}"),
  70.         Ok(result) => result,
  71.     };
  72.  
  73.     // Build map
  74.     let mut galaxies: Vec<Point2D> = Vec::new();
  75.     for (y,line) in input.iter().enumerate() {
  76.         for (x,ch) in line.chars().enumerate() {
  77.             let pt = Point2D { x: x as i64, y: y as i64 };
  78.             if ch == '#' {
  79.                 galaxies.push(pt);
  80.             }
  81.         }
  82.     }
  83.  
  84.     // Part 1 + Part 2
  85.     let part1 = distance_sum(&expand_map(&galaxies,2));
  86.     let part2 = distance_sum(&expand_map(&galaxies,1_000_000));
  87.     println!("Part 1: {part1}"); // 9509330
  88.     println!("Part 2: {part2}"); //635832237682
  89.  
  90.     Ok(())
  91. }
  92.  
  93. fn main() {
  94.     let args: Vec<String> = env::args().collect();
  95.     let filename = &args[1];
  96.     solve(&filename).unwrap();
  97. }
  98.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement