Advent of Code - Day 10
After the rope adventure, it's nice to do some easy task. We will be TV technicians!
Today’s puzzle in short: we have a screen display and need to figure out what we draw on it.
The input data
This time in the input file we get some nice programming commands:
- Each line contains exactly 1 command
- If the command is
noop
, it suppose to do nothing just takes one CPU cycle. - It the command is
addx n
, it suppose to increment / decrement the X register byn
(n
can be negative). This command takes two CPU cycle.
Game rules
- The
addx n
command first takes two CPU cycle, and only after that changes the register.
Part one
Now we have to sum the X register’s value in the 20th cycle and in every 40 cycles after that. This (with an additional
calculation) will give the Signal Strength
’s value, what we need to give to pass the puzzle.
The code
The code is so simple, I don’t waste too many characters to describe, how it works. Check it yourself:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$x = 1;
$cycle = 0;
$signalStrength = 0;
if ($fn = fopen(__DIR__ . '/input.txt', 'r')) {
while (($line = fgets($fn, 1024)) !== false) {
$line = trim($line);
$cycle++;
if ($cycle === 20 || ($cycle - 20) % 40 === 0) {
$signalStrength += $cycle * $x;
}
if ($line != 'noop') {
$cycle++;
if ($cycle === 20 || ($cycle - 20) % 40 === 0) {
$signalStrength += $cycle * $x;
}
[, $value] = explode(' ', $line);
$x += (int) $value;
}
}
fclose($fn);
}
echo $signalStrength.PHP_EOL;
Part two
The part two is a bit more complex, but should not confuse anybody. Here we have a small display screen
which is 40
characters wide and 6 characters tall. Luckily our input data contains exactly 240 CPU cycle (42 noop
and 99 addx
command).
So the input data is enough to fully fill the whole display with something. But with what? We move a pixel
on this screen,
and this pixel is 3 characters wide. The X register’s actual value contains the position of the middle character.
We draw on the screen exactly one character in every CPU cycle. The drawing position’s row and column is calculated from the CPU cycle.
- If the actual drawing position covers any of the three characters of the “pixel” - defined by X register - we draw
#
. - If no covering, we draw
.
.
In the end we should see some ASCII art letters printed on the screen. These letters are the solution for the puzzle.
The code
The description is actually more complex than the solution:
- Concatenate every
#
s and.
s together into a string. - We need to watch out for the screen size, when we reach the end, just add a line break.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$x = 1;
$cycle = 0;
$signalStrength = 0;
$crt = '';
$pixelPosition = 0;
if ($fn = fopen(__DIR__ . '/input.txt', 'r')) {
while (($line = fgets($fn, 1024)) !== false) {
$line = trim($line);
$cycle++;
$crt .= getPixel($x, $pixelPosition);
if ($line != 'noop') {
$cycle++;
$crt .= getPixel($x, $pixelPosition);
[, $value] = explode(' ', $line);
$x += (int) $value;
}
}
fclose($fn);
}
function getPixel(int $x, int &$pixelPosition): string
{
$pixel = ($x === $pixelPosition || $x - 1 === $pixelPosition || $x + 1 === $pixelPosition) ? '#' : '.';
$pixelPosition++;
if ($pixelPosition === 40) {
$pixel .= PHP_EOL;
$pixelPosition = 0;
}
return $pixel;
}
echo $crt.PHP_EOL;