1
0

Optimized day 11 part 2 by replacing Rc<Box<dyn Fn>> with a enum

This commit is contained in:
Ishan Jain 2022-12-11 13:28:17 +05:30
parent a31254fc6a
commit 3b92d6f3ed
Signed by: ishan
GPG Key ID: 0506DB2A1CC75C27

View File

@ -1,6 +1,6 @@
#![feature(test)] #![feature(test)]
use std::{cmp::Reverse, rc::Rc}; use std::cmp::Reverse;
extern crate test; extern crate test;
const INPUTS: [&str; 2] = [ const INPUTS: [&str; 2] = [
@ -11,12 +11,29 @@ const INPUTS: [&str; 2] = [
#[derive(Clone)] #[derive(Clone)]
struct Monkey { struct Monkey {
items: Vec<usize>, items: Vec<usize>,
operation: Rc<Box<dyn Fn(usize) -> usize>>, operation: Operation,
div_by_test: usize, div_by_test: usize,
if_true: usize, if_true: usize,
if_false: usize, if_false: usize,
} }
#[derive(Clone, Debug, Copy)]
enum Operation {
MulOld,
MulNop(usize),
AddNop(usize),
}
impl Operation {
fn apply(&self, v: usize) -> usize {
match self {
Operation::MulOld => v * v,
Operation::MulNop(i) => v * i,
Operation::AddNop(i) => v + i,
}
}
}
fn parse(input: &'static str) -> (Vec<Monkey>, usize) { fn parse(input: &'static str) -> (Vec<Monkey>, usize) {
let mut lcm = 1; let mut lcm = 1;
let output = input let output = input
@ -25,32 +42,28 @@ fn parse(input: &'static str) -> (Vec<Monkey>, usize) {
.map(|set| { .map(|set| {
let mut lines = set.lines().skip(1); let mut lines = set.lines().skip(1);
let sitems: Vec<usize> = lines let sitems: Vec<usize> = lines.next().unwrap()[18..]
.next()
.unwrap()
.split(',') .split(',')
.map(|c| { .map(|c| {
c.chars() c.bytes()
.filter(|c| c.is_numeric()) .filter(|c| (b'0'..=b'9').contains(c))
.fold(0, |a, x| (a * 10) + (x as u8 - b'0') as usize) .fold(0, |a, x| (a * 10) + (x - b'0') as usize)
}) })
.collect(); .collect();
let op = lines.next().unwrap(); let op = match lines.next().unwrap()[23..].split_at(1) {
let nop = op[21..] ("*", " old") => Operation::MulOld,
("+", v) => Operation::AddNop(
v[1..]
.bytes() .bytes()
.fold(0, |a, x| (a * 10) + (x - b'0') as usize); .fold(0, |a, x| (a * 10) + (x - b'0') as usize),
),
let op = move |old: usize| -> usize { ("*", v) => Operation::MulNop(
if op.contains("old * old") { v[1..]
old * old .bytes()
} else if op.contains("old +") { .fold(0, |a, x| (a * 10) + (x - b'0') as usize),
old + nop ),
} else if op.contains("old *") { (_, _) => unreachable!(),
old * nop
} else {
unreachable!()
}
}; };
let test = lines.next().unwrap()[21..] let test = lines.next().unwrap()[21..]
@ -69,7 +82,7 @@ fn parse(input: &'static str) -> (Vec<Monkey>, usize) {
Monkey { Monkey {
items: sitems, items: sitems,
operation: Rc::new(Box::new(op)), operation: op,
div_by_test: test, div_by_test: test,
if_true: true_result, if_true: true_result,
if_false: false_result, if_false: false_result,
@ -94,10 +107,11 @@ fn solution(mut input: Vec<Monkey>, lcm: usize) -> usize {
for _ in 0..10000 { for _ in 0..10000 {
for i in 0..mlen { for i in 0..mlen {
let monkey = &input[i].clone(); let monkey = input[i].clone();
activity[i] += monkey.items.len();
for &item in monkey.items.iter() { for &item in monkey.items.iter() {
let newwlevel = (monkey.operation)(item); let newwlevel = monkey.operation.apply(item);
let newwlevel = newwlevel % lcm; let newwlevel = newwlevel % lcm;
if newwlevel % monkey.div_by_test == 0 { if newwlevel % monkey.div_by_test == 0 {
@ -105,8 +119,6 @@ fn solution(mut input: Vec<Monkey>, lcm: usize) -> usize {
} else { } else {
input[monkey.if_false].items.push(newwlevel); input[monkey.if_false].items.push(newwlevel);
} }
activity[i] += 1;
} }
input[i].items.clear(); input[i].items.clear();
} }