Python 3 | 5 Approaches (Condition, Event, Lock/Semaphore, Barrier) | Explanation
Explanation\n- Basically we are trying to ensure the executing order under certain condition. Lock/Semaphore/Event/Condition they can all serve this purpose giv
## Explanation\n- Basically we are trying to ensure the executing order under certain condition. `Lock/Semaphore/Event/Condition` they can all serve this purpose giving a bit of change.\n- The `Barrier` solution focusing on syncing up each iteration of these 3 threads. \n\n## Approach \\#1. Condition\n```python\nfrom threading import Condition\nclass ZeroEvenOdd:\n    def __init__(self, n):\n        self.n = n\n        self.cur = 1\n        self.non_zero = False\n        self.c = Condition()\n\n    def zero(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(self.n):\n            with self.c:\n                printNumber(0)\n                self.non_zero = True\n                self.c.notify_all()\n                self.c.wait_for(lambda: not self.non_zero)\n\n    def even(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(self.n // 2):\n            with self.c:\n                self.c.wait_for(lambda: self.non_zero and self.cur % 2 == 0)\n                printNumber(self.cur)\n                self.cur += 1\n                self.non_zero = False\n                self.c.notify_all()\n\n    def odd(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range((self.n + 1) // 2):\n            with self.c:\n                self.c.wait_for(lambda: self.non_zero and self.cur % 2 != 0)\n                printNumber(self.cur)\n                self.cur += 1\n                self.non_zero = False\n                self.c.notify_all()\n```\n\n## Approach \\#2. Event\n```python\nfrom threading import Event\nclass ZeroEvenOdd:\n    def __init__(self, n):\n        self.n = n\n        self.cur = 1\n        self.ez = Event() # zero\n        self.ee = Event() # even\n        self.eo = Event() # odd\n\n    def zero(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(self.n):\n            printNumber(0)\n            self.ez.clear()\n            if self.cur % 2:\n                self.eo.set()\n            else:\n                self.ee.set()\n            self.ez.wait()\n\n    def even(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(self.n // 2):\n            self.ee.wait()\n            printNumber(self.cur)\n            self.cur += 1\n            self.ee.clear()\n            self.ez.set()\n\n    def odd(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range((self.n + 1) // 2):\n            self.eo.wait()\n            printNumber(self.cur)\n            self.cur += 1\n            self.eo.clear()\n            self.ez.set()\n```\n\n## Approach \\#3 & 4. Lock/Semaphore\n```python\nfrom threading import Lock\nclass ZeroEvenOdd:\n    def __init__(self, n):\n        self.n = n\n        self.cur = 1\n        self.z = Lock() # Semaphore(1)\n        self.e = Lock() # Semaphore(1)\n        self.o = Lock() # Semaphore(1)\n        self.e.acquire()\n        self.o.acquire()\n\n    def zero(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(self.n):\n            with self.z:\n                printNumber(0)\n                if self.cur % 2:\n                    self.o.release()\n                else:\n                    self.e.release()    \n            self.z.acquire()        \n\n    def even(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(self.n // 2):\n            with self.e:\n                printNumber(self.cur)\n                self.cur += 1\n                self.z.release()\n            self.e.acquire()    \n\n    def odd(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range((self.n + 1) // 2):\n            with self.o:\n                printNumber(self.cur)\n                self.cur += 1\n                self.z.release()\n            self.o.acquire()\n```\n\n## Approach \\#5. Barrier\n```python\nfrom threading import Barrier\nclass ZeroEvenOdd:\n    def __init__(self, n):\n        self.n = 2 * n + 1\n        self.cur = 1\n        self.br = Barrier(3)\n\n    def zero(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(1, self.n):\n            if i % 2:\n                printNumber(0)\n            self.br.wait()\n\n    def even(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(1, self.n):\n            if not i % 2 and not (i // 2) % 2:\n                printNumber(i // 2)\n            self.br.wait()\n\n    def odd(self, printNumber: \'Callable[[int], None]\') -> None:\n        for i in range(1, self.n):\n            if not i % 2 and (i // 2) % 2:\n                printNumber(i // 2)\n            self.br.wait()\n```
['Python3']