1
0
Fork 0
aoc2022/src/main.rs

136 lines
3.5 KiB
Rust
Raw Normal View History

2022-12-02 06:41:26 +00:00
#![feature(test)]
2022-12-11 06:01:27 +00:00
use std::{cmp::Reverse, rc::Rc};
extern crate test;
2022-12-11 06:01:27 +00:00
const INPUTS: [&str; 2] = [
include_str!("../inputs/sample.txt"),
include_str!("../inputs/input.txt"),
2022-12-01 05:07:17 +00:00
];
2022-12-11 06:01:27 +00:00
#[derive(Clone)]
struct Monkey {
items: Vec<usize>,
operation: Rc<Box<dyn Fn(usize) -> usize>>,
div_by_test: usize,
if_true: usize,
if_false: usize,
2022-12-07 15:38:47 +00:00
}
2022-12-11 06:47:03 +00:00
fn parse(input: &'static str) -> (Vec<Monkey>, usize) {
let mut lcm = 1;
let output = input
2022-12-11 06:01:27 +00:00
.split("\n\n")
2022-12-10 06:39:28 +00:00
.filter(|c| !c.is_empty())
2022-12-11 06:01:27 +00:00
.map(|set| {
let mut lines = set.lines().skip(1);
let sitems: Vec<usize> = lines
.next()
.unwrap()
.split(',')
.map(|c| {
c.chars()
.filter(|c| c.is_numeric())
.fold(0, |a, x| (a * 10) + (x as u8 - b'0') as usize)
})
.collect();
let op = lines.next().unwrap();
2022-12-11 07:12:06 +00:00
let nop = op[21..]
2022-12-11 06:01:27 +00:00
.bytes()
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
let op = move |old: usize| -> usize {
if op.contains("old * old") {
old * old
} else if op.contains("old +") {
old + nop
} else if op.contains("old *") {
old * nop
} else {
unreachable!()
}
};
2022-12-11 07:12:06 +00:00
let test = lines.next().unwrap()[21..]
2022-12-11 06:01:27 +00:00
.bytes()
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
2022-12-11 07:12:06 +00:00
let true_result = lines.next().unwrap()[29..]
2022-12-11 06:01:27 +00:00
.bytes()
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
2022-12-11 07:12:06 +00:00
let false_result = lines.next().unwrap()[30..]
2022-12-11 06:01:27 +00:00
.bytes()
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
2022-12-11 06:47:03 +00:00
lcm = lcm * test / gcd(lcm, test);
2022-12-11 06:01:27 +00:00
Monkey {
items: sitems,
operation: Rc::new(Box::new(op)),
div_by_test: test,
if_true: true_result,
if_false: false_result,
}
})
2022-12-11 06:47:03 +00:00
.collect();
(output, lcm)
2022-12-09 12:55:45 +00:00
}
fn main() {
for input in INPUTS.iter() {
let output = parse(input);
2022-12-11 06:47:03 +00:00
let score = solution(output.0, output.1);
2022-12-09 12:55:45 +00:00
println!("{}", score);
}
2022-12-01 05:07:17 +00:00
}
2022-12-02 06:41:26 +00:00
2022-12-11 06:47:03 +00:00
fn solution(mut input: Vec<Monkey>, lcm: usize) -> usize {
2022-12-11 06:01:27 +00:00
let mlen = input.len();
let mut activity = vec![0; mlen];
2022-12-10 06:39:28 +00:00
2022-12-11 06:47:03 +00:00
for _ in 0..10000 {
2022-12-11 06:01:27 +00:00
for i in 0..mlen {
let monkey = &input[i].clone();
2022-12-11 07:12:06 +00:00
for &item in monkey.items.iter() {
2022-12-11 06:01:27 +00:00
let newwlevel = (monkey.operation)(item);
2022-12-11 06:47:03 +00:00
let newwlevel = newwlevel % lcm;
2022-12-11 06:47:03 +00:00
if newwlevel % monkey.div_by_test == 0 {
input[monkey.if_true].items.push(newwlevel);
2022-12-11 06:01:27 +00:00
} else {
2022-12-11 06:47:03 +00:00
input[monkey.if_false].items.push(newwlevel);
}
2022-12-11 06:01:27 +00:00
activity[i] += 1;
}
2022-12-11 06:01:27 +00:00
input[i].items.clear();
2022-12-10 06:39:28 +00:00
}
}
2022-12-11 06:01:27 +00:00
activity.select_nth_unstable_by_key(1, |c| Reverse(*c));
2022-12-09 12:55:45 +00:00
2022-12-11 06:01:27 +00:00
activity[0] * activity[1]
2022-12-02 06:41:26 +00:00
}
#[bench]
fn solution_bench(b: &mut test::Bencher) {
b.iter(|| {
2022-12-09 12:55:45 +00:00
let input = parse(INPUTS[1]);
2022-12-11 06:47:03 +00:00
let result = solution(input.0, input.1);
2022-12-02 06:41:26 +00:00
test::black_box(result);
})
}
2022-12-11 06:47:03 +00:00
#[inline]
const fn gcd(a: usize, b: usize) -> usize {
if b == 0 {
return a;
}
gcd(b, a % b)
}