day 17 part 2, wow

This commit is contained in:
Joshua Seigler 2024-12-17 11:20:59 -05:00
parent 7fde4a549f
commit 4f6e500b7a
No known key found for this signature in database
3 changed files with 74 additions and 66 deletions

View file

@ -254,17 +254,17 @@
{ {
"part1": { "part1": {
"solved": true, "solved": true,
"result": null, "result": "1,5,0,1,7,4,1,0,3",
"attempts": [ "attempts": [
"1,4,0,1,1,0,1,0,3" "1,4,0,1,1,0,1,0,3"
], ],
"time": null "time": 0.057416
}, },
"part2": { "part2": {
"solved": false, "solved": true,
"result": null, "result": "47910079998866",
"attempts": [], "attempts": [],
"time": null "time": 8772.936208
} }
}, },
{ {

View file

@ -27,7 +27,7 @@
[![Day](https://badgen.net/badge/14/%E2%98%85%E2%98%86/yellow)](src/day14) [![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/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/16/%E2%98%85%E2%98%85/green)](src/day16)
[![Day](https://badgen.net/badge/17/%E2%98%85%E2%98%86/yellow)](src/day17) [![Day](https://badgen.net/badge/17/%E2%98%85%E2%98%85/green)](src/day17)
![Day](https://badgen.net/badge/18/%E2%98%86%E2%98%86/gray) ![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/19/%E2%98%86%E2%98%86/gray)
![Day](https://badgen.net/badge/20/%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 Day 17
Time part 1: 0.064ms Time part 1: -
Time part 2: - Time part 2: 8693.239ms
Both parts: 0.064ms Both parts: 8693.239ms
``` ```
``` ```
@ -243,8 +243,8 @@ Both parts: -
``` ```
``` ```
Total stars: 32/50 Total stars: 33/50
Total time: 150841.277ms Total time: 159534.453ms
``` ```
<!--/RESULTS--> <!--/RESULTS-->

View file

@ -1,10 +1,10 @@
import run from "aocrunner" import run from "aocrunner"
const parseInput = (rawInput: string) => { const parseInput = (rawInput: string) => {
const [registers, program] = rawInput.split('\n\n') const [registers, program] = rawInput.split("\n\n")
return { return {
registers: registers.split('\n').map(r => BigInt(r.split(": ")[1])), registers: registers.split("\n").map((r) => BigInt(r.split(": ")[1])),
program: program.split(': ')[1].split(',').map(Number) program: program.split(": ")[1].split(",").map(Number),
} }
} }
@ -12,70 +12,65 @@ const mod = (a: bigint, b: bigint) => ((a % b) + b) % b
const explainProgram = (program: number[]) => { const explainProgram = (program: number[]) => {
let explanation = "" let explanation = ""
const ops = [ const ops: ((x: number) => void)[] = [
x => `A = A >> ${combo(x)}`, (x) => `A = A >> ${combo(x)}`,
x => `B = B XOR ${x}`, (x) => `B = B XOR ${x}`,
x => `B = ${combo(x)} % 8`, (x) => `B = ${combo(x)} % 8`,
x => `GOTO ${x}`, (x) => `GOTO ${x}`,
x => `B = B XOR C`, () => `B = B XOR C`,
x => `Output ${combo(x)} % 8`, (x) => `Output ${combo(x)} % 8`,
x => `B = B >> ${combo(x)}`, (x) => `B = B >> ${combo(x)}`,
x => `C = C >> ${combo(x)}`, (x) => `C = C >> ${combo(x)}`,
] ]
const combo = x => "0123ABC"[x] const combo = (x: number) => "0123ABC"[x]
for (let i = 0; i < program.length; i += 2) { for (let i = 0; i < program.length; i += 2) {
const op = ops[program[i]](program[i+1]) const op = ops[program[i]](program[i + 1])
explanation += `${i}: ${op}\n` explanation += `${i}: ${op}\n`
} }
return explanation.trim() return explanation
} }
const execute = (registers: bigint[], program: number[]) => { const execute = (registers: bigint[], program: number[]) => {
let seenStates = new Set<string>()
let [a, b, c] = registers let [a, b, c] = registers
let pointer = 0 let pointer = 0
const output: number[] = [] const output: number[] = []
const getCombo = (n: number) => [0n, 1n, 2n, 3n, a, b, c][n] const getCombo = (n: number) => [0n, 1n, 2n, 3n, a, b, c][n]
const ops: ((operand: number) => void)[] = [ const ops: ((operand: number) => void)[] = [
n => { // adv function adv(n) {
a = a >> getCombo(n) a = a >> getCombo(n)
pointer += 2 pointer += 2
}, },
n => { // bxl function bxl(n) {
b = b ^ BigInt(n) b = b ^ BigInt(n)
pointer += 2 pointer += 2
}, },
n => { // bst function bst(n) {
b = mod(getCombo(n), 8n) b = mod(getCombo(n), 8n)
pointer += 2 pointer += 2
}, },
n => { // jnz function jnz(n) {
pointer = a === 0n ? pointer + 2 : n pointer = a === 0n ? pointer + 2 : n
}, },
n => { // bxc function bxc(_) {
b = b ^ c b = b ^ c
pointer += 2 pointer += 2
}, },
n => { // out function out(n) {
output.push(Number(mod(getCombo(n), 8n))) output.push(Number(mod(getCombo(n), 8n)))
pointer += 2 pointer += 2
}, },
n => { // bdv function bdv(n) {
b = a >> getCombo(n) b = a >> getCombo(n)
pointer += 2 pointer += 2
}, },
n => { // cdv function cdv(n) {
c = a >> getCombo(n) c = a >> getCombo(n)
pointer += 2 pointer += 2
}, },
] ]
while (true) { while (true) {
const thisState = [a,b,c,pointer].join()
if (seenStates.has(thisState)) {
return 'LOOP'
}
if (pointer >= program.length) { if (pointer >= program.length) {
return output.join() return output
} }
const opcode = program[pointer] const opcode = program[pointer]
const operand = program[pointer + 1] const operand = program[pointer + 1]
@ -85,40 +80,53 @@ const execute = (registers: bigint[], program: number[]) => {
const part1 = (rawInput: string) => { const part1 = (rawInput: string) => {
const { registers, program } = parseInput(rawInput) const { registers, program } = parseInput(rawInput)
return execute(registers, program) return execute(registers, program).join()
} }
const part2 = (rawInput: string) => { const part2 = (rawInput: string) => {
const { registers: [_a, b, c], program } = parseInput(rawInput) const {
registers: [_a, b, c],
program,
} = parseInput(rawInput)
console.log(explainProgram(program)) console.log(explainProgram(program))
// const target = program.join()
// let i = 1n let i = 0n
// while (true) { let found = 0
// const result = execute([i, b, c], program) while (true) {
// if (result.length < target.length) i *= 2n const result = execute([i, b, c], program)
// if (result === target) { console.log(`${i} ${result.join()}`)
// return i let matchCount = 0
// } for (let j = 0; j < result.length; j++) {
// console.log(`${i} ${result}`) if (result[result.length - 1 - j] === program[program.length - 1 - j]) {
// i += 1n matchCount++
// } } else break
}
if (matchCount === program.length) {
return Number(i)
}
if (matchCount > found) {
i = i << (3n * BigInt(matchCount - found))
found = matchCount
} else {
i++
}
}
} }
run({ run({
// part1: { part1: {
// tests: [ tests: [
// { {
// input: `Register A: 729 input: `Register A: 729
// Register B: 0 Register B: 0
// Register C: 0 Register C: 0
// Program: 0,1,5,4,3,0`, Program: 0,1,5,4,3,0`,
// expected: `4,6,3,5,6,3,5,2,1,0`, expected: `4,6,3,5,6,3,5,2,1,0`,
// }, },
// ], ],
// solution: part1, solution: part1,
// }, },
part2: { part2: {
tests: [ tests: [
{ {