Add day08

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2019-12-09 18:37:42 -05:00
parent 55d00bbaa3
commit 27606541a9
4 changed files with 143 additions and 0 deletions

126
day08/src/main.rs Normal file
View File

@@ -0,0 +1,126 @@
use std::{
fmt::{self, Display, Formatter},
io::{self, Read},
};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
fn get_input_string() -> io::Result<String> {
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer)?;
Ok(buffer)
}
#[allow(unused_macros)]
macro_rules! todo {
($($tt:tt)*) => { unimplemented!($($tt)*) };
}
fn main() -> Result<()> {
let input_string = get_input_string()?;
let image = Image::from_str(25, 6, input_string.trim());
println!("Image has {} layers", image.layers.len());
part1(&image);
part2(&image);
Ok(())
}
fn part1(image: &Image) {
let layer = image.layers
.iter()
.min_by_key(|layer| layer.data.iter().copied().filter(|n| *n == 0).count())
.unwrap();
let ones = layer.data.iter().copied().filter(|n| *n == 1).count();
let twos = layer.data.iter().copied().filter(|n| *n == 2).count();
println!("Part 1: {} * {} = {}", ones, twos, ones * twos);
}
fn part2(image: &Image) {
println!("Part 2:");
println!("{}", image);
}
#[derive(Debug, Clone)]
struct Image {
width: usize,
height: usize,
layers: Vec<Layer>,
}
impl Display for Image {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
const ANSI_PIXEL: [&'static str; 3] = [
"\u{001b}[40m \u{001b}[0m", // black
"\u{001b}[47m \u{001b}[0m", // white
"\u{001b}[45;1m \u{001b}[0m", // transparent
];
let layer_pixels: Vec<&'static str> = self.layers.iter()
.rev()
.fold(self.layers.last().unwrap().clone(), |acc, this| this.flatten_over(&acc))
.data
.into_iter()
.map(|n| ANSI_PIXEL[n])
.collect();
for px in layer_pixels.as_slice().chunks(self.width) {
writeln!(fmt, "{}", px.join(""))?;
}
Ok(())
}
}
impl Image {
pub fn from_str(width: usize, height: usize, text: &str) -> Self {
let count = width * height;
let mut idx = 0;
let mut layers = Vec::new();
while idx < text.len() {
let layer = Layer::from_str(width, height, &text[idx..]);
layers.push(layer);
idx += count;
}
Image { width, height, layers }
}
}
#[derive(Debug, Clone)]
struct Layer {
width: usize,
height: usize,
data: Vec<usize>,
}
impl Layer {
pub fn from_str(width: usize, height: usize, text: &str) -> Self {
let count = width * height;
let text = &text[0 .. count];
let data: Vec<_> = text.chars()
.map(|s| (s as usize) - ('0' as usize))
.collect();
Layer {
width,
height,
data,
}
}
pub fn flatten_over(&self, other: &Layer) -> Layer {
assert_eq!(self.width, other.width, "mismatched width");
assert_eq!(self.height, other.height, "mismatched height");
let data = self.data.iter().copied().zip(other.data.iter().copied())
.map(|(a, b)| match (a, b) {
(2, p)
| (p, _) => p
}).collect();
Layer {
width: self.width,
height: self.height,
data,
}
}
}