/ Rust / 2024 / 07.rs
07.rs
 1  #![feature(test)]
 2  
 3  type Input = Vec<Equation>;
 4  
 5  #[derive(Debug)]
 6  struct Equation {
 7      result: i64,
 8      numbers: Vec<i64>,
 9  }
10  
11  fn setup(input: &str) -> Input {
12      input
13          .trim()
14          .lines()
15          .map(|line| {
16              let mut nums = line.split_whitespace();
17              let result = nums.next().unwrap().trim_end_matches(':').parse().unwrap();
18              let numbers = nums.map(|n| n.parse().unwrap()).collect();
19              Equation { result, numbers }
20          })
21          .collect()
22  }
23  
24  fn solve<const P2: bool>(nums: &[i64], goal: i64) -> bool {
25      if nums.len() == 1 {
26          return nums[0] == goal;
27      }
28  
29      let (&last, init) = nums.split_last().unwrap();
30  
31      let p = 10i64.pow(last.ilog10() + 1);
32  
33      (P2 && goal % p == last && solve::<P2>(init, goal / p))
34          || (goal % last == 0 && solve::<P2>(init, goal / last))
35          || solve::<P2>(init, goal - last)
36  }
37  
38  fn part1(input: &Input) -> i64 {
39      input
40          .iter()
41          .filter(|eq| solve::<false>(&eq.numbers, eq.result))
42          .map(|eq| eq.result)
43          .sum()
44  }
45  
46  fn part2(input: &Input) -> i64 {
47      input
48          .iter()
49          .filter(|eq| solve::<true>(&eq.numbers, eq.result))
50          .map(|eq| eq.result)
51          .sum()
52  }
53  
54  aoc::main!(2024, 7, ex: 1);