1116. Print Zero Even Odd

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.

Example 1:

```Input: n = 2
Output: "0102"
Explanation: There are three threads being fired asynchronously.
One of them calls zero(), the other calls even(), and the last one calls odd().
"0102" is the correct output.
```

Example 2:

```Input: n = 5
Output: "0102030405"
```

Constraints:

• `1 <= n <= 1000`

1116. Print Zero Even Odd
``````use std::sync::Condvar;
use std::sync::Mutex;

struct ZeroEvenOdd {
state: (Mutex<i32>, Condvar),
n: i32,
}

impl ZeroEvenOdd {
fn new(n: i32) -> Self {
let state = (Mutex::new(0), Condvar::new());
ZeroEvenOdd { state, n }
}

fn zero(&self, print_number: impl Fn(i32)) {
self.job(true, print_number, |state| {
!(*state == 2 * self.n || *state % 2 == 0)
});
}

fn odd(&self, print_number: impl Fn(i32)) {
self.job(false, print_number, |state| {
!(*state == 2 * self.n || *state % 2 == 1 && *state % 4 == 1)
});
}

fn even(&self, print_number: impl Fn(i32)) {
self.job(false, print_number, |state| {
!(*state == 2 * self.n || *state % 2 == 1 && *state % 4 == 3)
});
}

fn job(
&self,
zero: bool,
print_number: impl Fn(i32),
condition: impl FnMut(&mut i32) -> bool + Copy,
) {
loop {
let (lock, cvar) = &self.state;
let mut g = cvar.wait_while(lock.lock().unwrap(), condition).unwrap();
if *g == 2 * self.n {
break;
}
print_number(if zero { 0 } else { (*g + 1) / 2 });
*g += 1;
cvar.notify_all();
}
}
}

#[test]
fn test() {
use std::sync::mpsc::channel;
use std::sync::Arc;

let zero_even_odd = Arc::new(ZeroEvenOdd::new(5));
let (tx, rx) = channel();

for i in 0..3 {
let zero_even_odd = zero_even_odd.clone();
let tx = tx.clone();
pool.execute(move || match i {
0 => zero_even_odd.zero(|x| tx.send(x.to_string()).unwrap()),
1 => zero_even_odd.even(|x| tx.send(x.to_string()).unwrap()),
2 => zero_even_odd.odd(|x| tx.send(x.to_string()).unwrap()),
_ => panic!(),
});
}
pool.join();
let nums: Vec<String> = rx.try_iter().collect();
let res = nums.join("");
let ans = "0102030405".to_string();
assert_eq!(res, ans);
}
``````