73 lines
1.8 KiB
Rust
73 lines
1.8 KiB
Rust
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<usize> {
|
|
Ok(
|
|
input
|
|
.lines()
|
|
.map(|line| {
|
|
line
|
|
.split(" | ")
|
|
.nth(1)
|
|
.ok_or(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(),
|
|
)
|
|
}
|
|
|
|
fn part_2(input: &str) -> Result<isize> {
|
|
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::<Vec<_>>(),
|
|
)?;
|
|
|
|
// 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::<Vec<_>>();
|
|
|
|
// 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)
|
|
}
|