Mary Knize

Advent of Code 2020, Day 5 -- Binary Boarding

4 min read

Advent of Code 2020

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))

More Advent of Code

Canonical URL