Fizz Buzz Multithreaded

medium concurrency threads synchronization

Problem

You have a class with four functions running on separate threads for numbers 1..n: fizz() prints "fizz" when a number is divisible by 3 (and not 5), buzz() prints "buzz" when divisible by 5 (and not 3), fizzbuzz() prints "fizzbuzz" when divisible by both 3 and 5, and number() prints the value otherwise. The four threads run concurrently, but the combined output must equal the single-threaded FizzBuzz sequence for 1..n.

Inputn = 5
Output1, 2, fizz, 4, buzz
Each thread waits its turn; only the eligible thread prints for the current number, then hands the turn to the next number.

from threading import Lock

class FizzBuzz:
    def __init__(self, n):
        self.n = n
        self.cur = 1
        self.lock = Lock()

    def _try(self, want, do):
        while True:
            with self.lock:
                if self.cur > self.n:
                    return
                d3 = self.cur % 3 == 0
                d5 = self.cur % 5 == 0
                kind = "fb" if d3 and d5 else "f" if d3 else "b" if d5 else "n"
                if kind == want:
                    do(self.cur)
                    self.cur += 1

    def fizz(self, printFizz):
        self._try("f", lambda x: printFizz())

    def buzz(self, printBuzz):
        self._try("b", lambda x: printBuzz())

    def fizzbuzz(self, printFizzBuzz):
        self._try("fb", lambda x: printFizzBuzz())

    def number(self, printNumber):
        self._try("n", lambda x: printNumber(x))
class FizzBuzz {
  constructor(n) {
    this.n = n;
    this.cur = 1;
  }
  kind(x) {
    const d3 = x % 3 === 0, d5 = x % 5 === 0;
    return d3 && d5 ? "fb" : d3 ? "f" : d5 ? "b" : "n";
  }
  // Each thread loops, acting only on its own turn.
  step(want, emit) {
    while (this.cur <= this.n) {
      if (this.kind(this.cur) === want) {
        emit(this.cur);
        this.cur++;
      }
    }
  }
  fizz(printFizz) { this.step("f", () => printFizz()); }
  buzz(printBuzz) { this.step("b", () => printBuzz()); }
  fizzbuzz(printFizzBuzz) { this.step("fb", () => printFizzBuzz()); }
  number(printNumber) { this.step("n", (x) => printNumber(x)); }
}
import java.util.concurrent.Semaphore;

class FizzBuzz {
    private int n;
    private int cur = 1;
    private final Object lock = new Object();

    public FizzBuzz(int n) { this.n = n; }

    private String kind(int x) {
        boolean d3 = x % 3 == 0, d5 = x % 5 == 0;
        return d3 && d5 ? "fb" : d3 ? "f" : d5 ? "b" : "n";
    }

    private void run(String want, Runnable doIt) {
        while (true) {
            synchronized (lock) {
                if (cur > n) return;
                if (kind(cur).equals(want)) { doIt.run(); cur++; }
            }
        }
    }

    public void fizz(Runnable printFizz) { run("f", printFizz); }
    public void buzz(Runnable printBuzz) { run("b", printBuzz); }
    public void fizzbuzz(Runnable printFizzBuzz) { run("fb", printFizzBuzz); }
    public void number(java.util.function.IntConsumer printNumber) {
        while (true) {
            synchronized (lock) {
                if (cur > n) return;
                if (kind(cur).equals("n")) { printNumber.accept(cur); cur++; }
            }
        }
    }
}
#include <mutex>
#include <functional>

class FizzBuzz {
    int n, cur = 1;
    std::mutex m;

    std::string kind(int x) {
        bool d3 = x % 3 == 0, d5 = x % 5 == 0;
        return d3 && d5 ? "fb" : d3 ? "f" : d5 ? "b" : "n";
    }
    void run(const std::string& want, std::function<void(int)> emit) {
        while (true) {
            std::lock_guard<std::mutex> g(m);
            if (cur > n) return;
            if (kind(cur) == want) { emit(cur); cur++; }
        }
    }
public:
    FizzBuzz(int n) : n(n) {}
    void fizz(std::function<void()> pf) { run("f", [&](int){ pf(); }); }
    void buzz(std::function<void()> pb) { run("b", [&](int){ pb(); }); }
    void fizzbuzz(std::function<void()> pfb) { run("fb", [&](int){ pfb(); }); }
    void number(std::function<void(int)> pn) { run("n", pn); }
};
Time: O(n) Space: O(1)