This commit is contained in:
JonOfUs 2022-12-11 23:18:32 +01:00
parent a87505aa6d
commit 524f02adfa
3 changed files with 218 additions and 1 deletions

55
res/11/input.txt Normal file
View file

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 89, 84, 88, 78, 70
Operation: new = old * 5
Test: divisible by 7
If true: throw to monkey 6
If false: throw to monkey 7
Monkey 1:
Starting items: 76, 62, 61, 54, 69, 60, 85
Operation: new = old + 1
Test: divisible by 17
If true: throw to monkey 0
If false: throw to monkey 6
Monkey 2:
Starting items: 83, 89, 53
Operation: new = old + 8
Test: divisible by 11
If true: throw to monkey 5
If false: throw to monkey 3
Monkey 3:
Starting items: 95, 94, 85, 57
Operation: new = old + 4
Test: divisible by 13
If true: throw to monkey 0
If false: throw to monkey 1
Monkey 4:
Starting items: 82, 98
Operation: new = old + 7
Test: divisible by 19
If true: throw to monkey 5
If false: throw to monkey 2
Monkey 5:
Starting items: 69
Operation: new = old + 2
Test: divisible by 2
If true: throw to monkey 1
If false: throw to monkey 3
Monkey 6:
Starting items: 82, 70, 58, 87, 59, 99, 92, 65
Operation: new = old * 11
Test: divisible by 5
If true: throw to monkey 7
If false: throw to monkey 4
Monkey 7:
Starting items: 91, 53, 96, 98, 68, 82
Operation: new = old * old
Test: divisible by 3
If true: throw to monkey 4
If false: throw to monkey 2

161
src/days/d11.rs Normal file
View file

@ -0,0 +1,161 @@
use std::fs;
pub fn solve() {
let path = "res/11/input.txt";
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
let monk_strings: Vec<&str> = contents
.split("\n\n")
.collect();
let mut monkeys: Vec<Monkey> = monk_strings.iter().map(|monkey| Monkey::new(*monkey)).collect();
let mut monkeys2 = monkeys.clone();
let monkeys_num = monkeys.len();
(0..20).for_each(|_| {
(0..monkeys_num).for_each(|i| {
// get changed items
let new_items = monkeys[i].turn(monkeys_num, |x| x / 3);
// add items to correct monkeys
(0..monkeys_num).for_each(|i| {
new_items[i].iter().for_each(|item| monkeys[i].items.push(*item))
});
})
});
monkeys.sort_by(|a, b| b.inspections.cmp(&a.inspections));
let res = monkeys[0].inspections * monkeys[1].inspections;
println!("Result 1: {res}");
(0..10000).for_each(|_| {
(0..monkeys_num).for_each(|i| {
// get changed items, modulo them with common divider of divisible by tests
let common_divider: u64 = monkeys2.iter().map(|x| x.test_divisible_by).product();
let new_items = monkeys2[i].turn(monkeys_num, |x| x % common_divider);
// add items to correct monkeys
(0..monkeys_num).for_each(|i| {
new_items[i].iter().for_each(|item| monkeys2[i].items.push(*item))
});
})
});
monkeys2.sort_by(|a, b| b.inspections.cmp(&a.inspections));
let res = monkeys2[0].inspections * monkeys2[1].inspections;
println!("Result 2: {res}");
}
#[derive(Debug, PartialEq, Clone)]
enum Operation {
Mult,
Add
}
#[derive(Debug, Clone)]
struct Monkey {
pub items: Vec<u64>,
operation_type: Operation,
operation_num: i32,
operation_quad: bool,
test_divisible_by: u64,
monkey_if_true: i32,
monkey_if_false: i32,
inspections: u64,
}
impl Monkey {
pub fn new(input: &str) -> Self {
let mut monkey = Monkey {
items: Vec::<u64>::new(),
operation_type: Operation::Add,
operation_num: 0,
operation_quad: false,
test_divisible_by: 0,
monkey_if_true: 0,
monkey_if_false: 0,
inspections: 0
};
input.split("\n").filter(|line| *line != "").for_each(|line| {
let (ident, mut val) = line.split_at(line.find(":").unwrap());
match ident {
" Starting items" => {
// remove whitespace and beginning, split by ,
let val = val.replace(":","").replace(" ", "");
monkey.items = val
.split(",")
.collect::<Vec::<&str>>()
.iter()
.map(|i| (*i).parse::<u64>().unwrap())
.collect()
},
" Operation" => {
// parse operator, parse last word as number
let val = val.replace(": new = old ", "");
let (op, num) = val.split_at(val.find(" ").unwrap());
match op {
"+" => monkey.operation_type = Operation::Add,
"*" => monkey.operation_type = Operation::Mult,
_ => {}
}
if num == " old" {
monkey.operation_quad = true
} else {
monkey.operation_num = num.trim().parse::<i32>().unwrap();
}
},
" Test" => {
// parse last word as number
let words: Vec<&str> = val.split(" ").collect();
monkey.test_divisible_by = words.last().unwrap().parse::<u64>().unwrap();
},
" If true" => {
// parse last word as number
let words: Vec<&str> = val.split(" ").collect();
monkey.monkey_if_true = words.last().unwrap().parse::<i32>().unwrap();
},
" If false" => {
// parse last word as number
let words: Vec<&str> = val.split(" ").collect();
monkey.monkey_if_false = words.last().unwrap().parse::<i32>().unwrap();
},
_ => {}
}
});
monkey
}
pub fn turn(&mut self, monkeys: usize, func: impl Fn(u64) -> u64) -> Vec<Vec<u64>> {
let mut items: Vec<Vec<u64>> = (0..monkeys).map(|_| Vec::<u64>::new()).collect();
self.items.iter().for_each(|item| {
let mut worry_level = *item;
// Operation
if self.operation_type == Operation::Add {
worry_level += self.operation_num as u64
} else {
worry_level *= if self.operation_quad {
worry_level
} else {
self.operation_num as u64
}
}
// Run func on worry level
let worry_level = func(worry_level);
// Test & push to other monkey
if worry_level % self.test_divisible_by as u64 == 0 {
items[self.monkey_if_true as usize].push(worry_level)
} else {
items[self.monkey_if_false as usize].push(worry_level)
}
self.inspections += 1
});
self.items.clear();
items
}
}

View file

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