aoc

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

commit 2641a35d5473beb6889b299b54de294fbf782b1f
parent 2f0e522317972711b5e03ad25b38bf03af17e8d5
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Mon,  7 Jul 2025 11:47:29 +0200

Day 21 2022

Diffstat:
A2022/21/a.rs | 19+++++++++++++++++++
A2022/21/b.rs | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2022/21/common.rs | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
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") + } +}