Date and Time: Feb 19, 2025, 00:15 (EST)
Link: https://leetcode.com/problems/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)
prints7
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 output0
'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 numbern
that represents the numbers that should be printed.void zero(printNumber)
: CallsprintNumber
to output one zero.void even(printNumber)
: CallsprintNumber
to output one even number.void odd(printNumber)
: CallsprintNumber
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"
1 <= n <= 1000
-
Define three semophores for
zero(), even(), odd()
. We initialize the semophore ofzero()
with priority1
(sem_init(&sem_zero, 0, 1);
), so we can always runsem_zero
with higher priority. -
We start at
i = 1
, and each time it only increments by1
inzero()
. We identify if we should callodd()
next oreven()
next byi
, ifi
is odd, we unlocksem_odd
to executeodd()
, otherwise, we unlocksem_even
foreven()
. -
odd()
starts withi = 1
, self-increment by2
each time. So we can alwaysprintNumber()
the odd number. After we print, we unlocksem_zero
again to back tozero()
. Same logic applies toeven()
.
class ZeroEvenOdd {
private:
int n;
sem_t sem_zero;
sem_t sem_even;
sem_t sem_odd;
public:
ZeroEvenOdd(int n) {
this->n = n;
sem_init(&sem_zero, 0, 1); // Give priority to semophore_zero to start first
sem_init(&sem_even, 0, 0);
sem_init(&sem_odd, 0, 0);
}
// printNumber(x) outputs "x", where x is an integer.
void zero(function<void(int)> printNumber) {
for (int i = 1; i < n+1; i++) {
// Wait to be unlocked
sem_wait(&sem_zero);
printNumber(0);
// Identify to unlock odd or even base on i
if (i % 2 == 1) {
sem_post(&sem_odd);
} else {
sem_post(&sem_even);
}
}
}
void even(function<void(int)> printNumber) {
for (int i = 2; i < n+1; i+=2) {
sem_wait(&sem_even); // Wait to be unlocked
printNumber(i);
sem_post(&sem_zero); // Get back to zero()
}
}
void odd(function<void(int)> printNumber) {
for (int i = 1; i < n+1; i+=2) {
sem_wait(&sem_odd);
printNumber(i);
sem_post(&sem_zero);
}
}
};