From aca62e1c441149846510b414890631a7f8b71bc7 Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Thu, 9 Dec 2021 15:16:13 -0800 Subject: [PATCH] day 8 part 1 --- 2021/src/day8.rs | 112 +++++++++++++++++++++++++++++++++++++++++++++++ 2021/src/main.rs | 6 +-- 2 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 2021/src/day8.rs diff --git a/2021/src/day8.rs b/2021/src/day8.rs new file mode 100644 index 0000000..039b430 --- /dev/null +++ b/2021/src/day8.rs @@ -0,0 +1,112 @@ +use std::str::FromStr; + +use color_eyre::eyre; +use eyre::eyre; + +use crate::lib::{ParseLines, IterExt}; + + +#[derive(Debug)] +enum Segment { + A = 1, + B = 2, + C = 4, + D = 8, + E = 16, + F = 32, + G = 64, // wheee! +} +use Segment::*; + +impl Segment { + fn from_char(c: char) -> eyre::Result { + match c { + 'a' => Ok(A), + 'b' => Ok(B), + 'c' => Ok(C), + 'd' => Ok(D), + 'e' => Ok(E), + 'f' => Ok(F), + 'g' => Ok(G), + _ => Err(eyre!("Invalid character for segment: {}", c)), + } + } +} + + +#[derive(Default, Debug)] +struct SegmentSet { + data: u8, + len: u8, +} + +impl SegmentSet { + fn contains(&self, segment: Segment) -> bool { + self.data & (segment as u8) > 0 + } + + fn insert(&mut self, segment: Segment) { + self.data |= segment as u8; + self.len += 1; + } + + fn remove(&mut self, segment: Segment) { + self.data ^= segment as u8; + self.len -= 1 + } + + fn len(&self) -> u8 { + self.len + } +} + +impl FromStr for SegmentSet { + type Err = eyre::Report; + fn from_str(s: &str) -> eyre::Result { + let mut set = Self::default(); + for c in s.chars() { + set.insert(Segment::from_char(c)?); + } + Ok(set) + } +} + + +#[derive(Default, Debug)] +struct Screen { + patterns: [SegmentSet; 10], + output: [SegmentSet; 4], +} + +impl FromStr for Screen { + type Err = eyre::Report; + fn from_str(s: &str) -> eyre::Result { + let mut screen = Screen::default(); + let (patterns, output) = s.split(" | ").take_pair()?; + + for (i, patt) in patterns.split(' ').enumerate() { + screen.patterns[i] = patt.parse::()?; + } + for (i, out) in output.split(' ').enumerate() { + screen.output[i] = out.parse::()?; + } + Ok(screen) + } +} + + +fn part1(screens: &[Screen]) -> usize { + screens.iter() + .flat_map(|d| d.output.iter()) + .filter(|s| matches!(s.len(), 2|3|4|7)) + .count() +} + + +pub fn run(data: &str) -> eyre::Result<(usize, usize)> { + let screens = data + .parse_lines::() + .collect::, _>>()?; + + Ok((part1(&screens), 0)) +} diff --git a/2021/src/main.rs b/2021/src/main.rs index ecb01fe..806623b 100644 --- a/2021/src/main.rs +++ b/2021/src/main.rs @@ -4,14 +4,14 @@ use color_eyre::eyre; mod lib; use lib::load; -mod day7; +mod day8; fn main() -> eyre::Result<()> { - let data = load("data/07.txt")?; + let data = load("data/08.txt")?; let start = Instant::now(); - let (one, two) = day7::run(&data)?; + let (one, two) = day8::run(&data)?; let (dur, unit) = format_ns(start.elapsed().as_nanos()); let precision = 2.0 - dur.log10().floor();