Day 21 - task 1

This commit is contained in:
Jonathan Flueren 2022-12-21 14:47:20 +01:00
parent c9808224ec
commit 93769a8013
4 changed files with 2162 additions and 1 deletions

2027
res/21/input.txt Normal file

File diff suppressed because it is too large Load diff

15
res/21/test-input.txt Normal file
View file

@ -0,0 +1,15 @@
root: pppw + sjmn
dbpl: 5
cczh: sllz + lgvd
zczc: 2
ptdq: humn - dvpt
dvpt: 3
lfqf: 4
humn: 5
ljgn: 2
sjmn: drzm * dbpl
sllz: 4
pppw: cczh / lfqf
lgvd: ljgn * ptdq
drzm: hmdt - zczc
hmdt: 32

119
src/days/d21.rs Normal file
View file

@ -0,0 +1,119 @@
use std::{collections::HashMap, fs};
const ROOT: &str = "root";
pub fn solve() {
let path = "res/21/input.txt";
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
// Holds the things the monkeys yell
let mut monkeys: HashMap<String, Yell> = contents
.lines()
.filter(|line| *line != "")
.map(|line| {
let split: Vec<&str> = line.split_whitespace().collect();
match split.len() {
4 => {
let op = match split[2] {
"+" => Operation::Add,
"-" => Operation::Substract,
"*" => Operation::Multiply,
"/" => Operation::Divide,
_ => std::unreachable!(),
};
(
split[0].replace(":", ""),
Yell::Calculation(
Monkey::Name(String::from(split[1])),
op,
Monkey::Name(String::from(split[3])),
),
)
}
2 => (
split[0].replace(":", ""),
Yell::Number(split[1].parse::<u64>().unwrap()),
),
_ => std::unreachable!(),
}
})
.collect();
// Holds all known results of monkey yells
let mut monkey_nums: HashMap<String, u64> = monkeys
.iter()
.filter(|(_, v)| match v {
Yell::Number(_) => true,
_ => false,
})
.map(|(k, v)| {
(
k.clone(),
match v {
Yell::Number(n) => *n,
_ => 0,
},
)
})
.collect();
// go through monkeys and calculate monkey results and replace monkey references with monkey results until root has a result
loop {
// break out of loop if finished
if let Yell::Number(_) = monkeys.get(ROOT).unwrap() {
break;
}
for (monkey, yell) in monkeys.iter_mut() {
if let Yell::Calculation(m1, op, m2) = yell {
// if possible, replace monkey names in yell with their actual numbers
if let Monkey::Name(name) = m1 {
if let Some(num) = monkey_nums.get(name) {
*m1 = Monkey::Result(*num)
}
}
if let Monkey::Name(name) = m2 {
if let Some(num) = monkey_nums.get(name) {
*m2 = Monkey::Result(*num)
}
}
// if both numbers of calc are known, calculate the result and update both hashmaps
if let Monkey::Result(r1) = m1 {
if let Monkey::Result(r2) = m2 {
let num: u64 = match op {
Operation::Add => *r1 + *r2,
Operation::Substract => *r1 - *r2,
Operation::Multiply => *r1 * *r2,
Operation::Divide => *r1 / *r2,
};
*yell = Yell::Number(num);
monkey_nums.insert(monkey.clone(), num);
}
}
}
}
}
let res = monkey_nums.get(ROOT).unwrap();
println!("Result 1: {res}")
}
#[derive(Debug, Clone)]
enum Operation {
Add,
Substract,
Multiply,
Divide,
}
#[derive(Debug, Clone)]
enum Yell {
Number(u64),
Calculation(Monkey, Operation, Monkey),
}
#[derive(Debug, Clone)]
enum Monkey {
Result(u64),
Name(String),
}

View file

@ -1,7 +1,7 @@
pub mod days;
fn main() {
days::d20::solve()
days::d21::solve()
//_all_days()
}