Today's challenge was about multithreading. To be honest, I have no idea how multithreading works, so I struggled to understand the question not only about finding the solution.

The challenge title was “Fizz Buzz Multithreaded." Let me give you all the question descriptions so that you can understand it better. If you need more description about the challenge, you can find more detail here.

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 only 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.

The solution

Before writing any code, I googled how multithreading works. After I understood how it works, I tried to fool the system by storing the instance of the functions (i.e., fizz, buzz, fizzbuzz, number) on an instance variable called functions to call them later. Here is the code snippet to clarify what I mean:

def number(self, printNumber: 'Callable[[int], None]') -> None:
   for number in range(1, self.n + 1):
       if number % 3 != 0 and number % 5 != 0:
           self.callResults[number] = printNumber
           
   time.sleep(0.1)
   self.checkAndFinish()
   
def checkAndFinish(self):
   if len(self.callResults) == self.n:
       for number, function in self.callResults.items():
           if number % 3 != 0 and number % 5 != 0:
               function(number)
           else:
               function()

All the codes are similar for the functions, the only difference is the condition. After every function is executed it will sleep for 0.1 second and call checkAndFinish function. The problem with this approach is, I can't call the function while being inside another thread.

I spent almost 2 and a half hours and was about to give up, but in my final trial, I found some code snippets that led me to the solution.

The Result

Runtime: 40 ms, faster than 91.57% of Python3 online submissions for Fizz Buzz Multithreaded.

Memory Usage: 14.6 MB, less than 55.56% of Python3 online submissions for Fizz Buzz Multithreaded.