--- /dev/null
+use std::io::BufRead;
+
+use crate::utils;
+
+#[derive(Debug)]
+pub struct Equation {
+ result: i64,
+ operands: Vec<i64>,
+}
+
+pub fn read<R>(reader: R) -> Vec<Equation>
+where
+ R: BufRead,
+{
+ reader
+ .lines()
+ .map(|l| {
+ let l = l.unwrap();
+ let mut result_and_rest = l.split(": ").into_iter();
+ Equation {
+ result: result_and_rest.next().unwrap().parse().unwrap(),
+ operands: utils::split_to_vec(result_and_rest.next().unwrap(), " "),
+ }
+ })
+ .collect()
+}
+
+pub fn sum_valid_equations(equations: &[Equation]) -> i64 {
+ fn is_valid(result: i64, operands: &[i64]) -> bool {
+ let l = operands.len();
+ if l == 1 {
+ return result == operands[0];
+ }
+ let last = operands[l - 1];
+ if result % last == 0 {
+ if is_valid(result / last, &operands[0..l - 1]) {
+ return true;
+ }
+ }
+ let sub = result - last;
+ if sub >= 0 {
+ return is_valid(sub, &operands[0..l - 1]);
+ }
+ false
+ }
+ equations
+ .iter()
+ .filter_map(|eq| {
+ if is_valid(eq.result, &eq.operands) {
+ Some(eq.result)
+ } else {
+ None
+ }
+ })
+ .sum()
+}
+
+fn nb_of_digits(mut v: i64) -> u32 {
+ let mut n = 1;
+ while v >= 10 {
+ v /= 10;
+ n += 1;
+ }
+ n
+}
+
+pub fn sum_valid_equations_with_concat(equations: &[Equation]) -> i64 {
+ fn is_valid(result: i64, operands: &[i64]) -> bool {
+ let l = operands.len();
+ if l == 1 {
+ return result == operands[0];
+ }
+ let last = operands[l - 1];
+ if result % last == 0 {
+ if is_valid(result / last, &operands[0..l - 1]) {
+ return true;
+ }
+ }
+ let sub = result - last;
+ if sub >= 0 {
+ if is_valid(sub, &operands[0..l - 1]) {
+ return true;
+ }
+
+ let p = 10i64.pow(nb_of_digits(last));
+ if sub % p == 0 {
+ if is_valid(sub / p, &operands[0..l - 1]) {
+ return true;
+ }
+ }
+ }
+ false
+ }
+ equations
+ .iter()
+ .filter_map(|eq| {
+ if is_valid(eq.result, &eq.operands) {
+ Some(eq.result)
+ } else {
+ None
+ }
+ })
+ .sum()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ static EQUATIONS: &str = "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";
+
+ #[test]
+ fn test_part1() {
+ let equations = read(EQUATIONS.as_bytes());
+ let sum = sum_valid_equations(&equations);
+ assert_eq!(sum, 3749);
+ }
+
+ #[test]
+ fn test_part2() {
+ let equations = read(EQUATIONS.as_bytes());
+ let sum = sum_valid_equations_with_concat(&equations);
+ assert_eq!(sum, 11387);
+ }
+}
day06::nb_possible_obstruction_position(&map, guard_pos),
)
}
+
+pub fn day07() -> String {
+ let f = fs::File::open("data/day07.input").unwrap();
+ let equations = day07::read(BufReader::new(f));
+ format!(
+ "part1: {}, part2: {}",
+ day07::sum_valid_equations(&equations),
+ day07::sum_valid_equations_with_concat(&equations),
+ )
+}