Solve 2024-17
This commit is contained in:
+1
-4
@@ -7,10 +7,7 @@ import {
|
|||||||
type CoordinateSides,
|
type CoordinateSides,
|
||||||
isCoordinateEqual
|
isCoordinateEqual
|
||||||
} from '../../utils/coordinates.ts';
|
} from '../../utils/coordinates.ts';
|
||||||
|
import { mod } from '../../utils/numbers.ts';
|
||||||
function mod(x: number, m: number) {
|
|
||||||
return ((x % m) + m) % m;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function solveFirst(
|
export function solveFirst(
|
||||||
input: string,
|
input: string,
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="2024-17" type="BunRunConfiguration">
|
||||||
|
<option name="program" value="2024/17/run.ts" />
|
||||||
|
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { describe, expect, it } from 'bun:test';
|
||||||
|
import { solveFirst, solveSecond } from './index.ts';
|
||||||
|
|
||||||
|
describe('2024-17', () => {
|
||||||
|
it('first', () => {
|
||||||
|
const testInput = `Register A: 729
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,1,5,4,3,0`;
|
||||||
|
expect(solveFirst(testInput)).toBe('4,6,3,5,6,3,5,2,1,0');
|
||||||
|
});
|
||||||
|
it('second', () => {
|
||||||
|
const testInput = `Register A: 2024
|
||||||
|
Register B: 0
|
||||||
|
Register C: 0
|
||||||
|
|
||||||
|
Program: 0,3,5,4,3,0`;
|
||||||
|
expect(solveSecond(testInput)).toBe(117440);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
import { unsignedXOR } from '../../utils/numbers.ts';
|
||||||
|
|
||||||
|
const Instructions = {
|
||||||
|
adv: 0,
|
||||||
|
bxl: 1,
|
||||||
|
bst: 2,
|
||||||
|
jnz: 3,
|
||||||
|
bxc: 4,
|
||||||
|
out: 5,
|
||||||
|
bdv: 6,
|
||||||
|
cdv: 7
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
type Instruction = (typeof Instructions)[keyof typeof Instructions];
|
||||||
|
|
||||||
|
function runCode(
|
||||||
|
instructions: Instruction[],
|
||||||
|
regA: number,
|
||||||
|
regB: number,
|
||||||
|
regC: number
|
||||||
|
) {
|
||||||
|
let instructionPointer = 0;
|
||||||
|
const output: number[] = [];
|
||||||
|
|
||||||
|
while (instructionPointer < instructions.length) {
|
||||||
|
let instruction = instructions[instructionPointer];
|
||||||
|
let operand = instructions[instructionPointer + 1];
|
||||||
|
let comboOperand: number = operand;
|
||||||
|
if (operand === 4) {
|
||||||
|
comboOperand = regA;
|
||||||
|
} else if (operand === 5) {
|
||||||
|
comboOperand = regB;
|
||||||
|
} else if (operand === 6) {
|
||||||
|
comboOperand = regC;
|
||||||
|
}
|
||||||
|
|
||||||
|
let jumped = false;
|
||||||
|
// console.log(regA, regB, regC, instruction, operand);
|
||||||
|
switch (instruction) {
|
||||||
|
case Instructions.adv:
|
||||||
|
regA = Math.floor(regA / Math.pow(2, comboOperand));
|
||||||
|
break;
|
||||||
|
case Instructions.bdv:
|
||||||
|
regB = Math.floor(regA / Math.pow(2, comboOperand));
|
||||||
|
break;
|
||||||
|
case Instructions.cdv:
|
||||||
|
regC = Math.floor(regA / Math.pow(2, comboOperand));
|
||||||
|
break;
|
||||||
|
case Instructions.bxl:
|
||||||
|
regB = unsignedXOR(regB, operand);
|
||||||
|
break;
|
||||||
|
case Instructions.bst:
|
||||||
|
regB = comboOperand % 8;
|
||||||
|
break;
|
||||||
|
case Instructions.jnz:
|
||||||
|
if (regA !== 0) {
|
||||||
|
instructionPointer = operand;
|
||||||
|
jumped = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Instructions.bxc:
|
||||||
|
regB = unsignedXOR(regB, regC);
|
||||||
|
break;
|
||||||
|
case Instructions.out:
|
||||||
|
output.push(comboOperand % 8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!jumped) {
|
||||||
|
instructionPointer += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solveFirst(input: string): string {
|
||||||
|
const match = input.match(
|
||||||
|
/^Register A: (\d*)\nRegister B: (\d*)\nRegister C: (\d*)\n\nProgram: ([\d,]*)$/m
|
||||||
|
);
|
||||||
|
if (!match) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const instructions = match[4].split(',').map(Number) as Instruction[];
|
||||||
|
return runCode(
|
||||||
|
instructions,
|
||||||
|
Number(match[1]),
|
||||||
|
Number(match[2]),
|
||||||
|
Number(match[3])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solveSecond(input: string): number {
|
||||||
|
const match = input.match(
|
||||||
|
/^Register A: (\d*)\nRegister B: (\d*)\nRegister C: (\d*)\n\nProgram: ([\d,]*)$/m
|
||||||
|
);
|
||||||
|
if (!match) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const instructions = match[4].split(',').map(Number) as Instruction[];
|
||||||
|
|
||||||
|
const regB = Number(match[2]);
|
||||||
|
const regC = Number(match[3]);
|
||||||
|
|
||||||
|
const possible: { result: string; length: number }[] = [];
|
||||||
|
possible.push({ result: '', length: 0 });
|
||||||
|
while (possible.length) {
|
||||||
|
const { result, length } = possible.shift()!;
|
||||||
|
if (length === instructions.length) {
|
||||||
|
return parseInt(result, 2);
|
||||||
|
}
|
||||||
|
const from = parseInt(`${result}000`, 2);
|
||||||
|
const to = parseInt(`${result}111`, 2);
|
||||||
|
|
||||||
|
const expect = instructions.slice(-(length + 1)).join(',');
|
||||||
|
for (let regA = from; regA <= to; regA++) {
|
||||||
|
const r = runCode(instructions, regA, regB, regC);
|
||||||
|
if (r === expect) {
|
||||||
|
possible.push({ result: regA.toString(2), length: length + 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
import { solveFirst, solveSecond } from './index.ts';
|
||||||
|
|
||||||
|
const input = await Bun.file(join(__dirname, 'input.txt')).text();
|
||||||
|
|
||||||
|
const firstAnswer = solveFirst(input);
|
||||||
|
|
||||||
|
console.log(firstAnswer);
|
||||||
|
|
||||||
|
const secondAnswer = solveSecond(input);
|
||||||
|
|
||||||
|
console.log(secondAnswer);
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export function mod(x: number, m: number) {
|
||||||
|
return ((x % m) + m) % m;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsignedXOR(a: number, b: number) {
|
||||||
|
return (a ^ b) >>> 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user