struct Image { width: usize, height: usize, layers: Vec>, } impl Image { fn from_str(width: usize, height: usize, data: &str) -> Image { assert_eq!(data.len() % (width * height), 0); let mut image = Image { width: width, height: height, layers: Vec::new(), }; let mut layer: usize = 0; image.layers.push(Vec::new()); let mut index: usize = 0; for c in data.chars() { if index >= (width*height) { layer += 1; image.layers.push(Vec::new()); index = 0; } image.layers[layer].push(c.to_digit(10).expect("Could not convert character to digit")); index += 1; } return image; } fn layer_n_digits(&self, layer_index: usize, value: u32) -> usize { let mut count: usize = 0; for v in self.layers[layer_index].iter() { if *v == value { count += 1; } } return count; } fn layer_merge(&self) -> Vec { let mut result: Vec = Vec::new(); result.resize(self.width * self.height, 2); for pixel_index in 0..(self.width*self.height) { for layer_index in 0..self.layers.len() { // 2 is transparent let value = self.layers[layer_index][pixel_index]; if value != 2 { result[pixel_index] = value; break; } } } return result; } } fn main() { let data = std::fs::read_to_string("input") .expect("Failed to read 'input'"); let image = Image::from_str(25, 6, &data); println!("Image contains {} layers", image.layers.len()); let mut layer_fewest_zeroes: usize = 0; let mut least_zeroes: usize = 200; for index in 0..image.layers.len() { let n_zeroes = image.layer_n_digits(index, 0); if n_zeroes < least_zeroes { layer_fewest_zeroes = index; least_zeroes = n_zeroes; } } println!("Layer {} has {} zeroes", layer_fewest_zeroes, least_zeroes); println!("[Part 1] {}", image.layer_n_digits(layer_fewest_zeroes, 1) * image.layer_n_digits(layer_fewest_zeroes, 2)); let merged = image.layer_merge(); let mut n: u32 = 0; for i in merged.iter() { let c = if *i == 0 { '⬛' } else if *i == 1 { '⬜' } else if *i == 2 { ' ' } else { '?' }; print!("{}", c); n += 1; if n % 25 == 0 { print!("\n"); } } } #[cfg(test)] mod test { use super::*; #[test] fn create_image() { let data = "123456789012"; let image = Image::from_str(3, 2, data); assert_eq!(image.layers.len(), 2); let layer_0 = vec![1, 2, 3, 4, 5, 6]; let layer_1 = vec![7, 8, 9, 0, 1, 2]; assert_eq!(image.layers[0], layer_0); assert_eq!(image.layers[1], layer_1); } #[test] fn layer_merge() { let data = "0222112222120000"; let image = Image::from_str(2, 2, data); let merged = image.layer_merge(); assert_eq!(merged[0], 0); assert_eq!(merged[1], 1); assert_eq!(merged[2], 1); assert_eq!(merged[3], 0); } }