#1116
Medium Concurrency Print zero even odd
Concurrency
65.2% acceptance
Feb 22, 2026
554
372
You have a function printNumber that can be called with an integer parameter and prints it to the console.
For example, calling printNumber(7) prints 7 to the console.
You are given an instance of the class ZeroEvenOdd that has three functions: zero, even, and odd. The same instance of ZeroEvenOdd will be passed to three different threads:
Thread A: calls zero() that should only output 0's.
Thread B: calls even() that should only output even numbers.
Thread C: calls odd() that should only output odd numbers.
Modify the given class to output the series "010203040506..." where the length of the series must be 2n.
Implement the ZeroEvenOdd class:
ZeroEvenOdd(int n) Initializes the object with the number n that represents the numbers that should be printed.
void zero(printNumber) Calls printNumber to output one zero.
void even(printNumber) Calls printNumber to output one even number.
void odd(printNumber) Calls printNumber to output one odd number.
Solution
Rust
Time O(n²)
Space O(n)
use std::sync::Condvar;
// state: 0 = zero's turn, 1 = odd's turn, 2 = even's turn, 3 = done
pub struct ZeroEvenOdd {
n: i32,
// (state, current_number)
inner: Arc<(Mutex<(u8, i32)>, Condvar)>,
}
impl ZeroEvenOdd {
pub fn new(n: i32) -> Self {
ZeroEvenOdd {
n,
inner: Arc::new((Mutex::new((0, 1)), Condvar::new())),
}
}
pub fn zero<F: Fn(i32)>(&self, print_number: F) {
let (lock, cvar) = &*self.inner;
for _ in 1..=self.n {
let mut s = lock.lock().unwrap();
while s.0 != 0 { s = cvar.wait(s).unwrap(); }
print_number(0);
s.0 = if s.1 % 2 == 1 { 1 } else { 2 };
cvar.notify_all();
}
}
pub fn odd<F: Fn(i32)>(&self, print_number: F) {
let (lock, cvar) = &*self.inner;
loop {
let mut s = lock.lock().unwrap();
while s.0 != 1 && s.0 != 3 { s = cvar.wait(s).unwrap(); }
if s.0 == 3 { return; }
let num = s.1;
print_number(num);
s.1 += 1;
s.0 = if s.1 > self.n { 3 } else { 0 };
cvar.notify_all();
if num + 2 > self.n { return; }
}
}
pub fn even<F: Fn(i32)>(&self, print_number: F) {
let (lock, cvar) = &*self.inner;
loop {
let mut s = lock.lock().unwrap();
while s.0 != 2 && s.0 != 3 { s = cvar.wait(s).unwrap(); }
if s.0 == 3 { return; }
let num = s.1;
print_number(num);
s.1 += 1;
s.0 = if s.1 > self.n { 3 } else { 0 };
cvar.notify_all();
if num + 2 > self.n { return; }
}
}
}