Advent of Code 2020 Day 11
This year’s Advent of Code’s day 11 challenge – Seating System was a type of cellular automata task where one needed to model the eventual seating positions of individuals who are waiting to board a ferry.
To create our visualizations first we generate a new, random initial seating layout based off of the AoC examples
def generate_layout(rows, columns):
chars = ['L', '.']
layout = []
for _ in range(rows):
column = []
for _ in range(columns):
column.append(random.choice(chars))
layout.append(row)
return(layout)
this returns a two dimensional array like
[
['.', '.', '.', 'L', '.', 'L', '.', 'L', '.', 'L'],
['.', 'L', 'L', 'L', 'L', 'L', 'L', '.', '.', '.'],
['.', '.', 'L', 'L', '.', 'L', 'L', 'L', 'L', 'L'],
['L', 'L', 'L', '.', 'L', 'L', 'L', 'L', 'L', '.'],
['.', '.', 'L', 'L', '.', 'L', '.', '.', 'L', 'L'],
['L', '.', 'L', 'L', '.', 'L', 'L', '.', 'L', 'L'],
['L', '.', '.', 'L', '.', 'L', '.', 'L', 'L', 'L'],
['.', 'L', 'L', '.', '.', '.', '.', 'L', '.', 'L'],
['.', '.', 'L', '.', 'L', 'L', 'L', '.', '.', '.'],
['L', 'L', 'L', '.', 'L', 'L', '.', '.', 'L', 'L']
]
next we have print_layout()
which gives us a nicer representation of our seats
def print_layout(seat_array):
layout = ""
for column in seat_array:
c = ""
for seat in column:
c += seat
layout += '\n' + c
return(layout)
...L.L.L.L
.LLLLLL...
..LL.LLLLL
LLL.LLLLL.
..LL.L..LL
L.LL.LL.LL
L..L.L.LLL
.LL....L.L
..L.LLL...
LLL.LL..LL
The fun thing about this function is that is gives us lot of flexibility in how we represent this data. For example we can draw our seats using unicode block elements.
def print_layout(seat_array):
layout = ""
for column in seat_array:
c = ""
for seat in column:
if seat == '.': c += ' '
if seat == '#': c += '▓'
if seat == 'L': c += '▒'
layout += '\n' + c
return(layout)
▓ ░▓▓░▓ ▓
▓ ░ ░░ ░ ▓
▓ ░ ░
░ ░▓ ░ ░
▓░ ░░ ▓▓░▓
░▓▓ ░▓░
░░ ░ ░░▓
▓▓ ░▓
░░ ▓░░
▓░ ░▓
Then we can create an animation of our generated layouts reaching equilibrium
while True:
os.system('clear')
rows, columns = os.popen('stty size', 'r').read().split()
layout = generate_layout(int(columns), int(rows))
seats = model_seats(layout)
occupied_seat_counts = [0]
while True:
seats = model_seats(seats) # model the next seat layout
layout = print_layout(seats)
print(layout, flush=True) # display our new seat layout
occupied_seats = layout.count('▓') # this should be whichever
# char you use to represent
# occupied seats
if occupied_seats == occupied_seat_counts[-1]:
break # if the number of occupied seats has not changed since
# the previous run break and start on new seating layout
else:
occupied_seat_counts.append(occupied_seats)
You can see the full code and run it in your browser.