61 lines
1.6 KiB
TypeScript
61 lines
1.6 KiB
TypeScript
const input = Deno.readTextFileSync('./input.txt').trimEnd().split('\n');
|
|
|
|
type State = { register: number; valX: number };
|
|
|
|
/**
|
|
* Returns Instruction list
|
|
* n=0: noop
|
|
* n!=0: addx n
|
|
*/
|
|
function getInstructions(input: Array<string>): Array<number> {
|
|
const instructions: Array<number> = [];
|
|
for (const line of input) {
|
|
const [type, value] = line.split(' ');
|
|
if (type === 'noop') {
|
|
instructions.push(0);
|
|
} else instructions.push(parseInt(value));
|
|
}
|
|
return instructions;
|
|
}
|
|
|
|
function getScreenChar(state: State): string {
|
|
let screenPos = (state.register % 40);
|
|
// Fix line wrap caused by modulo (as index starts at 1)
|
|
if (screenPos === 0) screenPos = 40;
|
|
|
|
if (screenPos >= state.valX && screenPos <= state.valX + 2) {
|
|
return '#';
|
|
}
|
|
return '.';
|
|
}
|
|
|
|
function* runCycles(instructions: Array<number>, register = 0, valX = 1): Generator<State> {
|
|
for (const instruction of instructions) {
|
|
register++;
|
|
yield { register: register, valX: valX };
|
|
if (instruction === 0) continue;
|
|
register++;
|
|
yield { register: register, valX: valX };
|
|
valX += instruction;
|
|
}
|
|
}
|
|
|
|
const instructions = getInstructions(input);
|
|
const checkCycles = new Set([20, 60, 100, 140, 180, 220]);
|
|
let p1 = 0;
|
|
let screen = '';
|
|
for (const state of runCycles(instructions)) {
|
|
// Relevant cycles Solution Part 1
|
|
if (checkCycles.has(state.register)) {
|
|
p1 += state.register * state.valX;
|
|
}
|
|
// Generate screen char for Part 2
|
|
screen += getScreenChar(state);
|
|
}
|
|
|
|
console.log('Solution Part 1:', p1);
|
|
console.log('Solution Part 2:');
|
|
for (const line of screen.match(/.{40}/g)!) {
|
|
console.log(line);
|
|
}
|