First part
Interesting stuff! I have been having the puzzle on my mind since yesterday, and today I managed to squeeze a few programming thinking minutes into the later part of the day.
HEIGHT = 6
WIDTH = 50
SCREEN = [['.' for _ in range(WIDTH)]
for _ in range(HEIGHT)]
def display_screen(screen: list[str]):
[print(line) for line in screen]
print()
def produce_new_lines(
old: list[str],
a: int,
b: int
) -> list[str]:
"""produces `b` new lines with `a`
columns of `#` and the remaining
columns with the previous screen content"""
return [['#' for _ in range(a)] + old[i][a:] for i in range(b)]
# a: width; b: height
def handle_rect(
old: list[str],
a: int,
b: int
) -> list[str]:
return produce_new_lines(old, a, b) + old[b:]
def handle_x_rotate(
old: list[str],
x: int,
amount: int
) -> list[str]:
old_deque = deque(old[x])
old_deque.rotate(amount)
return old[:x] + [list(old_deque)] + old[x + 1:]
def handle_y_rotate(
old: list[str],
y: int,
amount: int
) -> list[str]:
transpose = list(zip(*old))
return zip(*handle_x_rotate(transpose, y, amount))
All that's missing now is a parser, but I haven't given it much thought yet. Maybe tomorrow it will be finished.
Alas, it is not yet finished. I did some further work in the parsing, but I wasn't as rigorous with it. I really don't know what would be best practices for a functional parser. These have been very busy days, so I'm trying to make very small steps every time I find a few minutes I could dispense to programming.
I was having some miscellaneous issues that I managed to fix in some ten minutes; the code was not so bad (but it definitely feels long)
HEIGHT = 6
WIDTH = 50
SCREEN = [['.' for _ in range(WIDTH)]
for _ in range(HEIGHT)]
def display_screen(screen: list[str]):
[print(line) for line in screen]
print()
def produce_new_lines(
old: list[str],
a: int,
b: int
) -> list[str]:
"""produces `b` new lines with `a`
columns of `#` and the remaining
columns with the previous screen content"""
return [['#' for _ in range(a)] + list(old[i][a:]) for i in range(b)]
# a: width; b: height
def handle_rect(
old: list[str],
a: int,
b: int
) -> list[str]:
return produce_new_lines(old, a, b) + old[b:]
def handle_x_rotate(
old: list[str],
x: int,
amount: int
) -> list[str]:
old_deque = deque(old[x])
old_deque.rotate(amount)
return old[:x] + [list(old_deque)] + old[x + 1:]
def handle_y_rotate(
old: list[str],
y: int,
amount: int
) -> list[str]:
transpose = list(zip(*old))
return list(zip(*handle_x_rotate(transpose, y, amount)))
def iterate_through_lines(
screen: list[str],
lines: list[str]
) -> list[str]:
if not lines:
return screen
else:
instr = lines[0].split()
if instr[0] == 'rect':
screen = (handle_rect(
screen,
*list(map(int, (instr[1].split('x'))))))
# instruction is 'rotate'
else:
f = handle_x_rotate if instr[1] == 'row' else \
handle_y_rotate
screen = (f(screen,
*list(map(int, re.findall(
r'(\d+) by (\d+)', lines[0])[0]))))
return iterate_through_lines(screen, lines[1:])
with open('input') as file_input:
INPUT = file_input.read().splitlines()
print(reduce(lambda x, y: x + y.count('#'),
iterate_through_lines(SCREEN, INPUT),
0))
Part 2
For Part 2, I'd do something more rigorous if I had the time; instead, I just zoomed my terminal out, enough to see the image form itself.