-
Notifications
You must be signed in to change notification settings - Fork 17
/
exam-room.py
62 lines (46 loc) · 1.85 KB
/
exam-room.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from typing import List
from itertools import chain
class ExamRoom:
def __init__(self, N: int):
self._seats = N
self._occupied: List[int] = []
def seat(self) -> int:
if not self._occupied:
self._occupied.append(0)
return 0
interval_len = lambda x: (x[0] + x[1] - 1) // 2 - x[0]
max_interval = [1, 0]
first_interval = [-self._occupied[0] + 1, self._occupied[0]]
last_interval = [
self._occupied[-1] + 1,
2 * (self._seats - 1) - self._occupied[-1],
]
max_interval = max(
max_interval, first_interval, key=interval_len
)
for pos in range(len(self._occupied) - 1):
interval = [self._occupied[pos] + 1, self._occupied[pos + 1]]
max_interval = max(max_interval, interval, key=interval_len)
max_interval = max(
max_interval, last_interval, key=interval_len
)
middle = max_interval[0] + (max_interval[1] - 1 - max_interval[0]) // 2
self._occupied.append(middle)
for pos in reversed(range(len(self._occupied) - 1)):
if self._occupied[pos] > self._occupied[pos + 1]:
self._occupied[pos], self._occupied[pos + 1] = (
self._occupied[pos + 1],
self._occupied[pos],
)
return middle
def leave(self, p: int) -> None:
for pos in range(len(self._occupied)):
if self._occupied[pos] == p:
self._occupied[pos] = self._seats
for pos in range(len(self._occupied) - 1):
if self._occupied[pos] > self._occupied[pos + 1]:
self._occupied[pos], self._occupied[pos + 1] = (
self._occupied[pos + 1],
self._occupied[pos],
)
self._occupied.pop()