Skip to content

1116. Print Zero Even Odd

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// LeetCode doesn't support C++20 yet, so we don't have std::counting_semaphore
// or binary_semaphore.
#include <semaphore.h>

class ZeroEvenOdd {
 public:
  ZeroEvenOdd(int n) : n(n) {
    sem_init(&zeroSemaphore, /*pshared=*/0, /*value=*/1);
    sem_init(&evenSemaphore, /*pshared=*/0, /*value=*/0);
    sem_init(&oddSemaphore, /*pshared=*/0, /*value=*/0);
  }

  ~ZeroEvenOdd() {
    sem_destroy(&zeroSemaphore);
    sem_destroy(&evenSemaphore);
    sem_destroy(&oddSemaphore);
  }

  // printNumber(x) outputs "x", where x is an integer.
  void zero(function<void(int)> printNumber) {
    for (int i = 0; i < n; ++i) {
      sem_wait(&zeroSemaphore);
      printNumber(0);
      sem_post(&(i % 2 == 0 ? oddSemaphore : evenSemaphore));
    }
  }

  void even(function<void(int)> printNumber) {
    for (int i = 2; i <= n; i += 2) {
      sem_wait(&evenSemaphore);
      printNumber(i);
      sem_post(&zeroSemaphore);
    }
  }

  void odd(function<void(int)> printNumber) {
    for (int i = 1; i <= n; i += 2) {
      sem_wait(&oddSemaphore);
      printNumber(i);
      sem_post(&zeroSemaphore);
    }
  }

 private:
  const int n;
  sem_t zeroSemaphore;
  sem_t evenSemaphore;
  sem_t oddSemaphore;
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class ZeroEvenOdd {
  public ZeroEvenOdd(int n) {
    this.n = n;
  }

  // printNumber.accept(x) outputs "x", where x is an integer.
  public void zero(IntConsumer printNumber) throws InterruptedException {
    for (int i = 0; i < n; ++i) {
      zeroSemaphore.acquire();
      printNumber.accept(0);
      (i % 2 == 0 ? oddSemaphore : evenSemaphore).release();
    }
  }

  public void even(IntConsumer printNumber) throws InterruptedException {
    for (int i = 2; i <= n; i += 2) {
      evenSemaphore.acquire();
      printNumber.accept(i);
      zeroSemaphore.release();
    }
  }

  public void odd(IntConsumer printNumber) throws InterruptedException {
    for (int i = 1; i <= n; i += 2) {
      oddSemaphore.acquire();
      printNumber.accept(i);
      zeroSemaphore.release();
    }
  }

  private int n;
  private Semaphore zeroSemaphore = new Semaphore(1);
  private Semaphore evenSemaphore = new Semaphore(0);
  private Semaphore oddSemaphore = new Semaphore(0);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from threading import Semaphore


class ZeroEvenOdd:
  def __init__(self, n):
    self.n = n
    self.zeroSemaphore = Semaphore(1)
    self.evenSemaphore = Semaphore(0)
    self.oddSemaphore = Semaphore(0)

  # printNumber(x) outputs "x", where x is an integer.
  def zero(self, printNumber: 'Callable[[int], None]') -> None:
    for i in range(self.n):
      self.zeroSemaphore.acquire()
      printNumber(0)
      (self.oddSemaphore if i & 2 == 0 else self.evenSemaphore).release()

  def even(self, printNumber: 'Callable[[int], None]') -> None:
    for i in range(2, self.n + 1, 2):
      self.evenSemaphore.acquire()
      printNumber(i)
      self.zeroSemaphore.release()

  def odd(self, printNumber: 'Callable[[int], None]') -> None:
    for i in range(1, self.n + 1, 2):
      self.oddSemaphore.acquire()
      printNumber(i)
      self.zeroSemaphore.release()