Advertisement
Guest User

Untitled

a guest
Dec 17th, 2020
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.14 KB | None | 0 0
  1. use std::env;
  2. use std::io::{self, prelude::*, BufReader};
  3. use std::fs::File;
  4. use std::collections::HashMap;
  5.  
  6. const BOOT_CYCLES: i64 = 6;
  7.  
  8. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
  9. enum Square {
  10.     Active,
  11.     Inactive,
  12. }
  13.  
  14. fn neighbors(pt: (i64,i64,i64,i64)) -> Vec<(i64,i64,i64,i64)> {
  15.     let mut neighbors: Vec<(i64,i64,i64,i64)> = Vec::new();
  16.     for x in -1..=1 {
  17.         for y in -1..=1 {
  18.             for z in -1..=1 {
  19.                 for w in -1..=1 {
  20.                     let nxyzw = (pt.0+x, pt.1+y, pt.2+z, pt.3+w);
  21.                     if nxyzw != pt { neighbors.push(nxyzw); }
  22.                 }
  23.             }
  24.         }
  25.     }
  26.     neighbors
  27. }
  28.  
  29. fn count_neighbors(map: &HashMap<(i64,i64,i64,i64),Square>, pt: (i64,i64,i64,i64)) -> i64 {
  30.     neighbors(pt)
  31.         .iter()
  32.         .map(|n| match map.get(&n) {
  33.             Some(Square::Active) => 1,
  34.             _ => 0,
  35.         })
  36.         .sum()
  37. }
  38.  
  39. fn expand_map(map: &mut HashMap<(i64,i64,i64,i64),Square>) {
  40.     let temp = map.clone();
  41.     for (pt,_) in temp.iter() {
  42.         for neighbor in neighbors(*pt) {
  43.             match map.get(&neighbor) {
  44.                 Some(_) => {},
  45.                 None => { map.insert(neighbor, Square::Inactive); }
  46.             }
  47.         }
  48.     }
  49. }
  50.  
  51. fn part2(input: &str) -> io::Result<()> {
  52.     let file = File::open(input).expect("Input file not found.");
  53.     let reader = BufReader::new(file);
  54.  
  55.     let input: Vec<String> = match reader.lines().collect() {
  56.         Err(err) => panic!("Unknown error reading input: {}", err),
  57.         Ok(result) => result,
  58.     };
  59.  
  60.     // Build map
  61.     let mut map: HashMap<(i64,i64,i64,i64),Square> = HashMap::new();
  62.  
  63.     for (y,line) in input.iter().enumerate() {
  64.         for (x,ch) in line.chars().enumerate() {
  65.             let pt = (x as i64, y as i64, 0 as i64, 0 as i64);
  66.             match ch {
  67.                 '#' => { map.insert(pt,Square::Active); },
  68.                 '.' => { map.insert(pt,Square::Inactive); },
  69.                 other => panic!("Unknown square: {}", other),
  70.             }
  71.         }
  72.     }
  73.  
  74.     let mut cycle = 0;
  75.     'main_lp: loop {
  76.  
  77.        // Expand map to track neighbors
  78.        expand_map(&mut map);
  79.  
  80.        cycle += 1;
  81.        let current = map.clone();
  82.        
  83.        for (pt,sq) in current.iter() {
  84.  
  85.            let active_neighbors = count_neighbors(&current,*pt);
  86.            match sq {
  87.                Square::Active => {
  88.                    if !(2..=3).contains(&active_neighbors) {
  89.                        map.insert(*pt,Square::Inactive);
  90.                    }
  91.                },
  92.                Square::Inactive => {
  93.                    if active_neighbors == 3 {
  94.                        map.insert(*pt,Square::Active);
  95.                    }
  96.                }
  97.            }
  98.        }
  99.  
  100.        if cycle == BOOT_CYCLES { break 'main_lp; }
  101.     }
  102.  
  103.     let part2 = map
  104.         .iter()
  105.         .filter(|(_,v)| v == &&Square::Active)
  106.         .count();
  107.  
  108.     println!("Part 2: {}", part2); // 2084
  109.  
  110.     Ok(())
  111. }
  112.  
  113. fn main() {
  114.     let args: Vec<String> = env::args().collect();
  115.     let filename = &args[1];
  116.     part2(&filename).unwrap();
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement