From 7fde4a549f807de8396530bbf53817b1e9e42b29 Mon Sep 17 00:00:00 2001 From: Joshua Seigler Date: Tue, 17 Dec 2024 02:30:34 -0500 Subject: [PATCH] day 17 part 1 done, part 2 requires more thought --- .aocrunner.json | 6 +- README.md | 10 ++-- src/day17/README.md | 9 +++ src/day17/index.ts | 137 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 7 deletions(-) create mode 100644 src/day17/README.md create mode 100644 src/day17/index.ts diff --git a/.aocrunner.json b/.aocrunner.json index 5630e4f..6d9ae99 100644 --- a/.aocrunner.json +++ b/.aocrunner.json @@ -253,9 +253,11 @@ }, { "part1": { - "solved": false, + "solved": true, "result": null, - "attempts": [], + "attempts": [ + "1,4,0,1,1,0,1,0,3" + ], "time": null }, "part2": { diff --git a/README.md b/README.md index 893d346..5c742f2 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ [![Day](https://badgen.net/badge/14/%E2%98%85%E2%98%86/yellow)](src/day14) [![Day](https://badgen.net/badge/15/%E2%98%85%E2%98%85/green)](src/day15) [![Day](https://badgen.net/badge/16/%E2%98%85%E2%98%85/green)](src/day16) -![Day](https://badgen.net/badge/17/%E2%98%86%E2%98%86/gray) +[![Day](https://badgen.net/badge/17/%E2%98%85%E2%98%86/yellow)](src/day17) ![Day](https://badgen.net/badge/18/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/19/%E2%98%86%E2%98%86/gray) ![Day](https://badgen.net/badge/20/%E2%98%86%E2%98%86/gray) @@ -181,9 +181,9 @@ Both parts: 132.546ms ``` Day 17 -Time part 1: - +Time part 1: 0.064ms Time part 2: - -Both parts: - +Both parts: 0.064ms ``` ``` @@ -243,8 +243,8 @@ Both parts: - ``` ``` -Total stars: 31/50 -Total time: 150841.213ms +Total stars: 32/50 +Total time: 150841.277ms ``` diff --git a/src/day17/README.md b/src/day17/README.md new file mode 100644 index 0000000..8cbc0f7 --- /dev/null +++ b/src/day17/README.md @@ -0,0 +1,9 @@ +# 🎄 Advent of Code 2024 - day 17 🎄 + +## Info + +Task description: [link](https://adventofcode.com/2024/day/17) + +## Notes + +... \ No newline at end of file diff --git a/src/day17/index.ts b/src/day17/index.ts new file mode 100644 index 0000000..560a0e4 --- /dev/null +++ b/src/day17/index.ts @@ -0,0 +1,137 @@ +import run from "aocrunner" + +const parseInput = (rawInput: string) => { + const [registers, program] = rawInput.split('\n\n') + return { + registers: registers.split('\n').map(r => BigInt(r.split(": ")[1])), + program: program.split(': ')[1].split(',').map(Number) + } +} + +const mod = (a: bigint, b: bigint) => ((a % b) + b) % b + +const explainProgram = (program: number[]) => { + let explanation = "" + const ops = [ + x => `A = A >> ${combo(x)}`, + x => `B = B XOR ${x}`, + x => `B = ${combo(x)} % 8`, + x => `GOTO ${x}`, + x => `B = B XOR C`, + x => `Output ${combo(x)} % 8`, + x => `B = B >> ${combo(x)}`, + x => `C = C >> ${combo(x)}`, + ] + const combo = x => "0123ABC"[x] + for (let i = 0; i < program.length; i += 2) { + const op = ops[program[i]](program[i+1]) + explanation += `${i}: ${op}\n` + } + return explanation.trim() +} + +const execute = (registers: bigint[], program: number[]) => { + let seenStates = new Set() + let [a, b, c] = registers + let pointer = 0 + const output: number[] = [] + const getCombo = (n: number) => [0n, 1n, 2n, 3n, a, b, c][n] + const ops: ((operand: number) => void)[] = [ + n => { // adv + a = a >> getCombo(n) + pointer += 2 + }, + n => { // bxl + b = b ^ BigInt(n) + pointer += 2 + }, + n => { // bst + b = mod(getCombo(n), 8n) + pointer += 2 + }, + n => { // jnz + pointer = a === 0n ? pointer + 2 : n + }, + n => { // bxc + b = b ^ c + pointer += 2 + }, + n => { // out + output.push(Number(mod(getCombo(n), 8n))) + pointer += 2 + }, + n => { // bdv + b = a >> getCombo(n) + pointer += 2 + }, + n => { // cdv + c = a >> getCombo(n) + pointer += 2 + }, + ] + while (true) { + const thisState = [a,b,c,pointer].join() + if (seenStates.has(thisState)) { + return 'LOOP' + } + if (pointer >= program.length) { + return output.join() + } + const opcode = program[pointer] + const operand = program[pointer + 1] + ops[opcode](operand) + } +} + +const part1 = (rawInput: string) => { + const { registers, program } = parseInput(rawInput) + return execute(registers, program) +} + + +const part2 = (rawInput: string) => { + const { registers: [_a, b, c], program } = parseInput(rawInput) + console.log(explainProgram(program)) + // const target = program.join() + // let i = 1n + // while (true) { + // const result = execute([i, b, c], program) + // if (result.length < target.length) i *= 2n + // if (result === target) { + // return i + // } + // console.log(`${i} ${result}`) + // i += 1n + // } +} + +run({ +// part1: { +// tests: [ +// { +// input: `Register A: 729 +// Register B: 0 +// Register C: 0 + +// Program: 0,1,5,4,3,0`, +// expected: `4,6,3,5,6,3,5,2,1,0`, +// }, +// ], +// solution: part1, +// }, + part2: { + tests: [ + { + input: `Register A: 2024 +Register B: 0 +Register C: 0 + +Program: 0,3,5,4,3,0`, + expected: 117440, + }, + ], + solution: part2, + }, + trimTestInputs: true, + onlyTests: false, +})