use std::env::args; use std::fs::File; use std::io::BufRead; use std::io::BufReader; fn get_data() -> (Vec, Vec>) { let path = args().nth(1).unwrap(); let file = File::open(path).unwrap(); let mut lines = BufReader::new(file).lines(); let cypher = lines .next() .unwrap() .unwrap() .chars() .map(|c| c == '#') .collect(); assert_eq!(lines.next().unwrap().unwrap(), ""); let img = lines .map(|l| l .unwrap() .chars() .map(|c| c == '#') .collect()) .collect(); return (cypher, img); } fn enhance(img: &Vec>, outside: bool, cypher: &Vec) -> (Vec>, bool) { let rows = img.len(); let cols = img[0].len(); let mut result = vec![vec![false; cols + 2]; rows + 2]; let mut i; for x in 0..cols+2 { i = if outside {0b111111111} else {0}; for y in 0..rows+2 { i &= 0b111111; if y >= rows { i <<= 3; if outside { i |= 0b111; } } else { for dx in [0, 1, 2].iter() { i <<= 1; if x + dx < 2 || x + dx >= cols + 2 { if outside { i |= 1; } } else if img[y][x + dx - 2] { i |= 1; } } } result[y][x] = cypher[i]; } } let outside_i = if outside {0b111111111} else {0}; return (result, cypher[outside_i]); } fn count(img: &Vec>) -> usize { return img .iter() .map(|row| row .iter() .filter(|b| **b) .count()) .sum(); } fn main() { let (cypher, mut img) = get_data(); let mut outside = false; for i in 0..50 { let data = enhance(&img, outside, &cypher); img = data.0; outside = data.1; if i == 1 { println!("{}", count(&img)); } } println!("{}", count(&img)); }