From aba8c4be8eec16124692175f981c9a3e9e68dc02 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Sat, 7 Dec 2024 17:44:07 +0200 Subject: [PATCH] feat: day7 --- input/day7/example | 9 +++ src/day7/mod.rs | 184 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++ 3 files changed, 201 insertions(+) create mode 100644 input/day7/example create mode 100644 src/day7/mod.rs diff --git a/input/day7/example b/input/day7/example new file mode 100644 index 0000000..fc6e099 --- /dev/null +++ b/input/day7/example @@ -0,0 +1,9 @@ +190: 10 19 +3267: 81 40 27 +83: 17 5 +156: 15 6 +7290: 6 8 6 15 +161011: 16 10 13 +192: 17 8 14 +21037: 9 7 18 13 +292: 11 6 16 20 diff --git a/src/day7/mod.rs b/src/day7/mod.rs new file mode 100644 index 0000000..1ee7c66 --- /dev/null +++ b/src/day7/mod.rs @@ -0,0 +1,184 @@ +use std::{ + fs::File, + io::{BufRead, BufReader}, + path::Path, + str::FromStr, +}; + +pub fn solve(input: &Path) -> anyhow::Result<()> { + println!("part one: {}", part_one(input)?); + println!("part two: {}", part_two(input)?); + + Ok(()) +} + +#[derive(Debug)] +struct Equation { + answer: u64, + inputs: Vec, +} + +impl FromStr for Equation { + type Err = Box; + fn from_str(s: &str) -> Result { + let mut parts = s.split(":"); + + Ok(Equation { + answer: parts.next().unwrap().parse()?, + inputs: parts + .next() + .unwrap() + .split_whitespace() + .map(|n| -> u64 { n.parse().unwrap() }) + .collect(), + }) + } +} + +fn part_one(input: &Path) -> anyhow::Result { + let reader = BufReader::new(File::open(input)?); + + let mut equations = vec![]; + for line in reader.lines() { + equations.push(Equation::from_str(&line?).unwrap()); + } + + Ok(equations + .iter() + .filter(|eq| check_equation_one(eq)) + .map(|eq| eq.answer) + .collect::>() + .iter() + .sum()) +} + +fn check_equation_one(eq: &Equation) -> bool { + let positions = eq.inputs.len() - 1; + + if positions == 1 { + if eq.inputs[0] + eq.inputs[1] == eq.answer { + return true; + } + if eq.inputs[0] * eq.inputs[1] == eq.answer { + return true; + } + return false; + } + + let operators = ["+", "*"]; + + let combinations: Vec = (operators.len()..positions).fold( + operators + .iter() + .flat_map(|c| operators.iter().map(move |&d| d.to_owned() + *c)) + .collect(), + |a, _| { + a.into_iter() + .flat_map(|c| operators.iter().map(move |&d| d.to_owned() + &*c)) + .collect() + }, + ); + + for combination in combinations { + let combination: Vec = combination.chars().collect(); + let mut current: Option = None; + for (i, input) in eq.inputs.iter().enumerate() { + if current.is_none() { + current = Some(*input); + continue; + } + + match combination[i - 1] { + '+' => current = Some(current.unwrap() + input), + '*' => current = Some(current.unwrap() * input), + _ => panic!(), + } + } + if current.unwrap() == eq.answer { + return true; + } + } + + false +} + +fn part_two(input: &Path) -> anyhow::Result { + let reader = BufReader::new(File::open(input)?); + + let mut equations = vec![]; + for line in reader.lines() { + equations.push(Equation::from_str(&line?).unwrap()); + } + + Ok(equations + .iter() + .filter(|eq| check_equation_two(eq)) + .map(|eq| eq.answer) + .collect::>() + .iter() + .sum()) +} + +fn check_equation_two(eq: &Equation) -> bool { + let positions = eq.inputs.len() - 1; + + if positions == 1 { + if eq.inputs[0] + eq.inputs[1] == eq.answer { + return true; + } + if eq.inputs[0] * eq.inputs[1] == eq.answer { + return true; + } + if (eq.inputs[0].to_string() + &eq.inputs[1].to_string()) + .parse::() + .unwrap() + == eq.answer + { + return true; + } + return false; + } + + let operators = ["+", "*", "|"]; + + let combinations: Vec = (operators.len()..positions + 1).fold( + operators + .iter() + .flat_map(|c| operators.iter().map(move |&d| d.to_owned() + *c)) + .collect(), + |a, _| { + a.into_iter() + .flat_map(|c| operators.iter().map(move |&d| d.to_owned() + &*c)) + .collect() + }, + ); + + for combination in combinations { + let combination: Vec = combination.chars().collect(); + let mut current: Option = None; + for (i, input) in eq.inputs.iter().enumerate() { + if current.is_none() { + current = Some(*input); + continue; + } + + match combination[i - 1] { + '+' => current = Some(current.unwrap() + input), + '*' => current = Some(current.unwrap() * input), + '|' => { + current = Some( + (current.unwrap().to_string() + &input.to_string()) + .parse() + .unwrap(), + ) + } + _ => panic!(), + } + } + if current.unwrap() == eq.answer { + return true; + } + } + + false +} diff --git a/src/main.rs b/src/main.rs index f15eca4..b7e22d8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod day3; mod day4; mod day5; mod day6; +mod day7; #[derive(Parser)] struct Args { @@ -45,6 +46,10 @@ enum DayArgs { #[arg(short)] input: PathBuf, }, + Day7 { + #[arg(short)] + input: PathBuf, + }, } fn main() -> anyhow::Result<()> { @@ -69,6 +74,9 @@ fn main() -> anyhow::Result<()> { DayArgs::Day6 { input } => { day6::solve(&input)?; } + DayArgs::Day7 { input } => { + day7::solve(&input)?; + } } Ok(()) -- 2.44.1