Advent of Code 2020, Day 5 -- Binary Boarding
My Advent of Code solutions, done in Python. Refactors and solutions in other languages will be added if/when they're done.
Full code for Day 5 can be found on Github.
You can participate in Advent of Code at adventofcode.com/2020
The Day 5 problem can be found at adventofcode.com/2020/day/5
Index
Solution, part 1
The puzzle is basically splitting a list of integers until we end up with a single value. To do this, I did my usual text file parsing, then got the first seven characters (the seat row) and last three characters (the seat column). I did this using Python's string slicing, which is something I've used in the past but I always forget exists! Thanks to slicing, it was really easy to separate out the row and column instructions.
Then, I created a list of all the rows in the plane, from 0 to 127, and all the columns in the plane, from 0 to 7.
Iterating over the characters in my row
string, I start splitting the list of plane rows. I'm using floor division for this, taking the length of the existing rows and // by 2. Then, I use string slicing again to update plane_rows
with either the upper or lower half of the split, depending on whether the character was "F" or "B".
Once that's all done, I should be left with a single number in my plane_rows
list, so I return that as plane_rows[0]
.
I do the same thing with the colums
string, iterating over the characters in the string, splitting the integer list, and returning the remaining integer when it's down to one.
I'm returning a tuple from this function, that I'll then use to calculate the seat ID. I didn't want to calculate the seat ID in this function because I wasn't sure what part 2 was going to bring.
lines = puzzle_input.readlines()
lines = [line.strip() for line in lines]
# Create lists of rows and columns of seats.
# Based upon "F" or "B" split the list in half and return
# that half. Do the same with "L" and "R" with the columns.
def row_and_column(seat):
row = seat[:-3]
column = seat[7:]
plane_rows = list(range(0, 128))
plane_cols = list(range(0, 8))
for r in row:
split = len(plane_rows) // 2
if r == "F":
plane_rows = plane_rows[:-split]
if r == "B":
plane_rows = plane_rows[split:]
row = plane_rows[0]
for c in column:
split = len(plane_cols) // 2
if c == "L":
plane_cols = plane_cols[:-split]
if c == "R":
plane_cols = plane_cols[split:]
column = plane_cols[0]
return row, column
To get the seat ID, I created a function that gets the (row, column) location of each seat, then multiplies the row by 8 and adds the column, per the instructions.
# Return the seat ID of one seat based on
# row and column position.
def seat_id(seat):
location = row_and_column(seat)
return location[0] * 8 + location[1]
Finally, those two functions only operate on each line, so I built a function that iterates over the input list with a list comprehension, passing each line into seat_id
, and returns the puzzle answer, the highest seat ID number.
# Iterate over all of the seats and return
# the seat with the highest ID number.
# This is the answer to part 1.
def iterate_over_passes(lines):
ids = [seat_id(line) for line in lines]
return max(ids)
print(iterate_over_passes(lines))
Solution, part 2
It turns out that I didn't need (row, column) information for part 2, so I'm once again going to iterate over the input list and get a list of seat IDs. Then, I'm going to sort the IDs and create a range from sorted_ids[0]
(the lowest ID) to sorted_ids[-1] + 1
(the highest ID, plus 1 so make the range inclusive of that ID).
Then, I decided to loop through the list of all possible seat IDs until I found one that wasn't in my list of sorted IDs, and returned it as my seat ID. Possibly not the best way to do this. I'm thinking two sets might've actually worked better, and finding the difference between the two sets would've been trivial.
# Get all of the provided seat IDs.
# Then, sort the IDs from low to high.
# Next, get the range of possible IDs from lowest
# to highest, finally, loop over the range of possible
# IDs to see which one is missing from the list.
def my_seat(lines):
ids = [seat_id(line) for line in lines]
sorted_ids = sorted(ids)
all_seats = list(range(sorted_ids[0], (sorted_ids[-1]) + 1))
for (i, num) in enumerate(all_seats):
if num != sorted_ids[i]:
return num
print(my_seat(lines))