1116. Print Zero Even Odd - cocoder39/coco39_LC GitHub Wiki
Option 1: condition
from threading import Condition
class ZeroEvenOdd:
def __init__(self, n):
self.n = n
self.condition = Condition()
self.count = 0
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n):
with self.condition:
self.condition.wait_for(lambda: self.count % 2 == 0)
printNumber(0)
self.count += 1
self.condition.notifyAll()
def even(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n // 2):
with self.condition:
self.condition.wait_for(lambda: (self.count + 1) % 4 == 0)
printNumber(i*2 + 2)
self.count += 1
self.condition.notifyAll()
def odd(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n - self.n // 2):
with self.condition:
self.condition.wait_for(lambda: (self.count + 3) % 4 == 0)
printNumber(i*2 + 1)
self.count += 1
self.condition.notifyAll()
Option 2: semaphore
from threading import Semaphore
class ZeroEvenOdd:
def __init__(self, n):
self.n = n
self.zeroLock = Semaphore(1)
self.evenLock = Semaphore(0)
self.oddLock = Semaphore(0)
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n):
self.zeroLock.acquire()
printNumber(0)
if i % 2 == 0:
self.oddLock.release()
else:
self.evenLock.release()
def even(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(2, self.n+1, 2):
self.evenLock.acquire()
printNumber(i)
self.zeroLock.release()
def odd(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(1, self.n+1, 2):
self.oddLock.acquire()
printNumber(i)
self.zeroLock.release()
Option 3: event
from threading import Event
class ZeroEvenOdd:
def __init__(self, n):
self.n = n
self.zeroLock = Event()
self.evenLock = Event()
self.oddLock = Event()
self.zeroLock.set()
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n):
self.zeroLock.wait()
self.zeroLock.clear()
printNumber(0)
if i % 2 == 0:
self.oddLock.set()
else:
self.evenLock.set()
def even(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(2, self.n+1, 2):
self.evenLock.wait()
self.evenLock.clear()
printNumber(i)
self.zeroLock.set()
def odd(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(1, self.n+1, 2):
self.oddLock.wait()
self.oddLock.clear()
printNumber(i)
self.zeroLock.set()
Option 4: lock
from threading import Lock
class ZeroEvenOdd:
def __init__(self, n):
self.n = n
self.zeroLock = Lock()
self.evenLock = Lock()
self.oddLock = Lock()
self.evenLock.acquire()
self.oddLock.acquire()
# printNumber(x) outputs "x", where x is an integer.
def zero(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(self.n):
self.zeroLock.acquire()
printNumber(0)
if i % 2 == 0:
self.oddLock.release()
else:
self.evenLock.release()
def even(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(2, self.n+1, 2):
self.evenLock.acquire()
printNumber(i)
self.zeroLock.release()
def odd(self, printNumber: 'Callable[[int], None]') -> None:
for i in range(1, self.n+1, 2):
self.oddLock.acquire()
printNumber(i)
self.zeroLock.release()