Advertisement
krzysz00

Advent of code, day 21

Dec 21st, 2017
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 6.80 KB | None | 0 0
  1. use std::io::{stdin,BufRead};
  2. use std::collections::HashMap;
  3.  
  4. type Win2 = [bool; 4];
  5. type Win3 = [bool; 9];
  6. type Win4 = [bool; 16];
  7.  
  8. #[derive(Clone, Debug, PartialEq, Eq)]
  9. struct State {
  10.     even: HashMap<Win2, Win3>,
  11.     odd: HashMap<Win3, Win4>,
  12.     grid: Vec<bool>,
  13.     len: usize,
  14. }
  15.  
  16.  
  17. impl Default for State {
  18.     fn default() -> Self {
  19.         State {even: HashMap::new(), odd: HashMap::new(),
  20.                grid: vec![false, true, false,
  21.                           false, false, true,
  22.                           true, true, true],
  23.                len: 3}
  24.     }
  25. }
  26.  
  27. fn char_to_grid(c: char) -> Option<bool> {
  28.     match c {
  29.         '.' => Some(false),
  30.         '#' => Some(true),
  31.         _ => None,
  32.     }
  33. }
  34.  
  35. impl State {
  36.     pub fn new() -> Self { Default::default() }
  37.  
  38.     fn add_rule_two(&mut self, line: &str) {
  39.         let p: Vec<bool> = line.chars().filter_map(char_to_grid).collect();
  40.         if p.len() != 13 { panic!("")}
  41.         let mut o: Win3 = [false; 9];
  42.         o.copy_from_slice(&p[4..]);
  43.  
  44.         // coordinates are nonobvious because D_4 doesn't label how I'd like
  45.         let r0: Win2 = [p[0], p[1], p[2], p[3]];
  46.         let r1: Win2 = [p[1], p[3], p[0], p[2]];
  47.         let r2: Win2 = [p[3], p[2], p[1], p[0]];
  48.         let r3: Win2 = [p[2], p[0], p[3], p[1]];
  49.         let r0t: Win2 = [p[2], p[3], p[0], p[1]];
  50.         let r1t: Win2 = [p[3], p[1], p[2], p[0]];
  51.         let r2t: Win2 = [p[1], p[0], p[3], p[2]];
  52.         let r3t: Win2 = [p[0], p[2], p[1], p[3]];
  53.         let patterns = [r0, r1, r2, r3, r0t, r1t, r2t, r3t];
  54.         for &i in patterns.into_iter() {
  55.             self.even.insert(i, o.clone());
  56.         }
  57.     }
  58.  
  59.     fn add_rule_three(&mut self, line: &str) {
  60.         let p: Vec<bool> = line.chars().filter_map(char_to_grid).collect();
  61.         if p.len() != 25 { panic!("Invalid 3-pattern"); }
  62.         let mut o: Win4 = [false; 16];
  63.         o.copy_from_slice(&p[9..]);
  64.  
  65.         // Original is
  66.         // 0 1 2
  67.         // 3 4 5
  68.         // 6 7 8
  69.         // so, from 2-side, 0 => 0, 1 => 2, 2 => 6, 3 => 8
  70.         let r0: Win3 = [p[0], p[1], p[2], p[3] , p[4], p[5], p[6], p[7], p[8]];
  71.         let r1: Win3 = [p[2], p[5], p[8], p[1], p[4], p[7], p[0], p[3], p[6]];
  72.         let r2: Win3 = [p[8], p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]];
  73.         let r3: Win3 = [p[6], p[3], p[0], p[7], p[4], p[1], p[8], p[5], p[2]];
  74.         let r0t: Win3 = [p[6], p[7], p[8], p[3], p[4], p[5], p[0], p[1], p[2]];
  75.         let r1t: Win3 = [p[8], p[5], p[2], p[7], p[4], p[1], p[6], p[3], p[0]];
  76.         let r2t: Win3 = [p[2], p[1], p[0], p[5], p[4], p[3], p[8], p[7], p[6]];
  77.         let r3t: Win3 = [p[0], p[3], p[6], p[1], p[4], p[7], p[2], p[5], p[8]];
  78.  
  79.         let patterns = [r0, r1, r2, r3, r0t, r1t, r2t, r3t];
  80.         for &i in patterns.into_iter() {
  81.             self.odd.insert(i, o.clone());
  82.         }
  83.     }
  84.  
  85.     pub fn add_rule(&mut self, line: &str) {
  86.         let sep_count = line.matches('/').count();
  87.         match sep_count {
  88.             3 => self.add_rule_two(line), // 1 + 2 slashes
  89.             5 => self.add_rule_three(line), // 2 + 3 slashes
  90.             0 => (), // blank line,
  91.             _ => panic!("Unusable number of slashes in input"),
  92.         }
  93.     }
  94.  
  95.     fn update_two(&mut self) {
  96.         let n_windows = self.len / 2;
  97.         let new_len = self.len + n_windows;
  98.         let mut new_grid = vec![false; new_len * new_len];
  99.         for i in 0..n_windows {
  100.             for j in 0..n_windows {
  101.                 let l = i * 2;
  102.                 let t = j * 2;
  103.                 let pattern = [self.grid[l + t * self.len], self.grid[l + 1 + t * self.len],
  104.                                self.grid[l + (t + 1) * self.len], self.grid[l + 1 + (t + 1) * self.len]];
  105.                 match self.even.get(&pattern) {
  106.                     Some(rep) => {
  107.                         let new_l = i * 3;
  108.                         let new_t = j * 3;
  109.                         new_grid[new_l + (new_t * new_len)..(new_l + 3 + (new_t * new_len))].copy_from_slice(&rep[0..3]);
  110.                         new_grid[new_l + ((new_t + 1) * new_len)..(new_l + 3 + ((new_t + 1) * new_len))].copy_from_slice(&rep[3..6]);
  111.                         new_grid[new_l + ((new_t + 2) * new_len)..(new_l + 3 + ((new_t + 2) * new_len))].copy_from_slice(&rep[6..9]);
  112.                     },
  113.                     None => panic!("Could not find replacement rule"),
  114.                 }
  115.             }
  116.         }
  117.  
  118.         self.grid = new_grid;
  119.         self.len = new_len;
  120.     }
  121.  
  122.     fn update_three(&mut self) {
  123.         let n_windows = self.len / 3;
  124.         let new_len = self.len + n_windows;
  125.         let mut new_grid = vec![false; new_len * new_len];
  126.         for i in 0..n_windows {
  127.             for j in 0..n_windows {
  128.                 let l = i * 3;
  129.                 let t = j * 3;
  130.                 let pattern = [self.grid[l + t * self.len], self.grid[l + 1 + t * self.len], self.grid[l + 2 + t * self.len],
  131.                                self.grid[l + (t + 1) * self.len], self.grid[l + 1 + (t + 1) * self.len], self.grid[l + 2 + (t + 1) * self.len],
  132.                                self.grid[l + (t + 2) * self.len], self.grid[l + 1 + (t + 2) * self.len], self.grid[l + 2 + (t + 2) * self.len]];
  133.                 match self.odd.get(&pattern) {
  134.                     Some(rep) => {
  135.                         let new_l = i * 4;
  136.                         let new_t = j * 4;
  137.                         new_grid[new_l + (new_t * new_len)..(new_l + 4 + (new_t * new_len))].copy_from_slice(&rep[0..4]);
  138.                         new_grid[new_l + ((new_t + 1) * new_len)..(new_l + 4 + ((new_t + 1) * new_len))].copy_from_slice(&rep[4..8]);
  139.                         new_grid[new_l + ((new_t + 2) * new_len)..(new_l + 4 + ((new_t + 2) * new_len))].copy_from_slice(&rep[8..12]);
  140.                         new_grid[new_l + ((new_t + 3) * new_len)..(new_l + 4 + ((new_t + 3) * new_len))].copy_from_slice(&rep[12..16]);
  141.                     },
  142.                     None => panic!("Could not find replacement rule"),
  143.                 }
  144.             }
  145.         }
  146.  
  147.         self.grid = new_grid;
  148.         self.len = new_len;
  149.     }
  150.  
  151.     pub fn update(&mut self) {
  152.         if self.len % 2 == 0 {
  153.             self.update_two();
  154.         }
  155.         else if self.len % 3 == 0 {
  156.             self.update_three();
  157.         }
  158.         else {
  159.             panic!("Somehow we can't update");
  160.         }
  161.     }
  162.  
  163.     pub fn n_on(&self) -> usize {
  164.         self.grid.iter().cloned().map(|x| x as usize).sum()
  165.     }
  166. }
  167.  
  168. fn main() {
  169.     let stdin = stdin();
  170.     let handle = stdin.lock();
  171.  
  172.     let mut state = State::new();
  173.     handle.lines().for_each(|l| state.add_rule(&l.expect("I/O error")));
  174.     for i in 0..18 {
  175.         state.update();
  176.         if i == 4 || i == 17 {
  177.             println!("{} pixels on after {} iterations", state.n_on(), i + 1);
  178.         }
  179.     }
  180. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement