diff options
Diffstat (limited to '2019/rust/day08')
-rw-r--r-- | 2019/rust/day08/Cargo.toml | 7 | ||||
-rw-r--r-- | 2019/rust/day08/src/main.rs | 98 |
2 files changed, 105 insertions, 0 deletions
diff --git a/2019/rust/day08/Cargo.toml b/2019/rust/day08/Cargo.toml new file mode 100644 index 0000000..52476c3 --- /dev/null +++ b/2019/rust/day08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "day08" +version = "0.1.0" +authors = ["cos <cos>"] +edition = "2018" + +[dependencies] diff --git a/2019/rust/day08/src/main.rs b/2019/rust/day08/src/main.rs new file mode 100644 index 0000000..232d2c8 --- /dev/null +++ b/2019/rust/day08/src/main.rs @@ -0,0 +1,98 @@ +use std::io::{self, BufRead}; + +fn read_input() -> Vec<u32> { + let stdin = io::stdin(); + let line = stdin.lock().lines().next(); + line.unwrap().unwrap().trim_start().trim_end().chars() + .map(|c| { let d: u32 = c.to_digit(10).unwrap(); d }).collect() +} + +fn split_layers(mut image: Vec<u32>, width: usize, height: usize) -> Vec<Vec<u32>> { + let mut layers:Vec<Vec<u32>> = Vec::new(); + + for i in (0..image.len()).step_by(width*height) { + let mut layer = Vec::new(); + layer.append(&mut image[i..i+width*height].to_vec()); + layers.push(layer); + } + + layers +} + +fn combine_layers(layers: &Vec<Vec<u32>>, width: usize, height: usize) -> Vec<u32> { + let combined:Vec<Vec<u32>> = (0..height).map(|y| { + (0..width).map(|x| { + layers.iter().fold(2, |i, l| { if i == 2 { l[y*width+x] } else { i } }) + }).collect() + }).collect(); + + combined.into_iter().flatten().collect() +} + +fn print_image(image: &Vec<u32>, width: usize, height: usize) { + for y in 0..height { + for x in 0..width { + if image[y*width + x] == 1 { + print!("██"); + } else { + print!(" "); + } + } + println!(""); + } +} + +fn first_puzzle(layers: &Vec<Vec<u32>>) { + let number_counts: Vec<(usize, usize, usize)> = layers.iter() + .map(|l| l.iter() + .fold((0,0,0), |(mut zeros, mut ones, mut twos), n| { + if *n == 0 { zeros += 1; } + if *n == 1 { ones += 1; } + if *n == 2 { twos += 1; } + ( zeros, ones, twos ) + } + )).collect(); + + let interesting_layer: Option<usize> = number_counts.iter().enumerate(). + fold((None, None), |(mut best_layer, mut lowest_zero), (l, n)| { + match (best_layer, lowest_zero) { + (None, None) => { + best_layer = Some(l); + lowest_zero = Some(n.0); + }, + (_, Some(old_lowest)) => { + if n.0 < old_lowest { + best_layer = Some(l); + lowest_zero = Some(n.0); + } + }, + _ => panic!("Invalid internal logic!"), + } + (best_layer, lowest_zero) + }).0; + + match interesting_layer { + Some(i_l) => println!("Solution to first puzzle: {}.", + number_counts[i_l].1 * number_counts[i_l].2), + None => println!("No solution found for first puzzle."), + } +} + +fn second_puzzle(layers: &Vec<Vec<u32>>, width: usize, height: usize) { + let image = combine_layers(&layers, width, height); + + println!("Solution to second puzzle: "); + print_image(&image, width, height); +} + +fn main() { + let encoded_image = read_input(); + let width = 25; + let height = 6; + assert!(encoded_image.len() % (width * height) == 0, "Image data is corrupt."); + + let layers = split_layers(encoded_image, width, height); + + first_puzzle(&layers); + second_puzzle(&layers, width, height); +} |