Solution to problem 8 part 1 in Python
This commit is contained in:
parent
8ba6b57f2c
commit
bae5b96bf7
@ -1,53 +1,111 @@
|
||||
import numpy as np
|
||||
# --- Day 8: Two-Factor Authentication ---
|
||||
|
||||
with open("files/test") as f:
|
||||
# You come across a door implementing what you can only assume is an
|
||||
# implementation of two-factor authentication after a long game of
|
||||
# requirements telephone.
|
||||
|
||||
# To get past the door, you first swipe a keycard (no problem; there was one on
|
||||
# a nearby desk). Then, it displays a code on a little screen, and you type
|
||||
# that code on a keypad. Then, presumably, the door unlocks.
|
||||
|
||||
# Unfortunately, the screen has been smashed. After a few minutes, you've taken
|
||||
# everything apart and figured out how it works. Now you just have to work out
|
||||
# what the screen would have displayed.
|
||||
|
||||
# The magnetic strip on the card you swiped encodes a series of instructions
|
||||
# for the screen; these instructions are your puzzle input. The screen is 50
|
||||
# pixels wide and 6 pixels tall, all of which start off, and is capable of
|
||||
# three somewhat peculiar operations:
|
||||
|
||||
# rect AxB turns on all of the pixels in a rectangle at the top-left of the
|
||||
# screen which is A wide and B tall.
|
||||
# rotate row y=A by B shifts all of the pixels in row A (0 is the top row)
|
||||
# right by B pixels. Pixels that would fall off the right end appear at the
|
||||
# left end of the row.
|
||||
# rotate column x=A by B shifts all of the pixels in column A (0 is the
|
||||
# left column) down by B pixels. Pixels that would fall off the bottom appear
|
||||
# at the top of the column.
|
||||
|
||||
# For example, here is a simple sequence on a smaller screen:
|
||||
|
||||
# rect 3x2 creates a small rectangle in the top-left corner:
|
||||
|
||||
# ###....
|
||||
# ###....
|
||||
# .......
|
||||
|
||||
# rotate column x=1 by 1 rotates the second column down by one pixel:
|
||||
|
||||
# #.#....
|
||||
# ###....
|
||||
# .#.....
|
||||
|
||||
# rotate row y=0 by 4 rotates the top row right by four pixels:
|
||||
|
||||
# ....#.#
|
||||
# ###....
|
||||
# .#.....
|
||||
|
||||
# rotate column x=1 by 1 again rotates the second column down by one pixel,
|
||||
# causing the bottom pixel to wrap back to the top:
|
||||
|
||||
# .#..#.#
|
||||
# #.#....
|
||||
# .#.....
|
||||
|
||||
# As you can see, this display technology is extremely powerful, and will soon
|
||||
# dominate the tiny-code-displaying-screen market. That's what the
|
||||
# advertisement on the back of the display tries to convince you, anyway.
|
||||
|
||||
# There seems to be an intermediate check of the voltage used by the display:
|
||||
# after you swipe your card, if the screen did work, how many pixels should be
|
||||
# lit?
|
||||
|
||||
import numpy as np
|
||||
import numpy.typing as npt
|
||||
|
||||
with open("files/P8.txt") as f:
|
||||
instructions = [line for line in f.read().strip().split("\n")]
|
||||
|
||||
print(instructions)
|
||||
|
||||
# grid = np.zeros((6,50), dtype=int)
|
||||
init_grid = np.zeros((3, 7), dtype=int)
|
||||
|
||||
# initialize grid
|
||||
print(init_grid)
|
||||
def rect(instruction: str, grid: npt.NDArray[int]) -> npt.NDArray[int]:
|
||||
_, row = instruction.split("x")
|
||||
_, col = _.split()
|
||||
grid[: int(row), : int(col)] = 1
|
||||
|
||||
|
||||
def rect(instruction, grid):
|
||||
col, row = int(instruction[5:6]), int(instruction[7:])
|
||||
# print(col,row)
|
||||
grid[:row, :col] = 1
|
||||
def rotate_column(
|
||||
instruction: str, grid: npt.NDArray[int]
|
||||
) -> npt.NDArray[int]:
|
||||
_, cols = instruction.split("=")
|
||||
x, _, steps = cols.split()
|
||||
new_col = np.roll(grid[:, int(x) : int(x) + 1], int(steps), axis=0)
|
||||
grid[:, int(x) : int(x) + 1] = new_col
|
||||
|
||||
|
||||
rect(instructions[0], init_grid)
|
||||
|
||||
print(init_grid)
|
||||
def rotate_row(instruction: str, grid: npt.NDArray[int]) -> npt.NDArray[int]:
|
||||
_, rows = instruction.split("=")
|
||||
y, _, steps = rows.split()
|
||||
new_row = np.roll(grid[int(y) : int(y) + 1, :], int(steps), axis=1)
|
||||
grid[int(y) : int(y) + 1, :] = new_row
|
||||
|
||||
|
||||
def rotate_column(instruction, grid):
|
||||
x, steps = int(instruction[16:17]), int(instruction[21:])
|
||||
# print(x, steps)
|
||||
new_col = np.roll(grid[:, x : x + 1], steps, axis=0)
|
||||
grid[:, x : x + 1] = new_col
|
||||
def part_1() -> None:
|
||||
# dimensions given by the problem
|
||||
init_grid = np.zeros((6, 50), dtype=int)
|
||||
|
||||
for instruction in instructions:
|
||||
if instruction.startswith("rect"):
|
||||
rect(instruction, init_grid)
|
||||
elif instruction.startswith("rotate row"):
|
||||
rotate_row(instruction, init_grid)
|
||||
elif instruction.startswith("rotate column"):
|
||||
rotate_column(instruction, init_grid)
|
||||
|
||||
lit = np.sum(init_grid)
|
||||
|
||||
print(f"There should be {lit} pixels lit")
|
||||
|
||||
|
||||
rotate_column(instructions[1], init_grid)
|
||||
|
||||
print(init_grid)
|
||||
|
||||
|
||||
def rotate_row(instruction, grid):
|
||||
y, steps = int(instruction[13:14]), int(instruction[18:])
|
||||
# print(y, steps)
|
||||
new_row = np.roll(grid[y : y + 1, :], steps, axis=1)
|
||||
grid[y : y + 1, :] = new_row
|
||||
|
||||
|
||||
rotate_row(instructions[2], init_grid)
|
||||
|
||||
print(init_grid)
|
||||
|
||||
rotate_column(instructions[3], init_grid)
|
||||
|
||||
print(init_grid)
|
||||
|
||||
print(np.sum(init_grid))
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
|
Loading…
Reference in New Issue
Block a user