Skip to content

Commit

Permalink
[Rust/2023/20] Improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
Defelo committed Dec 20, 2023
1 parent 3632b0e commit c9d5f57
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
24 changes: 15 additions & 9 deletions Rust/2023/20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::collections::VecDeque;

use aoc::tuples::TupleExt;
use aoc::{iter_ext::IterExt, tuples::TupleExt};
use itertools::Itertools;
use num::Integer;
use rustc_hash::FxHashMap;
Expand Down Expand Up @@ -86,7 +86,10 @@ fn setup(input: &str) -> Input {
Input { modules, start, rx }
}

fn push_button(input: &Input, state: &mut [bool]) -> impl Iterator<Item = (usize, bool)> {
fn push_button<'a>(
input: &'a Input,
state: &'a mut [bool],
) -> impl Iterator<Item = (usize, bool)> + 'a {
let mut queue = input
.start
.iter()
Expand All @@ -112,24 +115,27 @@ fn push_button(input: &Input, state: &mut [bool]) -> impl Iterator<Item = (usize

Some((p, k))
})
.collect_vec()
.into_iter()
}

fn part1(input: &Input) -> usize {
const N: usize = 1000;
let mut state = vec![false; input.modules.len()];
let (lo, hi) = (0..N)
.flat_map(|_| push_button(input, &mut state).map(|(_, k)| k))
.fold((N, 0), |(lo, hi), k| (lo + !k as usize, hi + k as usize));
let (lo, hi) = (0..1000)
.map(|_| {
push_button(input, &mut state)
.map(|(_, k)| k)
.fold((1, 0), |(lo, hi), k| (lo + !k as usize, hi + k as usize))
})
.fold((0, 0), |acc, x| (acc.0 + x.0, acc.1 + x.1));
lo * hi
}

fn part2(input: &Input) -> usize {
let rx = &input.modules[input.rx];
let mut state = vec![false; input.modules.len()];
(1..)
.filter(|_| push_button(input, &mut state).any(|(p, k)| !k && rx.inputs.contains(&p)))
.filter(|_| {
push_button(input, &mut state).any_consume(|(p, k)| !k && rx.inputs.contains(&p))
})
.take(rx.inputs.len())
.reduce(|a, b| a.lcm(&b))
.unwrap()
Expand Down
28 changes: 28 additions & 0 deletions Rust/lib/iter_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ pub trait IterExt: Iterator {
where
Self: Sized,
Self::Item: IntoIterator;

fn all_consume<P>(self, predicate: P) -> bool
where
Self: Sized,
P: FnMut(Self::Item) -> bool;

fn any_consume<P>(self, predicate: P) -> bool
where
Self: Sized,
P: FnMut(Self::Item) -> bool;
}

impl<I> IterExt for I
Expand Down Expand Up @@ -47,6 +57,24 @@ where
iterators: self.map(|it| it.into_iter()).collect(),
}
}

fn all_consume<P>(self, mut predicate: P) -> bool
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
{
#[allow(clippy::unnecessary_fold)]
self.fold(true, |acc, x| acc && predicate(x))
}

fn any_consume<P>(self, mut predicate: P) -> bool
where
Self: Sized,
P: FnMut(Self::Item) -> bool,
{
#[allow(clippy::unnecessary_fold)]
self.fold(false, |acc, x| acc || predicate(x))
}
}

pub struct TakeWhileInclusive<I, P> {
Expand Down

0 comments on commit c9d5f57

Please sign in to comment.