Created
December 7, 2019 19:59
-
-
Save ludekstepan/493b80643ee230f2586b2337b5f4e5b1 to your computer and use it in GitHub Desktop.
Advent of code 2019
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Word = number | |
type Reader = Iterable<Word> | |
function* run(mem: Word[], input: () => Word) { | |
let position = 0 | |
function* program() { | |
while (position < mem.length) { | |
yield mem[position++] | |
} | |
} | |
function* params(opcode: Word) { | |
let power = 100 | |
for (const param of program()) { | |
const mode = Math.floor(opcode / power) % 10 | |
power *= 10 | |
yield mode ? param : mem[param] | |
} | |
} | |
const instructions: { | |
[code: number]: (params: Reader, raw: Reader) => Word | void | |
} = { | |
1: ([a, b], [dest]) => { | |
mem[dest] = a + b | |
}, | |
2: ([a, b], [dest]) => { | |
mem[dest] = a * b | |
}, | |
3: ([], [dest]) => { | |
mem[dest] = input() | |
}, | |
4: ([a]) => { | |
return a | |
}, | |
5: ([cond, addr]) => { | |
if (cond) { | |
position = addr | |
} | |
}, | |
6: ([cond, addr]) => { | |
if (!cond) { | |
position = addr | |
} | |
}, | |
7: ([a, b], [dest]) => { | |
mem[dest] = a < b ? 1 : 0 | |
}, | |
8: ([a, b], [dest]) => { | |
mem[dest] = a === b ? 1 : 0 | |
}, | |
99: () => { | |
position = Infinity | |
} | |
} | |
for (const opcode of program()) { | |
const instruction = instructions[opcode % 100] | |
if (!instruction) { | |
throw new Error(`Unknown opcode ${opcode}`) | |
} | |
const output = instruction(params(opcode), program()) | |
if (output) { | |
yield output | |
} | |
} | |
} | |
const mem = [3, 8, 1001, 8, 10, 8, 105, 1, 0, 0, 21, 46, 59, 84, 93, 110, 191, 272, 353, 434, 99999, 3, 9, 101, 2, 9, 9, 102, 3, 9, 9, 1001, 9, 5, 9, 102, 4, 9, 9, 1001, 9, 4, 9, 4, 9, 99, 3, 9, 101, 3, 9, 9, 102, 5, 9, 9, 4, 9, 99, 3, 9, 1001, 9, 4, 9, 1002, 9, 2, 9, 101, 2, 9, 9, 102, 2, 9, 9, 1001, 9, 3, 9, 4, 9, 99, 3, 9, 1002, 9, 2, 9, 4, 9, 99, 3, 9, 102, 2, 9, 9, 1001, 9, 5, 9, 1002, 9, 3, 9, 4, 9, 99, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 101, 2, 9, 9, 4, 9, 3, 9, 101, 2, 9, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 101, 2, 9, 9, 4, 9, 99, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 1001, 9, 2, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 1001, 9, 2, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 1001, 9, 2, 9, 4, 9, 99, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 99, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 2, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 99, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 1, 9, 4, 9, 3, 9, 101, 1, 9, 9, 4, 9, 3, 9, 102, 2, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 101, 2, 9, 9, 4, 9, 3, 9, 1002, 9, 2, 9, 4, 9, 3, 9, 1001, 9, 2, 9, 4, 9, 99] | |
function* amplifier(inputValues: Word[]) { | |
function input() { | |
return inputValues.shift()! | |
} | |
yield* run(mem, input) | |
} | |
function thrusters(phase: Word[]) { | |
const [ p1, p2, p3, p4, p5 ] = phase | |
const [a] = amplifier([p1, 0]) | |
const [b] = amplifier([p2, a]) | |
const [c] = amplifier([p3, b]) | |
const [d] = amplifier([p4, c]) | |
const [e] = amplifier([p5, d]) | |
return e | |
} | |
function combinations() { | |
const avail: Word[] = [0, 1, 2, 3, 4] | |
function * recur(used: Word[]): Iterable<Word[]> { | |
for (const i of ([0, 1, 2, 3, 4])) { | |
if (used.includes(i)) { | |
continue | |
} | |
const next = [...used, i] | |
if (next.length === 5) { | |
yield next | |
} else { | |
yield * recur(next) | |
} | |
} | |
} | |
return recur([]) | |
} | |
function* feed() { | |
for (const combination of combinations()) { | |
const thrust = thrusters(combination) | |
yield { combination, thrust } | |
} | |
} | |
const [x] = [...feed()].filter(a => a.thrust >0) | |
.sort((a, b) => b.thrust - a.thrust) | |
console.log(x) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment