Optimized day 11 part 2 by replacing Rc<Box<dyn Fn>> with a enum
This commit is contained in:
parent
a31254fc6a
commit
3b92d6f3ed
68
src/main.rs
68
src/main.rs
|
@ -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,
|
||||||
.bytes()
|
("+", v) => Operation::AddNop(
|
||||||
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
|
v[1..]
|
||||||
|
.bytes()
|
||||||
let op = move |old: usize| -> usize {
|
.fold(0, |a, x| (a * 10) + (x - b'0') as usize),
|
||||||
if op.contains("old * old") {
|
),
|
||||||
old * old
|
("*", v) => Operation::MulNop(
|
||||||
} else if op.contains("old +") {
|
v[1..]
|
||||||
old + nop
|
.bytes()
|
||||||
} else if op.contains("old *") {
|
.fold(0, |a, x| (a * 10) + (x - b'0') as usize),
|
||||||
old * nop
|
),
|
||||||
} else {
|
(_, _) => unreachable!(),
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user