Skip to content

Latest commit

 

History

History
132 lines (105 loc) · 5.77 KB

File metadata and controls

132 lines (105 loc) · 5.77 KB

1195. Fizz Buzz Multithreaded (Medium)

Date and Time: Jun 15, 2026

Link: https://leetcode.com/problems/fizz-buzz-multithreaded/


Question:

You have the four functions:

  • printFizz that prints the word "fizz" to the console,
  • printBuzz that prints the word "buzz" to the console,
  • printFizzBuzz that prints the word "fizzbuzz" to the console, and
  • printNumber that prints a given integer to the console.

You are given an instance of the class FizzBuzz that has four functions: fizz, buzz, fizzbuzz and number. The same instance of FizzBuzz will be passed to four different threads:

  • Thread A: calls fizz() that should output the word "fizz".
  • Thread B: calls buzz() that should output the word "buzz".
  • Thread C: calls fizzbuzz() that should output the word "fizzbuzz".
  • Thread D: calls number() that should output the integers.

Modify the given class to output the series [1, 2, "fizz", 4, "buzz", ...] where the ith token (1-indexed) of the series is:

  • "fizzbuzz" if i is divisible by 3 and 5,
  • "fizz" if i is divisible by 3 and not 5,
  • "buzz" if i is divisible by 5 and not 3, or
  • i if i is not divisible by 3 or 5.

Implement the FizzBuzz class.


Example 1:

Input: n = 15
Output: [1,2,"fizz",4,"buzz","fizz",7,8,"fizz","buzz",11,"fizz",13,14,"fizzbuzz"]

Example 2:

Input: n = 5
Output: [1,2,"fizz",4,"buzz"]


Constraints:

  • 1 <= n <= 50

Walk-through:

Use a shared Condition variable with a shared counter cur. Each thread holds the lock, waits on the Condition until cur satisfies its specific divisibility rule, prints, increments cur, and calls notify_all() to wake the other threads.

  • fizz: waits while cur % 3 != 0 or cur % 5 == 0 (not fizz-only).
  • buzz: waits while cur % 5 != 0 or cur % 3 == 0 (not buzz-only).
  • fizzbuzz: waits while cur % 3 != 0 or cur % 5 != 0 (not divisible by 15).
  • number: waits while cur % 3 == 0 or cur % 5 == 0 (not a plain number).

After each thread finishes its turn it calls notify_all() so the correct next thread can wake up. Each method also checks if self.cur > self.n after the inner wait loop to exit cleanly.


Python Solution:

from threading import Lock, Semaphore, Condition

class FizzBuzz:
    def __init__(self, n: int):
        self.n = n
        self.cur = 1
        self.cv = Condition()

    # printFizz() outputs "fizz"
    def fizz(self, printFizz: 'Callable[[], None]') -> None:
    	# i is divisible by 3 and not 5
        with self.cv:
            while self.cur <= self.n:
                while self.cur <= self.n and (self.cur % 3 != 0 or self.cur % 5 == 0):
                    self.cv.wait()
                # Case to close
                if self.cur > self.n:
                    return
                printFizz()
                self.cur += 1
                self.cv.notify_all()

    # printBuzz() outputs "buzz"
    def buzz(self, printBuzz: 'Callable[[], None]') -> None:
        # i is divisible by 5 and not 3
        with self.cv:
            while self.cur <= self.n:
                while self.cur <= self.n and (not self.cur % 5 == 0 or self.cur % 3 == 0):
                    self.cv.wait()
                # Case to close
                if self.cur > self.n:
                    return
                printBuzz()
                self.cur += 1
                self.cv.notify_all()

    # printFizzBuzz() outputs "fizzbuzz"
    def fizzbuzz(self, printFizzBuzz: 'Callable[[], None]') -> None:
        # Only wakes up when n % 15
        with self.cv:
            while self.cur <= self.n:
                while self.cur <= self.n and (not self.cur % 3 == 0 or not self.cur % 5 == 0):
                    self.cv.wait()
                # When finishes, we should wake up other threads and close
                if self.cur > self.n:
                    return
                # Otherwise, we are at index i % 15 == 0
                printFizzBuzz()
                self.cur += 1
                self.cv.notify_all()

    # printNumber(x) outputs "x", where x is an integer.
    def number(self, printNumber: 'Callable[[int], None]') -> None:
        # When other threads are sleeping (i is not divisible by 3 or 5)
        with self.cv:
            while self.cur <= self.n:
                while self.cur <= self.n and (self.cur % 3 == 0 or self.cur % 5 == 0):
                    self.cv.wait()
                if self.cur > self.n:
                    return
                printNumber(self.cur)
                self.cur += 1
                self.cv.notify_all()

Time Complexity: $O(n)$, each integer from 1 to n is printed exactly once.
Space Complexity: $O(1)$, only the shared counter and condition variable.


CC BY-NC-SABY: credit must be given to the creatorNC: Only noncommercial uses of the work are permittedSA: Adaptations must be shared under the same terms