151 lines
3.2 KiB
Python
151 lines
3.2 KiB
Python
def read_file():
|
|
with open("input.txt","r") as f:
|
|
seed = f.read().split('\n')
|
|
# pad with floor to prevent out-of-bounds checks
|
|
seats = []
|
|
seats.append(list('.' * (len(seed[0])+2)))
|
|
for row in seed:
|
|
seats.append(list('.' + row + '.'))
|
|
seats.append(list('.' * (len(seed[0])+2)))
|
|
return seats
|
|
|
|
def check_neighbors(state,i,j):
|
|
a = state[i-1][j-1]
|
|
b = state[i-1][j]
|
|
c = state[i-1][j+1]
|
|
d = state[i][j-1]
|
|
e = state[i][j+1]
|
|
f = state[i+1][j-1]
|
|
g = state[i+1][j]
|
|
h = state[i+1][j+1]
|
|
return a+b+c+d+e+f+g+h
|
|
|
|
from copy import deepcopy
|
|
def find_steady_state(seats):
|
|
height = len(seats)
|
|
width = len(seats[0])
|
|
state = deepcopy(seats)
|
|
prev_state = deepcopy(seats)
|
|
while True:
|
|
for i in range(height):
|
|
for j in range(width):
|
|
cell = prev_state[i][j]
|
|
if cell == ".":
|
|
pass
|
|
elif cell == "L":
|
|
# check for no occupied seats
|
|
neighbors = check_neighbors(prev_state,i,j)
|
|
if "#" not in neighbors:
|
|
state[i][j] = "#"
|
|
else:
|
|
state[i][j] = "L"
|
|
elif cell == "#":
|
|
# check for 4+ occupied seats
|
|
neighbors = check_neighbors(prev_state,i,j)
|
|
if neighbors.count("#") > 3:
|
|
state[i][j] = "L"
|
|
else:
|
|
state[i][j] = "#"
|
|
if state == prev_state:
|
|
break
|
|
prev_state = deepcopy(state)
|
|
return state
|
|
|
|
def part1(seats):
|
|
final_state = find_steady_state(seats)
|
|
output = ''
|
|
for row in final_state:
|
|
for character in row:
|
|
output += character
|
|
return output.count("#")
|
|
|
|
def check_line_of_sight(state,i,j):
|
|
height = len(state)
|
|
width = len(state[0])
|
|
a = "."
|
|
n = 1
|
|
while a == "." and i-n >= 0 and j-n >= 0:
|
|
a = state[i-n][j-n]
|
|
n += 1
|
|
b = "."
|
|
n = 1
|
|
while b == "." and i-n >= 0:
|
|
b = state[i-n][j]
|
|
n += 1
|
|
c = "."
|
|
n = 1
|
|
while c == "." and i-n >= 0 and j+n < width:
|
|
c = state[i-n][j+n]
|
|
n += 1
|
|
d = "."
|
|
n = 1
|
|
while d == "." and j-n >= 0:
|
|
d = state[i][j-n]
|
|
n += 1
|
|
e = "."
|
|
n = 1
|
|
while e == "." and j+n < width:
|
|
e = state[i][j+n]
|
|
n += 1
|
|
f = "."
|
|
n = 1
|
|
while f == "." and i+n < height and j-n >= 0:
|
|
f = state[i+n][j-n]
|
|
n += 1
|
|
g = "."
|
|
n = 1
|
|
while g == "." and i+n < height:
|
|
g = state[i+n][j]
|
|
n += 1
|
|
h = "."
|
|
n = 1
|
|
while h == "." and i+n < height and j+n < width:
|
|
h = state[i+n][j+n]
|
|
n += 1
|
|
return a+b+c+d+e+f+g+h
|
|
|
|
def find_steady_state_2(seats):
|
|
height = len(seats)
|
|
width = len(seats[0])
|
|
state = deepcopy(seats)
|
|
prev_state = deepcopy(seats)
|
|
while True:
|
|
for i in range(height):
|
|
for j in range(width):
|
|
cell = prev_state[i][j]
|
|
if cell == ".":
|
|
pass
|
|
elif cell == "L":
|
|
# check for no occupied seats
|
|
neighbors = check_line_of_sight(prev_state,i,j)
|
|
if "#" not in neighbors:
|
|
state[i][j] = "#"
|
|
else:
|
|
state[i][j] = "L"
|
|
elif cell == "#":
|
|
# check for 4+ occupied seats
|
|
neighbors = check_line_of_sight(prev_state,i,j)
|
|
if neighbors.count("#") > 4:
|
|
state[i][j] = "L"
|
|
else:
|
|
state[i][j] = "#"
|
|
if state == prev_state:
|
|
break
|
|
prev_state = deepcopy(state)
|
|
return state
|
|
|
|
def part2(seats):
|
|
pass
|
|
final_state = find_steady_state_2(seats)
|
|
output = ''
|
|
for row in final_state:
|
|
for character in row:
|
|
output += character
|
|
return output.count("#")
|
|
|
|
def main():
|
|
seats = read_file()
|
|
print(part1(seats), part2(seats))
|
|
|
|
if __name__ == "__main__":
|
|
main() |