Advent of Code: Day #11 - Seating System
5 - 6 minutes
Introduction
I was super busy yesterday so sorry this is late! The code is not the best optimised and I would like to go over it again in the future but it does work.
Task One
Today we are given a Game of Life-esque problem to model the seating in the waiting area. We are asked to apply the rules described and return the total amount of occupied seats.
Reading in the data
The input data is a map describing the layout of the seating area, a L character represents an empty chair, # an occupied one and . represents the floor. I read this data into a multidimensional array so I can access the data using an x, y index. seat = seats[y][x]
def read_data(path):dataset = []with open(path) as f:for line in f.readlines():dataset.append(list(line.rstrip()))return dataset
The Solution
To solve this I iterated over all of the seats and calculated the neighbors of the current seat. I then applied the rules and updated the seat as necessary. The solution is a bit slow, mainly because of the deepcopy every complete iteration.
def task_one(seatplan):def query(y, x):if y < 0 or x < 0 or y > height-1 or x > width-1:return "."return seats[y][x]width = len(seatplan[0])height = len(seatplan)seats = []while seats != seatplan:seats = deepcopy(seatplan)for y in range(height):for x in range(width):current_seat = query(y, x)neighbours = [query(y-1, x-1), query(y-1, x), query(y-1, x+1),query(y, x-1), query(y, x+1),query(y+1, x-1), query(y+1, x), query(y+1, x+1)]occupied = [seat for seat in neighbours if seat == "#"]if current_seat == "L" and "#" not in neighbours:seatplan[y][x] = "#"elif current_seat == "#" and len(occupied) >= 4:seatplan[y][x] = "L"return len([seat for row in seatplan for seat in row if seat == "#"])
Task Two
The Solution
Task two had us consider the first seat in the line of view from the current seat not just the ones adjacent. I do this by just checking spots until we find one that is not just floor.
def task_two(seatplan):def query(y, x):if y < 0 or x < 0 or y > height - 1 or x > width - 1:return "L"return old_seats[y][x]width = len(seatplan[0])height = len(seatplan)seats = deepcopy(seatplan)old_seats = deepcopy(seatplan)old_seats_new = deepcopy(seatplan)last = Falsecoeffs = [[-1, -1], [-1, 0], [-1, +1],[0, -1], [0, +1],[+1, -1], [+1, 0], [+1, +1]]while True:for y in range(height):for x in range(width):old_seats_new[y][x] = seats[y][x]current_seat = query(y, x)neighbours = [None, None, None,None, None,None, None, None]c = 1while any(seat is None for seat in neighbours):for i, (a, b) in enumerate(coeffs):seat = query(y - a * c, x - b * c)if neighbours[i] is None and seat != ".":neighbours[i] = seatc += 1if current_seat == "L" and "#" not in neighbours:seats[y][x] = "#"elif current_seat == "#" and len(["#" for seat in neighbours if seat == "#"]) >= 5:seats[y][x] = "L"old_seats = old_seats_newif seats == old_seats and last:breaklast = seats == old_seatsreturn len([1 for row in seats for seat in row if seat == "#"])
Links
Leaderboard Code: 353270-1fc6ef28
Github Repository A link to the github repo containing all the days.
main.py A direct download of the main.py script
3.1Kb