| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- #!/usr/bin/env python3
- import sys
- FLOOR, EMPTY, OCCUPIED = range(3)
- def parse(f):
- state = []
- for line in f:
- state += ['.L#'.index(c) for c in line.rstrip()]
- w = len(line.rstrip())
- return state, w
- def changes(state, w, tolerance, see_far):
- h = len(state) // w
- def see_occupied(x, y, dx, dy):
- x += dx
- y += dy
- if x < 0 or x >= w or y < 0 or y >= h:
- return False
- seat = state[y * w + x]
- if seat != FLOOR:
- return seat == OCCUPIED
- return see_far and see_occupied(x, y, dx, dy)
- def occupied_nb(i):
- y, x = divmod(i, w)
- return sum(see_occupied(x, y, dx, dy)
- for dx in (-1, 0, 1)
- for dy in (-1, 0, 1)
- if dx or dy)
- for i, seat in enumerate(state):
- if seat == EMPTY and occupied_nb(i) == 0:
- yield i, OCCUPIED
- elif seat == OCCUPIED and occupied_nb(i) >= tolerance:
- yield i, EMPTY
- def stabilize(state, w, tolerance, see_far):
- state = list(state)
- changeset = list(changes(state, w, tolerance, see_far))
- while changeset:
- for i, seat in changeset:
- state[i] = seat
- changeset[::] = changes(state, w, tolerance, see_far)
- return state
- state, w = parse(sys.stdin)
- print(stabilize(state, w, 4, False).count(OCCUPIED))
- print(stabilize(state, w, 5, True).count(OCCUPIED))
|