-
Notifications
You must be signed in to change notification settings - Fork 0
/
day11.py
73 lines (63 loc) · 2.6 KB
/
day11.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
63
64
65
66
67
68
69
70
71
72
73
with open("input/day11", "r") as input:
data = input.read().split("\n")
data.pop()
slopes_yx = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] # NW N NE W E SW S SE
seatsInLos = []
def getSeatsInLos():
for lineIdx in range(len(data)):
line = []
for charIdx in range(len(data[lineIdx])):
coords = []
if data[lineIdx][charIdx] == 'L':
coords.append((lineIdx, charIdx))
for slope in slopes_yx:
y = lineIdx + slope[0]
x = charIdx + slope[1]
while 0 <= y < len(data) and 0 <= x < len(data[lineIdx]):
if (data[y][x] == 'L'):
coords.append((y, x))
break
y += slope[0]
x += slope[1]
line.append(coords)
seatsInLos.append(line)
def getNumOccupiedSeats_pt1(lineIdx, charIdx, state):
min_y = lineIdx - 1 if lineIdx > 0 else 0
min_x = charIdx - 1 if charIdx > 0 else 0
max_y = lineIdx + 2 if lineIdx < len(state) - 1 else len(state)
max_x = charIdx + 2 if charIdx < len(state[lineIdx]) - 1 else len(state[lineIdx])
return [state[y][x] for y in range(min_y, max_y) for x in range(min_x, max_x)].count('#')
def getNumOccupiedSeats_pt2(lineIdx, charIdx, state):
return sum([1 for (y, x) in seatsInLos[lineIdx][charIdx] if state[y][x] == '#'])
def applyRules(lineIdx, state, isPt1):
line = ''
for charIdx in range(len(state[lineIdx])):
char = state[lineIdx][charIdx]
if char == '.':
line += char
else:
numOccupiedSeats = getNumOccupiedSeats_pt1(lineIdx, charIdx, state) if isPt1 else getNumOccupiedSeats_pt2(lineIdx, charIdx, state)
maxOccupiedAllowed = 5 if isPt1 else 6
if char == 'L' and numOccupiedSeats == 0:
line += '#'
elif char == '#' and numOccupiedSeats >= maxOccupiedAllowed:
line += 'L'
else:
line += char
return line
def progress(lastState, isPt1):
nextState = []
stabilized = True
for idx in range(len(lastState)):
nextState.append(applyRules(idx, lastState, isPt1))
if nextState[idx] != lastState[idx]:
stabilized = False
return (nextState, stabilized)
def parts(isPt1):
state = (data, False)
while not state[1]:
state = progress(state[0], isPt1)
return sum([line.count('#') for line in state[0]])
getSeatsInLos()
print("Part 1: " + str(parts(True)))
print("Part 2: " + str(parts(False)))