from itertools import product with open('input') as f: data = [line.strip() for line in f] def binary_partition(bsp, r): if r[0] == r[1]: return r[0] half = (r[1] + r[0]) // 2 if bsp[0] in ['F', 'L']: return binary_partition(bsp[1:], (r[0], half)) elif bsp[0] in ['B', 'R']: return binary_partition(bsp[1:], (half + 1, r[1])) def from_binary(bsp): #Apparently doing a binary partition as the problem describes is the same as reading #the instructions in binary, i think is in someway equivalent to the traversal of a binary tree return int(bsp.replace('F', '0').replace('L', '0').replace('B', '1').replace('R', '1'), 2) def get_id(row, col): # return row * 8 + col return row << 3 | col def parse_seats(data): seats = [] for line in data: row = binary_partition(line[:7], (0, 127)) #from_binary(line[:7]) col = binary_partition(line[7:], (0, 7)) #from_binary(line[7:]) seats.append(get_id(row, col)) return seats def solve_a(seats): return max(seats) def solve_b(seats): for seat in product(range(0, 127), range(0, 7)): seat_id = get_id(*seat) if seat_id not in seats and \ seat_id + 1 in seats and \ seat_id - 1 in seats: return seat_id seats = parse_seats(data) print(solve_a(seats)) print(solve_b(seats))