109 lines
3.8 KiB
Rust
109 lines
3.8 KiB
Rust
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)).collect::<anyhow::Result<Vec<_>>>()?.join("");
|
|
|
|
out.parse().map_err(anyhow::Error::new)
|
|
}
|
|
|
|
fn get_char(input: &[String], s: &str) -> 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(())
|
|
}
|
|
} |