aoc

My solutions for the Advent of Code
git clone https://git.tronto.net/aoc
Download | Log | Files | Refs | README

b.rs (2435B)


      1 mod common;
      2 use common::*;
      3 
      4 fn solve_for_humn(name: &str, n1: i64, monkeys: &Vec<Monkey>) -> i64 {
      5     if name == "humn" { return n1; }
      6 
      7     let i = monkeys.iter().position(|m| m.name == name).unwrap();
      8     if let MonkeyType::Op(op) = &monkeys[i].kind {
      9         if let Some(n2) = result_or_unknown(&op.m1, &monkeys) {
     10             // n1 = n2 [op] [unknown]
     11             match op.op {
     12                 '+' => solve_for_humn(&op.m2, n1-n2, &monkeys),
     13                 '-' => solve_for_humn(&op.m2, n2-n1, &monkeys),
     14                 '*' => solve_for_humn(&op.m2, n1/n2, &monkeys),
     15                 '/' => solve_for_humn(&op.m2, n2/n1, &monkeys),
     16                 _ => panic!("invalid operator")
     17             }
     18         } else {
     19             if let Some(n2) = result_or_unknown(&op.m2, &monkeys) {
     20                 // n1 = [unknown] [op] n2
     21                 match op.op {
     22                     '+' => solve_for_humn(&op.m1, n1-n2, &monkeys),
     23                     '-' => solve_for_humn(&op.m1, n1+n2, &monkeys),
     24                     '*' => solve_for_humn(&op.m1, n1/n2, &monkeys),
     25                     '/' => solve_for_humn(&op.m1, n1*n2, &monkeys),
     26                     _ => panic!("invalid operator")
     27                 }
     28             } else { panic!("both sides undetermined"); }
     29         }
     30     } else { panic!("found number when trying to solve for humn"); }
     31 }
     32 
     33 fn result_or_unknown(name: &str, monkeys: &Vec<Monkey>) -> Option<i64> {
     34     if name == "humn" { return None; }
     35 
     36     let i = monkeys.iter().position(|m| m.name == name).unwrap();
     37     match &monkeys[i].kind {
     38         MonkeyType::Num(n) => Some(*n),
     39         MonkeyType::Op(op) => {
     40             let n1 = result_or_unknown(&op.m1, &monkeys)?;
     41             let n2 = result_or_unknown(&op.m2, &monkeys)?;
     42             Some(apply_op(n1, n2, op))
     43         }
     44     }
     45 }
     46 
     47 pub fn solve(monkeys: &Vec<Monkey>) -> i64 {
     48     let i = monkeys.iter().position(|m| m.name == "root").unwrap();
     49     if let MonkeyType::Op(op) = &monkeys[i].kind {
     50         if let Some(n) = result_or_unknown(&op.m1, &monkeys) {
     51             return solve_for_humn(&op.m2, n, monkeys);
     52         } else {
     53             if let Some(n) = result_or_unknown(&op.m2, &monkeys) {
     54                 return solve_for_humn(&op.m1, n, &monkeys);
     55             } else { panic!("humn not found"); }
     56         }
     57     } else { panic!("root monkey is of type number"); }
     58 }
     59 
     60 fn main() {
     61     let monkeys = read_monkeys_from_stdin();
     62     println!("{}", solve(&monkeys));
     63 }