Completed day 8
This commit is contained in:
1 parent
7beabbf7c9
commit
a954425a9e
6 files changed
+156
No files matched your search
Generated
+6
@@ -0,0 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "day8"
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "day8"
|
||||
version = "0.1.0"
|
||||
authors = ["Tyler Hallada <tyler@hallada.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
@@ -0,0 +1 @@
|
||||
2112021212222222222212222122222020222222222221222212202222222222222222222222022222222222221221210222222122222222222122122222222102222022122222220122222002220212222222222202222222222022222222222220222202212222222222222222222222222222222222220220220222222222222222222222122222222212222222022202222022222202020212222222222212222022222122222222222221222222202222222222222222222222222222222222221222200222222122222222222022222222222202222022122212221022222112020202222222222212222222222122222222222220222202212222222222222222222222122222222222221220221222222022222222222122022222222122222022122222222022222202220222222222222212222122222020222222222222222212202222222222222222222222122222222222220221222222222222222222222022022222222202222222022222222122222100021222222222222212222122222220222222222221222212212222222222222222122222022222222222220222202222222022222222222122222222222212222222222202221122222110121212222222222222222222222222212222222221222202222222222222222222122222122222222222220221202222222222222222222122022222222212222122022212221222222121221212222222222222222122221220222222222222222212202222222222222222122222122222202222221220210222222222222222222122022222222212222222022202221022222002120202220222222222222122220122212222222221222212212222222222222222122222022222222222222221211222222122222222222122122222222212222122222222221112222120220212221222222202222022220220222222222221222202212222222222222222022222222222222222221221202222222222222222222022122222222102222122122212220202222012222222220222222222222222221222222222222220222212202222222222222222022222122222222222222222220222222222222222222022222222222212222122022212220022222202020202221222222202222022221122212222222220222202222222222222222222222222122222202222220221200222222122220222222022022222222002222022022212222102222200221222222222222222222122220220212222222222222202212222222222222222022222022222212222222220201222222122201222222022122222222012222022122212221122222200022222220222222202222222221221212222222220222222212222222222222222122222022222012222222221202222222222212222222222022222222122222022222202221012222002120212220222222212222022221222222222222222222212202222222222222222222222122222102222220220221222222222200222222022022222222222222222222222222202222210220222221222222202222222220120202222202221222202212222222222222222122222122222122222222222200222222122220222222122222222222122222122122212220112222220120222221222222202222022222201222222222221222202212222222222222222222222122222212222221220200222222222222222222222222222022202222022122202220222222121022212221222222222222022221120212222222220222222202222222222222222222222222222022222220221200202222122210222222022022222122102222122022202222112222101022202222222222202222222221201222222222220222202202222222222222222222222222222022222222222221202222222201222222222022222022002222022222222222202222000120222221222222202222022222201222222222221222202222222222222222222022222122222202202221221220222222122220222222222222222022012222122122212222212222121222212220222222202222002221120222222222222222200202222222222222222022222022222202212222220202222222022211222222122122222122122222222122212222122222110122212220222222222222202222011212222202220222220212222222222222222122222222222002212221222202212222022201222222222022222222112222222022202220222222120021202222222222202222202221002222222212220222221222222222022222222122222122222212222220221211222222022220222222022022222122002222222022202220102222121022222220022222212222212220110222222222220222221202222222022222222222222122222102212220222210212222122202222222022122222122022222222022202220012222200120202221122222222222212221211222222202221222200202222222122222222122222122222202222221220222212222022200222222222022222222102222022022202220102222110221202222122222212222202222021202222212221222211222222222202222222022222022222102212222222211222222222200222222022122222022012222022122202220122222002120222221222222222222222222122222222222221222201212222222102222222022222122222012202221221211222222222220222222222222222122102222122122202222002222000121222221122222212222022222012202222222222222212212222222012222222122222222222102202222221221212222222210222222222222222122202222022122202222022222020122202222122222202222012220101212222202222222200202222222012222222122222122222202202222221222212222222210222222022022222022022222122222202222112222011120212220122222202222212221011212222202222222211212222222012222222122222022220222202220222211222222222221222222122222222222012222222222222222202222012021222221022222222222012221022202222222221222202222222222202222222222222022222112222221221202212222122211222222122022222022002222222222222220202222222221212222222222222222122220120212022222220222200212222222222222222022222222222002202220222210202222122201222222022222222222212222222122202122202222101222202222222222222222122221102222122202222222200212222222122222222222222122220012212221220200212222122220222222022022222122122222222022222121022222100221212221022221212222102220211212022212221222Line truncated
|
||||
@@ -0,0 +1 @@
|
||||
123456789012
|
||||
@@ -0,0 +1 @@
|
||||
0222112222120000
|
||||
@@ -0,0 +1,138 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::{prelude::*, BufReader};
|
||||
use std::result;
|
||||
|
||||
const INPUT: &str = "input/input.txt";
|
||||
|
||||
type Result<T> = result::Result<T, Box<dyn Error>>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Image {
|
||||
layers: Vec<Layer>,
|
||||
}
|
||||
|
||||
impl Image {
|
||||
fn final_layer(&self) -> Layer {
|
||||
let mut layer_iter = self.layers.iter();
|
||||
let mut final_layer = (*layer_iter.next().expect("No layers in image")).clone();
|
||||
for layer in layer_iter {
|
||||
for (row_index, row) in layer.rows.iter().enumerate() {
|
||||
for (col_index, pixel) in row.iter().enumerate() {
|
||||
if final_layer.rows[row_index][col_index] == 2 {
|
||||
final_layer.rows[row_index][col_index] = *pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final_layer
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Image {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for layer in self.layers.iter() {
|
||||
write!(f, "{}\n", layer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
struct Layer {
|
||||
rows: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Layer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for row in self.rows.iter() {
|
||||
let row_string = row
|
||||
.iter()
|
||||
.map(|pixel| pixel.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join("");
|
||||
write!(f, "{}\n", row_string)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Layer {
|
||||
fn count_pixels(&self, pixel: u8) -> u32 {
|
||||
self.rows
|
||||
.iter()
|
||||
.flatten()
|
||||
.fold(0, |acc, p| if *p == pixel { acc + 1 } else { acc })
|
||||
}
|
||||
}
|
||||
|
||||
fn read_image_file(filename: &str) -> Result<String> {
|
||||
let mut file = File::open(filename)?;
|
||||
let mut image_string = String::new();
|
||||
file.read_to_string(&mut image_string)?;
|
||||
|
||||
Ok(image_string.trim().to_string())
|
||||
}
|
||||
|
||||
fn parse_image(image_string: String, width: usize, height: usize) -> Result<Image> {
|
||||
let mut layers = vec![];
|
||||
let mut layer = vec![];
|
||||
let mut row: Vec<u8> = vec![];
|
||||
for pixel in image_string.chars() {
|
||||
row.push(pixel.to_digit(10).expect("Invalid pixel character") as u8);
|
||||
if row.len() == width {
|
||||
layer.push(row);
|
||||
row = vec![];
|
||||
}
|
||||
if layer.len() == height {
|
||||
layers.push(Layer { rows: layer });
|
||||
layer = vec![];
|
||||
}
|
||||
}
|
||||
Ok(Image { layers })
|
||||
}
|
||||
|
||||
fn solve_part1() -> Result<u32> {
|
||||
let image_string = read_image_file(INPUT)?;
|
||||
let image = parse_image(image_string, 25, 6)?;
|
||||
let fewest_zero_layer = image
|
||||
.layers
|
||||
.iter()
|
||||
.min_by_key(|layer| layer.count_pixels(0))
|
||||
.expect("No image layers created");
|
||||
Ok(fewest_zero_layer.count_pixels(1) * fewest_zero_layer.count_pixels(2))
|
||||
}
|
||||
|
||||
fn solve_part2() -> Result<String> {
|
||||
let image_string = read_image_file(INPUT)?;
|
||||
let image = parse_image(image_string, 25, 6)?;
|
||||
Ok(format!("{}", image.final_layer()))
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
println!("Part 1: {}", solve_part1()?);
|
||||
println!("Part 2:\n{}", solve_part2()?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "input/test.txt";
|
||||
|
||||
#[test]
|
||||
fn reads_image() {
|
||||
let image_string = read_image_file(TEST_INPUT).unwrap();
|
||||
assert_eq!(
|
||||
parse_image(image_string, 3, 2).unwrap(),
|
||||
Image {
|
||||
layers: vec![Layer {
|
||||
rows: vec![vec![1, 2, 3], vec![4, 5, 6]],
|
||||
}],
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user