1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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);
}
|