-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path05_challenge.py
96 lines (69 loc) · 2.85 KB
/
05_challenge.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import re
from pathlib import Path
import colorama as clr
import numpy as np
# Prepare colorama to highlight printed solutions.
clr.init(autoreset=True)
answer_highlight = clr.Fore.BLUE + clr.Style.BRIGHT
# Read in data.
input_data_path = Path("data/day_05/input.txt")
boarding_passes = []
with open(input_data_path, "r") as file:
boarding_passes = list(file)
boarding_passes = [x.rstrip() for x in boarding_passes]
def parse_binary_space_partitioning_system(x, max_n):
"""Perform the binary space partitioning algorithm to locate a single value."""
if not bool(re.match("^[a-b]+$", x)):
# Check that all characters in `x` are either 'a' or 'b'.
raise Exception(f"Unrecognized characters in input x: {x}")
ary = np.arange(start=0, stop=max_n, step=1, dtype="int")
for c in x:
half = int(len(ary) / 2)
if c == "a":
ary = ary[:half]
else:
ary = ary[half:]
if ary.shape[0] != 1:
raise Exception(f"Length of final array is not 1: {ary}")
return ary[0]
def modify_boarding_pass_characters(bp, lower_char, upper_char):
"""Replace the existing code with a standard one for first or second have or binary partition."""
return bp.replace(lower_char, "a").replace(upper_char, "b")
def parse_row(x, max_row):
"""Parse row information."""
mod_x = modify_boarding_pass_characters(x, "F", "B")
return parse_binary_space_partitioning_system(mod_x, max_row)
def parse_col(x, max_col):
"""Parse column information."""
mod_x = modify_boarding_pass_characters(x, "L", "R")
return parse_binary_space_partitioning_system(mod_x, max_col)
def get_seat_location(bp, max_rows, max_cols):
"""Find a seat location of a boarding pass."""
return (parse_row(bp[:7], max_rows), parse_col(bp[7:], max_cols))
# Get all seat locations: [(row, col)]
seat_locations = [get_seat_location(bp, 128, 8) for bp in boarding_passes]
def calculate_seat_id(r, c):
"""From the seat's location, calculate the seat ID."""
return r * 8 + c
# List of all seat IDs.
seat_ids = [calculate_seat_id(*bp) for bp in seat_locations]
# Solution to first puzzle.
print(answer_highlight + f"highest seat id: {max(seat_ids)}")
# Create a seating chart with 0 = empty, 1 = occupied.
seating_chart = np.zeros((128, 8))
for r, c in seat_locations:
seating_chart[r, c] = 1
# Locate my seat as unoccupied but with neighboring seat IDs occupied.
my_seat = -1
for r, c in zip(*np.where(seating_chart == 0)):
seat_id = calculate_seat_id(r, c)
if seat_id + 1 in seat_ids and seat_id - 1 in seat_ids:
# Solution to second puzzle.
print(
answer_highlight
+ f"my seat is located at row {r}, column {c} with seat id {seat_id}"
)
my_seat = seat_id
# Print sad message if my seat is not located.
if my_seat == -1:
print("I didn't find my seat 😔")