Day 08 part 2
authorGrégory Burri <gregory.burri@matisa.ch>
Tue, 10 Dec 2019 07:13:27 +0000 (08:13 +0100)
committerGrégory Burri <gregory.burri@matisa.ch>
Tue, 10 Dec 2019 07:13:27 +0000 (08:13 +0100)
.gitignore
src/day08.rs
src/main.rs

index 088ba6b..94bb2fb 100644 (file)
@@ -8,3 +8,4 @@ Cargo.lock
 
 # These are backup files generated by rustfmt
 **/*.rs.bk
+data/day08.png
index 074a632..0f1bb38 100644 (file)
@@ -13,29 +13,47 @@ pub fn decode_image(digits: &[u8], width: usize, height: usize) -> Vec<Vec<u8>>
     layers
 }
 
+fn count(layer: &[u8], value: u8) -> u32 {
+    layer.iter().fold(0, |sum, pix| if *pix == value { sum + 1 } else { sum })
+}
+
 pub fn layer_with_fewer_0(layers: &[Vec<u8>]) -> &Vec<u8> {
     let mut min = std::u32::MAX;
-    let mut layer_min = 0;
-    for i in 0 .. layers.len() {
-        let sum = layers[i].iter().fold(0, |sum, pix| if *pix == 0u8 { sum + 1 } else { sum });
+    let mut layer_min: &Vec<u8> = &layers[0];
+    for layer in layers {
+        let sum = count(&layer, 0u8);
         if sum < min {
             min = sum;
-            layer_min = i;
+            layer_min = layer;
         }
     }
-    &layers[layer_min]
+    layer_min
 }
 
-pub fn one_digits_times_two_digits(layer: &[u8]) -> i32 {
-    let (nb_1, nb_2) =
-        layer
-            .iter()
-            .fold(
-                (0, 0),
-                |(nb_1, nb_2), pix|
-                    match *pix { 1u8 => (nb_1 + 1, nb_2), 2u8 => (nb_1, nb_2 + 1), _ => (nb_1, nb_2)}
-            );
-    nb_1 * nb_2
+pub fn merge_layers(layers: &[Vec<u8>]) -> Vec<u8> {
+    let size = layers[0].len();
+    let mut result: Vec<u8> = Vec::new();
+    result.resize(size, 0);
+
+    for i in 0 .. size {
+        for layer in layers {
+            if layer[i] != 2 {
+                result[i] = layer[i];
+                break;
+            }
+        }
+    }
+
+    result
+}
+
+pub fn write_layer<P : AsRef<std::path::Path>>(layer: &[u8], width: u32, height: u32, to: P) {
+    let layer_normalized: Vec<u8> = layer.iter().map(|v| v * 255).collect();
+    let _ = image::save_buffer(to, &layer_normalized, width, height, image::Gray(8));
+}
+
+pub fn one_digits_times_two_digits(layer: &[u8]) -> u32 {
+    count(layer, 1) * count(layer, 2)
 }
 
 #[cfg(test)]
@@ -49,4 +67,12 @@ mod tests {
         let layer = layer_with_fewer_0(&layers[..]);
         assert_eq!(one_digits_times_two_digits(layer), 1);
     }
+
+    #[test]
+    fn part2() {
+        let raw = read_from_string("0222112222120000");
+        let layers = decode_image(&raw, 2, 2);
+        let layer = merge_layers(&layers[..]);
+        assert_eq!(layer, vec![0, 1, 1, 0]);
+    }
 }
\ No newline at end of file
index 470327b..c388bbd 100644 (file)
@@ -57,8 +57,14 @@ fn day08() -> String {
 
     let raw = day08::read_from_string(&img);
     let layers = day08::decode_image(&raw, 25, 6);
+
     let layer = day08::layer_with_fewer_0(&layers[..]);
-    format!("part1: {}, part2: {}", day08::one_digits_times_two_digits(layer), 1)
+    let result = day08::merge_layers(&layers[..]);
+
+    let img_output = "data/day08.png";
+    day08::write_layer(&result, 25, 6, img_output);
+
+    format!("part1: {}, part2: {}", day08::one_digits_times_two_digits(layer), img_output)
 }
 
 fn day09() -> String {