Skip to content

Commit 9c39e2c

Browse files
committed
1116 Print Zero Even Odd
1 parent 09930cf commit 9c39e2c

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

1116 Print Zero Even Odd.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/python3
2+
"""
3+
uppose you are given the following code:
4+
5+
class ZeroEvenOdd {
6+
public ZeroEvenOdd(int n) { ... } // constructor
7+
public void zero(printNumber) { ... } // only output 0's
8+
public void even(printNumber) { ... } // only output even numbers
9+
public void odd(printNumber) { ... } // only output odd numbers
10+
}
11+
The same instance of ZeroEvenOdd will be passed to three different threads:
12+
13+
Thread A will call zero() which should only output 0's.
14+
Thread B will call even() which should only ouput even numbers.
15+
Thread C will call odd() which should only output odd numbers.
16+
Each of the threads is given a printNumber method to output an integer. Modify
17+
the given program to output the series 010203040506... where the length of the
18+
series must be 2n.
19+
20+
21+
Example 1:
22+
23+
Input: n = 2
24+
Output: "0102"
25+
Explanation: There are three threads being fired asynchronously. One of them
26+
calls zero(), the other calls even(), and the last one calls odd(). "0102" is
27+
the correct output.
28+
Example 2:
29+
30+
Input: n = 5
31+
Output: "0102030405"
32+
"""
33+
from threading import Lock
34+
35+
36+
class ZeroEvenOdd:
37+
def __init__(self, n):
38+
"""
39+
only use 3 locks, and zero() knows and commonds which lock to release,
40+
determing whether even() or odd() will run.
41+
"""
42+
self.n = n
43+
self.locks = [Lock() for _ in range(3)]
44+
self.locks[1].acquire()
45+
self.locks[2].acquire()
46+
47+
# printNumber(x) outputs "x", where x is an integer.
48+
def zero(self, printNumber: 'Callable[[int], None]') -> None:
49+
for i in range(self.n):
50+
self.locks[0].acquire()
51+
printNumber(0)
52+
if (i + 1) % 2 == 1:
53+
self.locks[1].release()
54+
else:
55+
self.locks[2].release()
56+
57+
def odd(self, printNumber: 'Callable[[int], None]') -> None:
58+
for i in range(self.n // 2):
59+
self.locks[1].acquire()
60+
printNumner(i * 2 + 1)
61+
self.locks[0].release()
62+
63+
def even(self, printNumber: 'Callable[[int], None]') -> None:
64+
for i in range(self.n // 2):
65+
self.locks[2].acquire()
66+
printNumber(i * 2 + 2)
67+
self.locks[0].release()
68+
69+
70+
class ZeroEvenOddError:
71+
def __init__(self, n):
72+
"""
73+
Like 1115, two layer of locks can do: zero and non-zero alternating,
74+
odd and even alternating. 4 locks required.
75+
76+
Using only 3 locks?
77+
"""
78+
self.n = n
79+
self.locks = [Lock(), Lock(), Lock(), Lock()]
80+
for i in range(1, len(self.locks)):
81+
self.locks[i].acquire()
82+
83+
# printNumber(x) outputs "x", where x is an integer.
84+
def zero(self, printNumber: 'Callable[[int], None]') -> None:
85+
with self.locks[0]:
86+
printNumber(0)
87+
88+
def even(self, printNumber: 'Callable[[int], None]') -> None:
89+
# cannot lock self.locks[1] from both "even" and "odd"
90+
pass
91+
92+
93+
def odd(self, printNumber: 'Callable[[int], None]') -> None:
94+
pass

0 commit comments

Comments
 (0)