Solution to problem 11 part 2

This commit is contained in:
David Doblas Jiménez 2021-12-06 21:22:18 +01:00
parent 2c9f5f3cbe
commit 243406503f

View File

@ -172,5 +172,196 @@ def part_1(seats: list[str]) -> None:
print(f"There are {free_seats(seats)} seats occupied") print(f"There are {free_seats(seats)} seats occupied")
# --- Part Two ---
# As soon as people start to arrive, you realize your mistake. People don't
# just care about adjacent seats - they care about the first seat they can see
# in each of those eight directions!
# Now, instead of considering just the eight immediately adjacent seats,
# consider the first seat in each of those eight directions. For example, the
# empty seat below would see eight occupied seats:
# .......#.
# ...#.....
# .#.......
# .........
# ..#L....#
# ....#....
# .........
# #........
# ...#.....
# The leftmost empty seat below would only see one empty seat, but cannot see
# any of the occupied ones:
# .............
# .L.L.#.#.#.#.
# .............
# The empty seat below would see no occupied seats:
# .##.##.
# #.#.#.#
# ##...##
# ...L...
# ##...##
# #.#.#.#
# .##.##.
# Also, people seem to be more tolerant than you expected: it now takes five or
# more visible occupied seats for an occupied seat to become empty (rather than
# four or more from the previous rules). The other rules still apply: empty
# seats that see no occupied seats become occupied, seats matching no rule
# don't change, and floor never changes.
# Given the same starting layout as above, these new rules cause the seating
# area to shift around as follows:
# L.LL.LL.LL
# LLLLLLL.LL
# L.L.L..L..
# LLLL.LL.LL
# L.LL.LL.LL
# L.LLLLL.LL
# ..L.L.....
# LLLLLLLLLL
# L.LLLLLL.L
# L.LLLLL.LL
# #.##.##.##
# #######.##
# #.#.#..#..
# ####.##.##
# #.##.##.##
# #.#####.##
# ..#.#.....
# ##########
# #.######.#
# #.#####.##
# #.LL.LL.L#
# #LLLLLL.LL
# L.L.L..L..
# LLLL.LL.LL
# L.LL.LL.LL
# L.LLLLL.LL
# ..L.L.....
# LLLLLLLLL#
# #.LLLLLL.L
# #.LLLLL.L#
# #.L#.##.L#
# #L#####.LL
# L.#.#..#..
# ##L#.##.##
# #.##.#L.##
# #.#####.#L
# ..#.#.....
# LLL####LL#
# #.L#####.L
# #.L####.L#
# #.L#.L#.L#
# #LLLLLL.LL
# L.L.L..#..
# ##LL.LL.L#
# L.LL.LL.L#
# #.LLLLL.LL
# ..L.L.....
# LLLLLLLLL#
# #.LLLLL#.L
# #.L#LL#.L#
# #.L#.L#.L#
# #LLLLLL.LL
# L.L.L..#..
# ##L#.#L.L#
# L.L#.#L.L#
# #.L####.LL
# ..#.#.....
# LLL###LLL#
# #.LLLLL#.L
# #.L#LL#.L#
# #.L#.L#.L#
# #LLLLLL.LL
# L.L.L..#..
# ##L#.#L.L#
# L.L#.LL.L#
# #.LLLL#.LL
# ..#.L.....
# LLL###LLL#
# #.LLLLL#.L
# #.L#LL#.L#
# Again, at this point, people stop shifting around and the seating area
# reaches equilibrium. Once this occurs, you count 26 occupied seats.
# Given the new visibility method and the rule change for occupied seats
# becoming empty, once equilibrium is reached, how many seats end up occupied?
def seats_around_mod(seats: list[str], r: int, c: int) -> int:
total = 0
around_me = [
(-1, -1),
(-1, 0),
(-1, 1),
(0, -1),
(0, 1),
(1, -1),
(1, 0),
(1, 1),
]
for row, col in around_me:
_row = r + row
_col = c + col
while (
_row >= 0
and _row < len(seats)
and _col < len(seats[c])
and seats[_row][_col] == "."
):
_row += row
_col += col
if (
_row >= 0
and _row < len(seats)
and _col >= 0
and _col < len(seats[c])
):
total += seats[_row][_col] == "#"
return total
def part_2(seats: list[str]) -> None:
R = len(seats)
C = len(seats[0])
while True:
has_changed = False
next_iter = []
for r in range(R):
new_row = ""
for c in range(C):
seat = seats[r][c]
if seat != ".":
occupants = seats_around_mod(seats, r, c)
if seat == "L" and occupants == 0:
seat = "#"
has_changed = True
elif seat == "#" and occupants >= 5:
seat = "L"
has_changed = True
new_row += seat
next_iter.append(new_row)
if not has_changed:
break
seats = next_iter
print(f"There are {free_seats(seats)} seats occupied")
if __name__ == "__main__": if __name__ == "__main__":
part_1(seats) part_1(seats)
part_2(seats)