AoC2021/src/day08.rs

109 lines
3.8 KiB
Rust
Raw Normal View History

2021-12-08 09:56:50 +01:00
use crate::Day;
pub struct Day08(Vec<(Vec<String>, Vec<String>)>);
impl Day for Day08 {
fn init(content: String) -> anyhow::Result<Self> {
let x = content.lines().map(foo).collect::<Vec<(Vec<String>, Vec<String>)>>();
Ok(Self(x))
}
fn part1(&self) -> anyhow::Result<String> {
let mut count = 0;
for (_, b) in &self.0 {
let l = b.iter().map(String::len).filter(|n| (*n == 2) || (*n == 4) || (*n == 3) | (*n == 7)).count();
count += l;
}
Ok(format!("{}", count))
}
fn part2(&self) -> anyhow::Result<String> {
Ok(format!("{}", self.0.iter().cloned().map(do_stuff).collect::<anyhow::Result<Vec<i32>>>()?.iter().sum::<i32>()))
}
}
fn do_stuff((input, output): (Vec<String>, Vec<String>)) -> anyhow::Result<i32> {
let out = output.iter().map(|x| get_char(&input, x.clone())).collect::<anyhow::Result<Vec<_>>>()?.join("");
out.parse().map_err(anyhow::Error::new)
}
fn get_char(input: &[String], s: String) -> anyhow::Result<String> {
let one = input.iter().cloned().find(|x| x.len() == 2).ok_or_else(|| anyhow::Error::msg("could not find one"))?.chars().collect::<Vec<char>>();
let four = input.iter().cloned().find(|x| x.len() == 4).ok_or_else(|| anyhow::Error::msg("could not find one"))?.chars().collect::<Vec<char>>();
let chars = s.chars().collect::<Vec<char>>();
let x = match s.len() {
2 => "1",
3 => "7",
4 => "4",
5 => match chars.iter().filter(|x| !one.contains(*x)).count() {
3 => "3",
_ => match chars.iter().filter(|x| !four.contains(*x)).count() {
3 => "2",
_ => "5",
}
},
6 => match chars.iter().filter(|x| !one.contains(*x)).count() {
5 => "6",
_ => match chars.iter().filter(|x| !four.contains(*x)).count() {
2 => "9",
_ => "0",
}
}
_ => "8",
};
Ok(x.to_string())
}
fn foo(st: &str) -> (Vec<String>, Vec<String>) {
let z = st.split('|').collect::<Vec<_>>();
let input = z[0];
let output = z[1];
(input.split_whitespace().map(String::from).collect(), output.split_whitespace().map(String::from).collect())
}
#[cfg(test)]
mod tests{
use crate::Day08;
use crate::day::Day;
const INPUT: &str = r"be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce";
#[test]
fn part1_test() -> anyhow::Result<()>{
let d = Day08::init(INPUT.to_string())?;
assert_eq!("26", d.part1()?);
Ok(())
}
#[test]
fn part2_test() -> anyhow::Result<()>{
let d = Day08::init(INPUT.to_string())?;
assert_eq!("61229", d.part2()?);
Ok(())
}
#[test]
fn part1_real() -> anyhow::Result<()> {
let d = Day08::init(crate::load_input("08")?)?;
assert_eq!("479", d.part1()?);
Ok(())
}
#[test]
fn part2_real() -> anyhow::Result<()> {
let d = Day08::init(crate::load_input("08")?)?;
assert_eq!("1041746", d.part2()?);
Ok(())
}
}