1116. Print Zero Even Odd - cocoder39/coco39_LC GitHub Wiki

1116. Print Zero Even Odd

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()