/ day07 / src / main.rs
main.rs
 1  use std::str;
 2  
 3  fn main() {
 4      let mut list: Vec<(f64, Vec<f64>)> = vec![];
 5      str::from_utf8(include_bytes!("input"))
 6          .unwrap()
 7          .lines()
 8          .map(|l| l.split(": ").collect::<Vec<&str>>())
 9          .for_each(|l| {
10              list.push((
11                  l[0].parse::<f64>().unwrap(),
12                  l[1].split(" ")
13                      .collect::<Vec<&str>>()
14                      .iter()
15                      .map(|e| e.parse::<f64>().unwrap())
16                      .collect::<Vec<f64>>(),
17              ))
18          });
19  
20      // Part 1
21      let mut correct_sum: f64 = 0.0;
22  
23      let mut incorrect_lines: Vec<(f64, Vec<f64>)> = vec![];
24  
25      for line in list {
26          if is_true(line.0, &line.1) {
27              correct_sum += line.0;
28          } else {
29              incorrect_lines.push(line.clone())
30          }
31      }
32      println!("Part 1 : {correct_sum}");
33  
34      // Part 2
35      for line in incorrect_lines {
36          if is_true_2(line.0, &line.1) {
37              dbg!("CORRECT", &line);
38              correct_sum += line.0;
39          }
40      }
41      println!("Part 2 : {correct_sum}");
42  }
43  
44  fn is_true(n: f64, l: &[f64]) -> bool {
45      if l.len() == 1 {
46          return n == l[0];
47      }
48  
49      let state = is_true(n - l.last().unwrap(), &l[..l.len() - 1])
50          || is_true(n / l.last().unwrap(), &l[..l.len() - 1]);
51  
52      return state;
53  }
54  
55  fn is_true_2(n: f64, l: &[f64]) -> bool {
56      if l.len() == 1 {
57          return n == l[0];
58      }
59      
60      let state = is_true_2(n - l.last().unwrap(), &l[..l.len() - 1])
61          || is_true_2(n / l.last().unwrap(), &l[..l.len() - 1]);
62      
63      // Concat if possible
64      if n.abs() != f64::INFINITY && n.fract() == 0.0
65          && (n as u64) % (10u64.pow(l.last().unwrap().max(1.0).log10().floor() as u32 + 1)) as u64
66              == *l.last().unwrap() as u64
67      {
68          return state
69              || is_true_2(
70                  (n / (10u64.pow(l.last().unwrap().max(1.0).log10().floor() as u32 + 1)) as f64)
71                      .floor(),
72                  &l[..l.len() - 1],
73              );
74      }
75      
76      return state;
77  }