Skip to content

Commit 725127d

Browse files
committed
Tidy threading
1 parent 10f7542 commit 725127d

File tree

1 file changed

+16
-36
lines changed

1 file changed

+16
-36
lines changed

src/year2022/day11.rs

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
//! [`iter_unsigned`]: ParseOps::iter_unsigned
4444
use crate::util::parse::*;
4545
use crate::util::thread::*;
46-
use std::sync::Mutex;
46+
47+
type Pair = (usize, u64);
4748

4849
pub struct Monkey {
4950
items: Vec<u64>,
@@ -59,19 +60,8 @@ pub enum Operation {
5960
Add(u64),
6061
}
6162

62-
type Pair = (usize, u64);
6363
type Business = [u64; 8];
6464

65-
struct Shared<'a> {
66-
monkeys: &'a [Monkey],
67-
mutex: Mutex<Exclusive>,
68-
}
69-
70-
struct Exclusive {
71-
pairs: Vec<Pair>,
72-
business: Business,
73-
}
74-
7565
/// Extract each Monkey's info from the flavor text. With the exception of the lines starting
7666
/// `Operation` we are only interested in the numbers on each line.
7767
pub fn parse(input: &str) -> Vec<Monkey> {
@@ -102,7 +92,7 @@ pub fn part2(input: &[Monkey]) -> u64 {
10292
}
10393

10494
/// Convenience wrapper to reuse common logic between part one and two.
105-
fn solve(monkeys: &[Monkey], play: impl Fn(&[Monkey], Vec<Pair>) -> Business) -> u64 {
95+
fn solve(monkeys: &[Monkey], play: impl Fn(&[Monkey], &[Pair]) -> Business) -> u64 {
10696
let mut pairs = Vec::new();
10797

10898
for (from, monkey) in monkeys.iter().enumerate() {
@@ -111,16 +101,16 @@ fn solve(monkeys: &[Monkey], play: impl Fn(&[Monkey], Vec<Pair>) -> Business) ->
111101
}
112102
}
113103

114-
let mut business = play(monkeys, pairs);
104+
let mut business = play(monkeys, &pairs);
115105
business.sort_unstable();
116106
business.iter().rev().take(2).product()
117107
}
118108

119109
/// Play 20 rounds dividing the worry level by 3 each inspection.
120-
fn sequential(monkeys: &[Monkey], pairs: Vec<Pair>) -> Business {
110+
fn sequential(monkeys: &[Monkey], pairs: &[Pair]) -> Business {
121111
let mut business = [0; 8];
122112

123-
for pair in pairs {
113+
for &pair in pairs {
124114
let extra = play(monkeys, 20, |x| x / 3, pair);
125115
business.iter_mut().enumerate().for_each(|(i, b)| *b += extra[i]);
126116
}
@@ -129,31 +119,21 @@ fn sequential(monkeys: &[Monkey], pairs: Vec<Pair>) -> Business {
129119
}
130120

131121
/// Play 10,000 rounds adjusting the worry level modulo the product of all the monkey's test values.
132-
fn parallel(monkeys: &[Monkey], pairs: Vec<Pair>) -> Business {
133-
let shared = Shared { monkeys, mutex: Mutex::new(Exclusive { pairs, business: [0; 8] }) };
134-
122+
fn parallel(monkeys: &[Monkey], pairs: &[Pair]) -> Business {
135123
// Use as many cores as possible to parallelize the calculation.
136-
spawn(|| worker(&shared));
124+
let result = spawn_parallel_iterator(pairs, |iter| worker(monkeys, iter));
137125

138-
shared.mutex.into_inner().unwrap().business
126+
let mut business = [0; 8];
127+
for extra in result.into_iter().flatten() {
128+
business.iter_mut().zip(extra).for_each(|(b, e)| *b += e);
129+
}
130+
business
139131
}
140132

141133
/// Multiple worker functions are executed in parallel, one per thread.
142-
fn worker(shared: &Shared<'_>) {
143-
let product: u64 = shared.monkeys.iter().map(|m| m.test).product();
144-
145-
loop {
146-
// Take an item from the queue until empty, using the mutex to allow access
147-
// to a single thread at a time.
148-
let Some(pair) = shared.mutex.lock().unwrap().pairs.pop() else {
149-
break;
150-
};
151-
152-
let extra = play(shared.monkeys, 10000, |x| x % product, pair);
153-
154-
let mut exclusive = shared.mutex.lock().unwrap();
155-
exclusive.business.iter_mut().enumerate().for_each(|(i, b)| *b += extra[i]);
156-
}
134+
fn worker(monkeys: &[Monkey], iter: ParIter<'_, Pair>) -> Vec<Business> {
135+
let product: u64 = monkeys.iter().map(|m| m.test).product();
136+
iter.map(|&pair| play(monkeys, 10000, |x| x % product, pair)).collect()
157137
}
158138

159139
/// Play an arbitrary number of rounds for a single item.

0 commit comments

Comments
 (0)