Day 11
This commit is contained in:
parent
a87505aa6d
commit
524f02adfa
3 changed files with 218 additions and 1 deletions
55
res/11/input.txt
Normal file
55
res/11/input.txt
Normal 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
161
src/days/d11.rs
Normal 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
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
pub mod days;
|
||||
|
||||
fn main() {
|
||||
days::d10::solve()
|
||||
days::d11::solve()
|
||||
//_all_days()
|
||||
}
|
||||
|
||||
fn _all_days() {
|
||||
|
|
Loading…
Reference in a new issue