Solution to problem 8 part 1 in Python

This commit is contained in:
David Doblas Jiménez 2022-04-03 20:40:14 +02:00
parent 8ba6b57f2c
commit bae5b96bf7

View File

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