# Advent of Code 2022: Day 10

A TypeScript solution for the Advent of Code 2022, Day 10 puzzle: emulating CPU instructions and rendering to a virtual screen.

Today’s puzzle asks us to read a set of CPU instructions that draw a signal to an imaginary CRT screen.

The example input looks like this.

```noop
```

What’s challenging about today’s puzzle conditions is that the instructions vary in the duration of CPU cycles (`noop` takes one cycle and `addx` takes two cycles), and because of timing issues, we have to track the cycle count carefully and separately from the instruction count.

We start, as always, by splitting the puzzle input into a more manageable data structure: a list of instructions with a `cmd` and an optional integer `arg`.

```const instructions = puzzleInput.split('\n')
.map(line => line.split(' '))
.map(([cmd, arg]) => ({cmd, arg: parseInt(arg)}));
```

Because I was trying to compete for time1 today, I went with a fully imperative approach in a giant block of code, similar in strategy to many of the top competitors. Check out the comments for more details ðŸ˜ƒ

These variables track the state of the emulator, and accumulate values for our part 1 and part 2 answers.

```let part1 = 0     // signal strength sum
let part2 = '\n'; // CRT screen output
let x = 1;        // X register value
let cycles = 0;   // clock/cycles/ticks
```

And the emulation is basically a couple of nested loops: one to iterate through each instruction, and one to handle the individual cycles.

```for (const { cmd, arg } of instructions) {
// Switch on the cmd to figure out how long
// the instruction will run
let duration = cmd === 'addx' ? 2 : 1;

// The inner loop simulates the instruction
// for its given number of cycles, and handles the
// cycle updating logic + answer accumulation
while (duration > 0) {
// Construct the sprite by drawing lit pixels
// at the X position and 1 pixel either side
const sprite = Array(40).fill(0)
.map((_, i) => [x-1,x,x+1].includes(i) ? '▓' : '░')

// Render the correct part of the sprite
// depending on the previous cycle
part2 += sprite[cycles % 40];

// Increment the cycle count
cycles++;

// In the middle of each line of 40 cycles,
// calculate signal strength and accumulate
if ((cycles - 20) % 40 === 0 && cycles <= 220)
part1 += x * cycles;

// After each line of 40 cycles,
// switch to a new line on the CRT output
if (cycles % 40 === 0)
part2 += '\n';

duration--;
}
// Updating the X value always occurs at the
// end of the duration of the 'addx' instruction
if (cmd === 'addx' && !!arg)
x += arg;
}
```

## Final Solution

```const instructions = puzzleInput.split('\n')
.map(line => line.split(' '))
.map(([cmd, arg]) => ({cmd, arg: parseInt(arg)}));

let part1 = 0     // signal strength sum
let part2 = '\n'; // CRT screen output
let x = 1;        // X register value
let cycles = 0;   // clock/cycles/ticks

for (const { cmd, arg } of instructions) {
// Switch on the cmd to figure out how long
// the instruction will run
let duration = cmd === 'addx' ? 2 : 1;

// The inner loop simulates the instruction
// for its given number of cycles, and handles the
// cycle updating logic + answer accumulation
while (duration > 0) {
// Construct the sprite by drawing lit pixels
// at the X position and 1 pixel either side
const sprite = Array(40).fill(0)
.map((_, i) => [x-1,x,x+1].includes(i) ? '▓' : '░')

// Render the correct part of the sprite
// depending on the previous cycle
part2 += sprite[cycles % 40];

// Increment the cycle count
cycles++;

// In the middle of each line of 40 cycles,
// calculate signal strength and accumulate
if ((cycles - 20) % 40 === 0 && cycles <= 220)
part1 += x * cycles;

// After each line of 40 cycles,
// switch to a new line on the CRT output
if (cycles % 40 === 0)
part2 += '\n';

duration--;
}
// Updating the X value always occurs at the
// end of the duration of the 'addx' instruction
if (cmd === 'addx' && !!arg)
x += arg;
}

console.log("Part 1:", part1);
console.log("Part 2:", part2);
```
```Part 1: 14420
Part 2:
▓▓▓░░░▓▓░░▓░░░░▓▓▓░░▓▓▓░░▓▓▓▓░░▓▓░░▓░░▓░
▓░░▓░▓░░▓░▓░░░░▓░░▓░▓░░▓░░░░▓░▓░░▓░▓░░▓░
▓░░▓░▓░░░░▓░░░░▓░░▓░▓▓▓░░░░▓░░▓░░▓░▓░░▓░
▓▓▓░░▓░▓▓░▓░░░░▓▓▓░░▓░░▓░░▓░░░▓▓▓▓░▓░░▓░
▓░▓░░▓░░▓░▓░░░░▓░▓░░▓░░▓░▓░░░░▓░░▓░▓░░▓░
▓░░▓░░▓▓▓░▓▓▓▓░▓░░▓░▓▓▓░░▓▓▓▓░▓░░▓░░▓▓░░

```

## Footnotes:

1

I got rank 2939 for part 1 in 00:16:29, and rank 1856 for part 2 in 00:27:43. Nowhere near the leaderboard ðŸ˜…