Skip to content

1195. Fizz Buzz Multithreaded

 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// LeetCode doesn't support C++20 yet, so we don't have std::counting_semaphore
// or binary_semaphore.
#include <semaphore.h>

class FizzBuzz {
 public:
  FizzBuzz(int n) : n(n) {
    sem_init(&fizzSemaphore, /*pshared=*/0, /*value=*/0);
    sem_init(&buzzSemaphore, /*pshared=*/0, /*value=*/0);
    sem_init(&fizzbuzzSemaphore, /*pshared=*/0, /*value=*/0);
    sem_init(&numberSemaphore, /*pshared=*/0, /*value=*/1);
  }

  ~FizzBuzz() {
    sem_destroy(&fizzSemaphore);
    sem_destroy(&buzzSemaphore);
    sem_destroy(&fizzbuzzSemaphore);
    sem_destroy(&numberSemaphore);
  }

  // printFizz() outputs "fizz".
  void fizz(function<void()> printFizz) {
    for (int i = 1; i <= n; ++i)
      if (i % 3 == 0 && i % 15 != 0) {
        sem_wait(&fizzSemaphore);
        printFizz();
        sem_post(&numberSemaphore);
      }
  }

  // printBuzz() outputs "buzz".
  void buzz(function<void()> printBuzz) {
    for (int i = 1; i <= n; ++i)
      if (i % 5 == 0 && i % 15 != 0) {
        sem_wait(&buzzSemaphore);
        printBuzz();
        sem_post(&numberSemaphore);
      }
  }

  // printFizzBuzz() outputs "fizzbuzz".
  void fizzbuzz(function<void()> printFizzBuzz) {
    for (int i = 1; i <= n; ++i)
      if (i % 15 == 0) {
        sem_wait(&fizzbuzzSemaphore);
        printFizzBuzz();
        sem_post(&numberSemaphore);
      }
  }

  // printNumber(x) outputs "x", where x is an integer.
  void number(function<void(int)> printNumber) {
    for (int i = 1; i <= n; ++i) {
      sem_wait(&numberSemaphore);
      if (i % 15 == 0)
        sem_post(&fizzbuzzSemaphore);
      else if (i % 3 == 0)
        sem_post(&fizzSemaphore);
      else if (i % 5 == 0)
        sem_post(&buzzSemaphore);
      else {
        printNumber(i);
        sem_post(&numberSemaphore);
      }
    }
  }

 private:
  const int n;
  sem_t fizzSemaphore;
  sem_t buzzSemaphore;
  sem_t fizzbuzzSemaphore;
  sem_t numberSemaphore;
};
 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
50
51
52
53
54
55
56
57
58
class FizzBuzz {
  public FizzBuzz(int n) {
    this.n = n;
  }

  // printFizz.run() outputs "fizz".
  public void fizz(Runnable printFizz) throws InterruptedException {
    for (int i = 1; i <= n; ++i)
      if (i % 3 == 0 && i % 15 != 0) {
        fizzSemaphore.acquire();
        printFizz.run();
        numberSemaphore.release();
      }
  }

  // printBuzz.run() outputs "buzz".
  public void buzz(Runnable printBuzz) throws InterruptedException {
    for (int i = 1; i <= n; ++i)
      if (i % 5 == 0 && i % 15 != 0) {
        buzzSemaphore.acquire();
        printBuzz.run();
        numberSemaphore.release();
      }
  }

  // printFizzBuzz.run() outputs "fizzbuzz".
  public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {
    for (int i = 1; i <= n; ++i)
      if (i % 15 == 0) {
        fizzbuzzSemaphore.acquire();
        printFizzBuzz.run();
        numberSemaphore.release();
      }
  }

  // printNumber.accept(x) outputs "x", where x is an integer.
  public void number(IntConsumer printNumber) throws InterruptedException {
    for (int i = 1; i <= n; ++i) {
      numberSemaphore.acquire();
      if (i % 15 == 0)
        fizzbuzzSemaphore.release();
      else if (i % 3 == 0)
        fizzSemaphore.release();
      else if (i % 5 == 0)
        buzzSemaphore.release();
      else {
        printNumber.accept(i);
        numberSemaphore.release();
      }
    }
  }

  private int n;
  private Semaphore fizzSemaphore = new Semaphore(0);
  private Semaphore buzzSemaphore = new Semaphore(0);
  private Semaphore fizzbuzzSemaphore = new Semaphore(0);
  private Semaphore numberSemaphore = new Semaphore(1);
}
 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
from threading import Semaphore


class FizzBuzz:
  def __init__(self, n: int):
    self.n = n
    self.fizzSemaphore = Semaphore(0)
    self.buzzSemaphore = Semaphore(0)
    self.fizzbuzzSemaphore = Semaphore(0)
    self.numberSemaphore = Semaphore(1)

  # printFizz() outputs "fizz"
  def fizz(self, printFizz: 'Callable[[], None]') -> None:
    for i in range(1, self.n + 1):
      if i % 3 == 0 and i % 15 != 0:
        self.fizzSemaphore.acquire()
        printFizz()
        self.numberSemaphore.release()

  # printBuzz() outputs "buzz"
  def buzz(self, printBuzz: 'Callable[[], None]') -> None:
    for i in range(1, self.n + 1):
      if i % 5 == 0 and i % 15 != 0:
        self.buzzSemaphore.acquire()
        printBuzz()
        self.numberSemaphore.release()

  # printFizzBuzz() outputs "fizzbuzz"
  def fizzbuzz(self, printFizzBuzz: 'Callable[[], None]') -> None:
    for i in range(1, self.n + 1):
      if i % 15 == 0:
        self.fizzbuzzSemaphore.acquire()
        printFizzBuzz()
        self.numberSemaphore.release()

  # printNumber(x) outputs "x", where x is an integer.
  def number(self, printNumber: 'Callable[[int], None]') -> None:
    for i in range(1, self.n + 1):
      self.numberSemaphore.acquire()
      if i % 15 == 0:
        self.fizzbuzzSemaphore.release()
      elif i % 3 == 0:
        self.fizzSemaphore.release()
      elif i % 5 == 0:
        self.buzzSemaphore.release()
      else:
        printNumber(i)
        self.numberSemaphore.release()