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")]
|
instructions = [line for line in f.read().strip().split("\n")]
|
||||||
|
|
||||||
print(instructions)
|
|
||||||
|
|
||||||
# grid = np.zeros((6,50), dtype=int)
|
def rect(instruction: str, grid: npt.NDArray[int]) -> npt.NDArray[int]:
|
||||||
init_grid = np.zeros((3, 7), dtype=int)
|
_, row = instruction.split("x")
|
||||||
|
_, col = _.split()
|
||||||
# initialize grid
|
grid[: int(row), : int(col)] = 1
|
||||||
print(init_grid)
|
|
||||||
|
|
||||||
|
|
||||||
def rect(instruction, grid):
|
def rotate_column(
|
||||||
col, row = int(instruction[5:6]), int(instruction[7:])
|
instruction: str, grid: npt.NDArray[int]
|
||||||
# print(col,row)
|
) -> npt.NDArray[int]:
|
||||||
grid[:row, :col] = 1
|
_, 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)
|
def rotate_row(instruction: str, grid: npt.NDArray[int]) -> npt.NDArray[int]:
|
||||||
|
_, rows = instruction.split("=")
|
||||||
print(init_grid)
|
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):
|
def part_1() -> None:
|
||||||
x, steps = int(instruction[16:17]), int(instruction[21:])
|
# dimensions given by the problem
|
||||||
# print(x, steps)
|
init_grid = np.zeros((6, 50), dtype=int)
|
||||||
new_col = np.roll(grid[:, x : x + 1], steps, axis=0)
|
|
||||||
grid[:, x : x + 1] = new_col
|
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)
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
||||||
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))
|
|
||||||
|
Loading…
Reference in New Issue
Block a user