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 { Ok( input .lines() .map(|line| { line .split(" | ") .nth(1) .ok_or_else(|| eyre!("Invalid input: {}", line)) }) .collect::>>()? .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 { 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::>(), )?; // 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()) }