-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Colin Sullivan
committed
Dec 10, 2022
1 parent
d060c82
commit 0ddcec5
Showing
6 changed files
with
444 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
noop | ||
addx 22 | ||
addx -17 | ||
addx 1 | ||
addx 4 | ||
addx 17 | ||
addx -16 | ||
addx 4 | ||
addx 1 | ||
addx 21 | ||
addx -17 | ||
addx -10 | ||
noop | ||
addx 17 | ||
addx -1 | ||
addx 5 | ||
addx -1 | ||
noop | ||
addx 4 | ||
addx 1 | ||
noop | ||
addx -37 | ||
addx 5 | ||
addx 27 | ||
addx -22 | ||
addx -2 | ||
addx 2 | ||
addx 5 | ||
addx 2 | ||
addx 5 | ||
noop | ||
noop | ||
addx -2 | ||
addx 5 | ||
addx 16 | ||
addx -11 | ||
addx -2 | ||
addx 2 | ||
addx 5 | ||
addx 2 | ||
addx -8 | ||
addx 9 | ||
addx -38 | ||
addx 5 | ||
addx 20 | ||
addx -16 | ||
addx 8 | ||
addx -5 | ||
addx 1 | ||
addx 4 | ||
noop | ||
noop | ||
addx 5 | ||
addx -2 | ||
noop | ||
noop | ||
addx 18 | ||
noop | ||
addx -8 | ||
addx 2 | ||
addx 7 | ||
addx -2 | ||
noop | ||
noop | ||
noop | ||
noop | ||
noop | ||
addx -35 | ||
noop | ||
addx 32 | ||
addx -26 | ||
addx 12 | ||
addx -8 | ||
addx 3 | ||
noop | ||
addx 2 | ||
addx 16 | ||
addx -24 | ||
addx 11 | ||
addx 3 | ||
addx -17 | ||
addx 17 | ||
addx 5 | ||
addx 2 | ||
addx -15 | ||
addx 22 | ||
addx 3 | ||
noop | ||
addx -40 | ||
noop | ||
addx 2 | ||
noop | ||
addx 3 | ||
addx 13 | ||
addx -6 | ||
addx 10 | ||
addx -9 | ||
addx 2 | ||
addx 22 | ||
addx -15 | ||
addx 8 | ||
addx -7 | ||
addx 2 | ||
addx 5 | ||
addx 2 | ||
addx -32 | ||
addx 33 | ||
addx 2 | ||
addx 5 | ||
addx -39 | ||
addx -1 | ||
addx 3 | ||
addx 4 | ||
addx 1 | ||
addx 4 | ||
addx 21 | ||
addx -20 | ||
addx 2 | ||
addx 12 | ||
addx -4 | ||
noop | ||
noop | ||
noop | ||
noop | ||
noop | ||
addx 4 | ||
noop | ||
noop | ||
noop | ||
addx 6 | ||
addx -27 | ||
addx 31 | ||
noop | ||
noop | ||
noop | ||
noop | ||
noop |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
""" | ||
Start by figuring out the signal being sent by the CPU. The CPU has a single register, X, which starts with the value 1. It supports only two instructions: | ||
addx V takes two cycles to complete. After two cycles, the X register is increased by the value V. (V can be negative.) | ||
noop takes one cycle to complete. It has no other effect. | ||
The CPU uses these instructions in a program (your puzzle input) to, somehow, tell the screen what to draw. | ||
Consider the following small program: | ||
noop | ||
addx 3 | ||
addx -5 | ||
Execution of this program proceeds as follows: | ||
At the start of the first cycle, the noop instruction begins execution. During the first cycle, X is 1. After the first cycle, the noop instruction finishes execution, doing nothing. | ||
At the start of the second cycle, the addx 3 instruction begins execution. During the second cycle, X is still 1. | ||
During the third cycle, X is still 1. After the third cycle, the addx 3 instruction finishes execution, setting X to 4. | ||
At the start of the fourth cycle, the addx -5 instruction begins execution. During the fourth cycle, X is still 4. | ||
During the fifth cycle, X is still 4. After the fifth cycle, the addx -5 instruction finishes execution, setting X to -1. | ||
Maybe you can learn something by looking at the value of the X register throughout execution. For now, consider the signal strength (the cycle number multiplied by the value of the X register) during the 20th cycle and every 40 cycles after that (that is, during the 20th, 60th, 100th, 140th, 180th, and 220th cycles). | ||
The interesting signal strengths can be determined as follows: | ||
During the 20th cycle, register X has the value 21, so the signal strength is 20 * 21 = 420. (The 20th cycle occurs in the middle of the second addx -1, so the value of register X is the starting value, 1, plus all of the other addx values up to that point: 1 + 15 - 11 + 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.) | ||
During the 60th cycle, register X has the value 19, so the signal strength is 60 * 19 = 1140. | ||
During the 100th cycle, register X has the value 18, so the signal strength is 100 * 18 = 1800. | ||
During the 140th cycle, register X has the value 21, so the signal strength is 140 * 21 = 2940. | ||
During the 180th cycle, register X has the value 16, so the signal strength is 180 * 16 = 2880. | ||
During the 220th cycle, register X has the value 18, so the signal strength is 220 * 18 = 3960. | ||
The sum of these signal strengths is 13140. | ||
Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and 220th cycles. What is the sum of these six signal strengths? | ||
""" | ||
|
||
|
||
def sum_interesting_signals(input_str: str) -> int: | ||
instructions = [ | ||
0 if line == "noop" else int(line.split()[1]) for line in input_str.split("\n") | ||
] | ||
|
||
signals = [] | ||
curr_signal = 1 | ||
curr_cycle = 0 | ||
|
||
for i, instruction in enumerate(instructions): | ||
curr_cycle += 1 | ||
if instruction: | ||
if (curr_cycle - 20) % 40 == 0 and curr_cycle >= 20: | ||
signals.append(curr_signal * curr_cycle) | ||
curr_cycle += 1 | ||
if (curr_cycle - 20) % 40 == 0 and curr_cycle >= 20: | ||
signals.append(curr_signal * curr_cycle) | ||
curr_signal += instruction | ||
else: | ||
if (curr_cycle - 20) % 40 == 0 and curr_cycle >= 20: | ||
signals.append(curr_signal * curr_cycle) | ||
return sum(signals) | ||
|
||
|
||
if __name__ == "__main__": | ||
input_str = open("data/day10.txt").read() | ||
|
||
print(sum_interesting_signals(input_str)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
""" | ||
It seems like the X register controls the horizontal position of a sprite. Specifically, the sprite is 3 pixels wide, and the X register sets the horizontal position of the middle of that sprite. (In this system, there is no such thing as "vertical position": if the sprite's horizontal position puts its pixels where the CRT is currently drawing, then those pixels will be drawn.) | ||
You count the pixels on the CRT: 40 wide and 6 high. This CRT screen draws the top row of pixels left-to-right, then the row below that, and so on. The left-most pixel in each row is in position 0, and the right-most pixel in each row is in position 39. | ||
Like the CPU, the CRT is tied closely to the clock circuit: the CRT draws a single pixel during each cycle. Representing each pixel of the screen as a #, here are the cycles during which the first and last pixel in each row are drawn: | ||
Cycle 1 -> ######################################## <- Cycle 40 | ||
Cycle 41 -> ######################################## <- Cycle 80 | ||
Cycle 81 -> ######################################## <- Cycle 120 | ||
Cycle 121 -> ######################################## <- Cycle 160 | ||
Cycle 161 -> ######################################## <- Cycle 200 | ||
Cycle 201 -> ######################################## <- Cycle 240 | ||
So, by carefully timing the CPU instructions and the CRT drawing operations, you should be able to determine whether the sprite is visible the instant each pixel is drawn. If the sprite is positioned such that one of its three pixels is the pixel currently being drawn, the screen produces a lit pixel (#); otherwise, the screen leaves the pixel dark (.). | ||
Allowing the program to run to completion causes the CRT to produce the following image: | ||
##..##..##..##..##..##..##..##..##..##.. | ||
###...###...###...###...###...###...###. | ||
####....####....####....####....####.... | ||
#####.....#####.....#####.....#####..... | ||
######......######......######......#### | ||
#######.......#######.......#######..... | ||
Render the image given by your program. What eight capital letters appear on your CRT? | ||
""" | ||
import numpy as np | ||
|
||
|
||
def get_pixel_val(sprite_location: np.ndarray, curr_cycle: int) -> str: | ||
old_cycle = curr_cycle | ||
if old_cycle == 175: | ||
old_cycle | ||
if curr_cycle > 40: | ||
curr_cycle = curr_cycle % 40 | ||
if any(sprite_location == curr_cycle - 1): | ||
pixel = "#" | ||
else: | ||
pixel = "." | ||
if curr_cycle % 40 == 0: | ||
pixel += "\n" | ||
return pixel | ||
|
||
|
||
def print_screen(input_str: str) -> str: | ||
instructions = [ | ||
0 if line == "noop" else int(line.split()[1]) for line in input_str.split("\n") | ||
] | ||
|
||
sprite_location = np.array([0, 1, 2]) | ||
curr_cycle = 0 | ||
pixels = [] | ||
|
||
for instruction in instructions: | ||
curr_cycle += 1 | ||
pixel_val = get_pixel_val(sprite_location, curr_cycle) | ||
pixels.append(pixel_val) | ||
if instruction: | ||
curr_cycle += 1 | ||
pixel_val = get_pixel_val(sprite_location, curr_cycle) | ||
pixels.append(pixel_val) | ||
sprite_location += instruction | ||
return "".join(pixels) | ||
|
||
|
||
if __name__ == "__main__": | ||
input_str = open("data/day10.txt").read() | ||
|
||
print(print_screen(input_str)) |
Oops, something went wrong.