commit 2641a35d5473beb6889b299b54de294fbf782b1f
parent 2f0e522317972711b5e03ad25b38bf03af17e8d5
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Mon, 7 Jul 2025 11:47:29 +0200
Day 21 2022
Diffstat:
3 files changed, 133 insertions(+), 0 deletions(-)
diff --git a/2022/21/a.rs b/2022/21/a.rs
@@ -0,0 +1,19 @@
+mod common;
+use common::*;
+
+pub fn calculate(name: &str, monkeys: &Vec<Monkey>) -> i64 {
+ let i = monkeys.iter().position(|m| m.name == name).unwrap();
+ match &monkeys[i].kind {
+ MonkeyType::Num(n) => *n,
+ MonkeyType::Op(op) => {
+ let n1 = calculate(&op.m1, &monkeys);
+ let n2 = calculate(&op.m2, &monkeys);
+ apply_op(n1, n2, op)
+ }
+ }
+}
+
+fn main() {
+ let monkeys = read_monkeys_from_stdin();
+ println!("{}", calculate(&"root", &monkeys));
+}
diff --git a/2022/21/b.rs b/2022/21/b.rs
@@ -0,0 +1,63 @@
+mod common;
+use common::*;
+
+fn solve_for_humn(name: &str, n1: i64, monkeys: &Vec<Monkey>) -> i64 {
+ if name == "humn" { return n1; }
+
+ let i = monkeys.iter().position(|m| m.name == name).unwrap();
+ if let MonkeyType::Op(op) = &monkeys[i].kind {
+ if let Some(n2) = result_or_unknown(&op.m1, &monkeys) {
+ // n1 = n2 [op] [unknown]
+ match op.op {
+ '+' => solve_for_humn(&op.m2, n1-n2, &monkeys),
+ '-' => solve_for_humn(&op.m2, n2-n1, &monkeys),
+ '*' => solve_for_humn(&op.m2, n1/n2, &monkeys),
+ '/' => solve_for_humn(&op.m2, n2/n1, &monkeys),
+ _ => panic!("invalid operator")
+ }
+ } else {
+ if let Some(n2) = result_or_unknown(&op.m2, &monkeys) {
+ // n1 = [unknown] [op] n2
+ match op.op {
+ '+' => solve_for_humn(&op.m1, n1-n2, &monkeys),
+ '-' => solve_for_humn(&op.m1, n1+n2, &monkeys),
+ '*' => solve_for_humn(&op.m1, n1/n2, &monkeys),
+ '/' => solve_for_humn(&op.m1, n1*n2, &monkeys),
+ _ => panic!("invalid operator")
+ }
+ } else { panic!("both sides undetermined"); }
+ }
+ } else { panic!("found number when trying to solve for humn"); }
+}
+
+fn result_or_unknown(name: &str, monkeys: &Vec<Monkey>) -> Option<i64> {
+ if name == "humn" { return None; }
+
+ let i = monkeys.iter().position(|m| m.name == name).unwrap();
+ match &monkeys[i].kind {
+ MonkeyType::Num(n) => Some(*n),
+ MonkeyType::Op(op) => {
+ let n1 = result_or_unknown(&op.m1, &monkeys)?;
+ let n2 = result_or_unknown(&op.m2, &monkeys)?;
+ Some(apply_op(n1, n2, op))
+ }
+ }
+}
+
+pub fn solve(monkeys: &Vec<Monkey>) -> i64 {
+ let i = monkeys.iter().position(|m| m.name == "root").unwrap();
+ if let MonkeyType::Op(op) = &monkeys[i].kind {
+ if let Some(n) = result_or_unknown(&op.m1, &monkeys) {
+ return solve_for_humn(&op.m2, n, monkeys);
+ } else {
+ if let Some(n) = result_or_unknown(&op.m2, &monkeys) {
+ return solve_for_humn(&op.m1, n, &monkeys);
+ } else { panic!("humn not found"); }
+ }
+ } else { panic!("root monkey is of type number"); }
+}
+
+fn main() {
+ let monkeys = read_monkeys_from_stdin();
+ println!("{}", solve(&monkeys));
+}
diff --git a/2022/21/common.rs b/2022/21/common.rs
@@ -0,0 +1,51 @@
+#[derive(Debug)]
+pub struct Operation {
+ pub m1: String,
+ pub m2: String,
+ pub op: char
+}
+
+#[derive(Debug)]
+pub enum MonkeyType {
+ Num(i64),
+ Op(Operation)
+}
+
+#[derive(Debug)]
+pub struct Monkey {
+ pub name: String,
+ pub kind: MonkeyType
+}
+
+pub fn read_monkeys_from_stdin() -> Vec<Monkey> {
+ let mut v = vec![];
+ let mut line = String::new();
+ while std::io::stdin().read_line(&mut line).unwrap() > 0 {
+ let name = String::from(&line[0..4]);
+ let monkey = match line.chars().nth(6).unwrap() {
+ '0'..='9' => {
+ let n = line[6..line.len()-1].parse::<i64>().unwrap();
+ Monkey { name, kind: MonkeyType::Num(n) }
+ },
+ _ => {
+ let m1 = String::from(&line[6..10]);
+ let m2 = String::from(&line[13..17]);
+ let op = Operation { m1, m2, op: line.chars().nth(11).unwrap() };
+ Monkey { name, kind: MonkeyType::Op(op) }
+ }
+ };
+ v.push(monkey);
+ line.clear();
+ }
+ v
+}
+
+pub fn apply_op(n1: i64, n2: i64, op: &Operation) -> i64 {
+ match op.op {
+ '+' => n1 + n2,
+ '-' => n1 - n2,
+ '*' => n1 * n2,
+ '/' => n1 / n2,
+ _ => panic!("invalid operator")
+ }
+}