diff options
Diffstat (limited to '11/src/part-2.rs')
-rw-r--r-- | 11/src/part-2.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/11/src/part-2.rs b/11/src/part-2.rs new file mode 100644 index 0000000..3bdb50e --- /dev/null +++ b/11/src/part-2.rs @@ -0,0 +1,62 @@ +mod tensor; + +use std::io::{BufRead}; + +pub type Matrix<T> = tensor::Tensor<T, 2>; +pub type Index = tensor::Index<2>; + + +pub fn main() { + let stdin = std::io::stdin(); + let handle = stdin.lock(); + + let mut energy: Matrix<usize> = { + let mut tmp: Vec<usize> = Vec::new(); + let mut m: usize = 0; + for l in handle.lines() { + let line = l.unwrap(); + tmp.extend(line.chars().map(|c| c.to_digit(10).unwrap() as usize)); + m += 1; + } + let n = tmp.len()/m; + Matrix::new_from([m, n], tmp) + }; + let m = energy.shape()[0]; + let n = energy.shape()[1]; + + let mut can_flash: Matrix<bool> = Matrix::new(energy.shape().clone(), true); + let mut to_increase: Vec<Index> = Vec::new(); + for s in 0.. { + can_flash.fill(true); + to_increase.clear(); + for i in 0..m { + for j in 0..n { + to_increase.push([i, j]); + } + } + + while let Some(idx) = to_increase.pop() { + if can_flash[idx] { + energy[idx] += 1; + if energy[idx] > 9 { + let neighbors: [Index; 8] = [[idx[0] , idx[1].wrapping_sub(1)], [idx[0] , idx[1]+1], + [idx[0].wrapping_sub(1) , idx[1] ], [idx[0]+1, idx[1] ], + [idx[0].wrapping_sub(1) , idx[1].wrapping_sub(1)], [idx[0]+1, idx[1]+1], + [idx[0].wrapping_sub(1) , idx[1]+1 ], [idx[0]+1, idx[1].wrapping_sub(1)] ]; + energy[idx] = 0; + can_flash[idx] = false; + for neighbor in (& neighbors).into_iter().filter(|neighbor| energy.in_bounds(neighbor)) { + to_increase.push(*neighbor); + } + } + } + } + + let e = energy[[0,0]]; + if energy.data().into_iter().all(|& x| x == e) { + println!("Synchronized after step {} (so answer is step {})", s, s+1); + break; + } + } + +} |