nairby

Day 20 Code

Dec 20th, 2021
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.94 KB | None | 0 0
  1. use std::env;
  2. use std::io::{self};
  3. use std::collections::HashMap;
  4.  
  5. type Point = (isize,isize);
  6.  
  7. fn pixel_from(ch: char) -> bool {
  8.     match ch {
  9.         '#' => true,
  10.         '.' => false,
  11.         _ => unreachable!(),
  12.     }
  13. }
  14.  
  15. fn enhancement_index(pt: &Point, map: &HashMap<Point,bool>, canvas: bool) -> usize {
  16.     let square_indices = vec![
  17.         (pt.0-1,pt.1-1),
  18.         (pt.0+0,pt.1-1),
  19.         (pt.0+1,pt.1-1),
  20.         (pt.0-1,pt.1+0),
  21.         (pt.0+0,pt.1+0),
  22.         (pt.0+1,pt.1+0),
  23.         (pt.0-1,pt.1+1),
  24.         (pt.0+0,pt.1+1),
  25.         (pt.0+1,pt.1+1),
  26.         ];
  27.     let mut index = String::new();
  28.     for square in square_indices {
  29.         match map.get(&square) {
  30.             Some(true) => index.push_str("1"),
  31.             Some(false) => index.push_str("0"),
  32.             _ => {
  33.                 match canvas {
  34.                     true => index.push_str("0"),
  35.                     false => index.push_str("1"),
  36.                 }
  37.             }
  38.         }
  39.     }
  40.     usize::from_str_radix(&index,2).unwrap()
  41. }
  42.  
  43. fn map_extents(map: &HashMap<Point,bool>) -> (isize,isize,isize,isize) {
  44.     let xmin = &map.keys().map(|&pt| pt.0).min().unwrap();
  45.     let ymin = &map.keys().map(|&pt| pt.1).min().unwrap();
  46.     let xmax = &map.keys().map(|&pt| pt.0).max().unwrap();
  47.     let ymax = &map.keys().map(|&pt| pt.1).max().unwrap();
  48.     (*xmin,*ymin,*xmax,*ymax)
  49. }
  50.  
  51. fn solve(input: &str) -> io::Result<()> {
  52.     // Input
  53.     let input_str = std::fs::read_to_string(input).unwrap();
  54.     let input_str = input_str.trim();
  55.     let input: Vec<_> = input_str.split("\n\n").collect();
  56.  
  57.     // Build algorithm
  58.     let algorithm: HashMap<usize,bool> =
  59.         input[0]
  60.         .chars()
  61.         .enumerate()
  62.         .map(|(i,ch)| (i,pixel_from(ch)))
  63.         .collect();
  64.    
  65.     // Build initial image
  66.     let mut image: HashMap<Point,bool> = HashMap::new();
  67.     for (y,line) in input[1].split("\n").enumerate() {
  68.         for (x,ch) in line.chars().enumerate() {
  69.             let (x,y) = (x.try_into().unwrap(),y.try_into().unwrap());
  70.             image.insert((x,y),pixel_from(ch));
  71.         }
  72.     }
  73.  
  74.     // Apply algorithm
  75.     let mut part1 = 0;
  76.     for step in 0..50 {
  77.         let image_before = image.clone();
  78.         let (xmin,ymin,xmax,ymax) = map_extents(&image_before);
  79.         let canvas = step % 2 == 0;
  80.  
  81.         for y in (ymin-1)..=(ymax+1) {
  82.             for x in (xmin-1)..=(xmax+1) {
  83.                 let new_px = algorithm[&enhancement_index(&(x,y),&image_before,canvas)];
  84.                 image.insert((x,y),new_px);
  85.             }
  86.         }
  87.  
  88.         if step == 2 { part1 = image.iter().filter(|&(_,v)| *v).count(); }
  89.     }
  90.  
  91.     println!("Part 1: {}", part1); // 5395
  92.    
  93.     let part2 = image.iter().filter(|&(_,v)| *v).count();
  94.     println!("Part 2: {}", part2); // 17584
  95.  
  96.     Ok(())
  97. }
  98.  
  99. fn main() {
  100.     let args: Vec<String> = env::args().collect();
  101.     let filename = &args[1];
  102.     solve(&filename).unwrap();
  103. }
Advertisement
Add Comment
Please, Sign In to add comment