1
Fork 0
advent-of-code/source/year_2021/day_08/mod.rs

70 lines
1.7 KiB
Rust

mod display;
use display::{CharSet, Display};
use crate::prelude::*;
pub fn solution() -> Solution {
Solution::new(Day::new(8, 2021), part_1, part_2).with_expected(521, 1016804)
}
fn part_1(input: &str) -> Result<String> {
Ok(
input
.lines()
.map(|line| {
line
.split(" | ")
.nth(1)
.ok_or_else(|| eyre!("Invalid input: {}", line))
})
.collect::<Result<Vec<_>>>()?
.into_iter()
.flat_map(|line| line.split(' ').map(Display::parse))
.filter(|display| [2, 4, 3, 7].contains(&display.0))
.count()
.to_string(),
)
}
fn part_2(input: &str) -> Result<String> {
let mut sum = 0;
for line in input.lines() {
let mut split = line.split(" | ");
// Figure out the displays from the signal side.
let displays = Display::figure_out_from_others(
split
.next()
.ok_or_else(|| eyre!("Invalid input: {}", line))?
.split(' ')
.map(Display::parse)
.collect::<Vec<_>>(),
)?;
// Get all the CharSets from the encoded side.
let encoded = split
.next()
.ok_or_else(|| eyre!("Invalid input: {}", line))?
.split(' ')
.map(str::chars)
.map(CharSet::from_iter);
// Loop through the encoded numbers backwards so we can use the loop index
// to multiply it by 10 to the power of the index.
// So 123 would be (3 * 1) + (2 * 10) + (1 * 100).
for (index, set) in encoded.rev().enumerate() {
let decoded_number = displays
.iter()
.find(|display| display.1 == &set)
.map(|display| display.0)
.ok_or_else(|| eyre!("Impossible to decode {:?}", set))?;
sum += 10_isize.pow(index as u32) * decoded_number;
}
}
Ok(sum.to_string())
}