use color_eyre::{eyre::eyre, Result}; mod display; use display::{CharSet, Display}; pub fn solve() -> Result<()> { let input_data = include_str!("../../data/day_08.txt").trim(); println!("Day 08 Part 1: {}", part_1(input_data)?); println!("Day 08 Part 2: {}", part_2(input_data)?); Ok(()) } fn part_1(input: &str) -> Result { Ok( input .lines() .map(|line| { line .split(" | ") .nth(1) .ok_or(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(), ) } 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(eyre!("Invalid input: {}", line))? .split(" ") .map(Display::parse) .collect::>(), )?; // Get all the CharSets from the encoded side. let encoded = split .next() .ok_or(eyre!("Invalid input: {}", line))? .split(" ") .map(str::chars) .map(CharSet::from_iter) .collect::>(); // 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.into_iter().rev().enumerate() { let decoded_number = displays .iter() .find(|display| display.1 == &set) .map(|display| display.0) .ok_or(eyre!("Impossible to decode {:?}", set))?; sum += 10_isize.pow(index as u32) * decoded_number; } } Ok(sum) }