|
1 |
| -import * as fs from "fs" |
| 1 | +import * as fs from "fs" |
2 | 2 |
|
3 |
| -const input = [5] |
| 3 | +function load(program: string) { |
| 4 | + return fs.readFileSync(program, "utf8") |
| 5 | + .split(",") |
| 6 | + .map(l => parseInt(l)) |
| 7 | +} |
| 8 | + |
| 9 | +const program = load("input-day7.txt") |
| 10 | + |
| 11 | +//const program = [3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0] |
| 12 | + |
| 13 | +function thruster(input: number[]): number { |
| 14 | + const out = compute(program, input) |
| 15 | + return out[out.length - 1] |
| 16 | +} |
| 17 | +function thrusterChain(phases: number[]): number { |
| 18 | + const p = phases.slice() |
| 19 | + let out = thruster([p.shift(), 0]) |
| 20 | + while (p.length) { |
| 21 | + out = thruster([p.shift(), out]) |
| 22 | + } |
| 23 | + return out |
| 24 | +} |
4 | 25 |
|
5 |
| -const mem = fs.readFileSync("input-day5.txt", "utf8") |
6 |
| - .split(",") |
7 |
| - .map(l => parseInt(l)) |
| 26 | +const phases = [0, 1, 2, 3, 4] |
| 27 | +const allPhases = permutate(phases) |
| 28 | +const maxThrust = allPhases.reduce((acc, v) => { |
| 29 | + return Math.max(acc, thrusterChain(v)) |
| 30 | +}, 0) |
| 31 | +console.log(maxThrust) |
8 | 32 |
|
9 |
| -let iptr = 0 |
| 33 | +function permutate(a: number[]): number[][] { |
| 34 | + if (a.length == 1) { |
| 35 | + return [a] |
| 36 | + } |
| 37 | + return Array(a.length).fill(0) |
| 38 | + .map((_, i) => { |
| 39 | + const c = a.slice() |
| 40 | + return [c.splice(i, 1)[0], c] as const |
| 41 | + }) |
| 42 | + .reduce((acc, [prefix, rest]) => { |
| 43 | + permutate(rest) |
| 44 | + .map(p => [prefix, ...p]) |
| 45 | + .forEach(p => acc.push(p)) |
| 46 | + return acc |
| 47 | + }, []) |
| 48 | +} |
10 | 49 |
|
11 |
| -while(true) { |
12 |
| - const code = mem[iptr] |
13 |
| - const op = code % 100 |
14 |
| - const modes = [code % 1000 / 100, code % 10000 / 1000, code % 100000 / 10000].map(Math.floor) |
| 50 | +function compute(p: number[], input: number[]): number[] { |
| 51 | + const mem = p.slice() |
| 52 | + const outputs = [] |
| 53 | + let iptr = 0 |
| 54 | + while (true) { |
| 55 | + const code = mem[iptr] |
| 56 | + const op = code % 100 |
| 57 | + const modes = [code % 1000 / 100, code % 10000 / 1000, code % 100000 / 10000].map(Math.floor) |
15 | 58 |
|
16 |
| - switch(op) { |
17 |
| - case 1: |
18 |
| - iptr = add(iptr, mem, modes) |
19 |
| - break |
20 |
| - case 2: |
21 |
| - iptr = mul(iptr, mem, modes) |
22 |
| - break |
23 |
| - case 3: |
24 |
| - iptr = get(iptr, mem, modes) |
25 |
| - break |
26 |
| - case 4: |
27 |
| - iptr = put(iptr, mem, modes) |
28 |
| - break |
29 |
| - case 5: |
30 |
| - iptr = jnz(iptr, mem, modes) |
31 |
| - break |
32 |
| - case 6: |
33 |
| - iptr = jz(iptr, mem, modes) |
34 |
| - break |
35 |
| - case 7: |
36 |
| - iptr = lt(iptr, mem, modes) |
37 |
| - break |
38 |
| - case 8: |
39 |
| - iptr = eq(iptr, mem, modes) |
40 |
| - break |
41 |
| - case 99: |
42 |
| - process.exit(0) |
43 |
| - break |
44 |
| - default: throw new Error(`unknown instruction ${mem[iptr]}`) |
| 59 | + switch (op) { |
| 60 | + case 1: |
| 61 | + iptr = add(iptr, mem, modes) |
| 62 | + break |
| 63 | + case 2: |
| 64 | + iptr = mul(iptr, mem, modes) |
| 65 | + break |
| 66 | + case 3: |
| 67 | + iptr = get(iptr, mem, modes, input) |
| 68 | + break |
| 69 | + case 4: |
| 70 | + const [newIptr, output] = put(iptr, mem, modes) |
| 71 | + iptr = newIptr |
| 72 | + //outputs.push(output) |
| 73 | + return [output] |
| 74 | + break |
| 75 | + case 5: |
| 76 | + iptr = jnz(iptr, mem, modes) |
| 77 | + break |
| 78 | + case 6: |
| 79 | + iptr = jz(iptr, mem, modes) |
| 80 | + break |
| 81 | + case 7: |
| 82 | + iptr = lt(iptr, mem, modes) |
| 83 | + break |
| 84 | + case 8: |
| 85 | + iptr = eq(iptr, mem, modes) |
| 86 | + break |
| 87 | + case 99: |
| 88 | + return outputs |
| 89 | + default: throw new Error(`unknown instruction ${mem[iptr]}`) |
| 90 | + } |
45 | 91 | }
|
46 | 92 | }
|
47 | 93 |
|
48 |
| -function v(ptr: number, mode: number) { |
49 |
| - if(mode === 0) { |
| 94 | +function v(mem: number[], ptr: number, mode: number) { |
| 95 | + if (mode === 0) { |
50 | 96 | return mem[mem[ptr]]
|
51 |
| - } else if(mode === 1) { |
| 97 | + } else if (mode === 1) { |
52 | 98 | return mem[ptr]
|
53 | 99 | }
|
54 | 100 | throw new Error(`unknown mode ${mode}`)
|
55 | 101 | }
|
56 | 102 |
|
57 | 103 | function add(iptr: number, mem: number[], modes: number[]) {
|
58 |
| - mem[mem[iptr+3]] = v(iptr+1, modes[0]) + v(iptr+2, modes[1]) |
| 104 | + mem[mem[iptr + 3]] = v(mem, iptr + 1, modes[0]) + v(mem, iptr + 2, modes[1]) |
59 | 105 | return iptr + 4
|
60 | 106 | }
|
61 | 107 | function mul(iptr: number, mem: number[], modes: number[]) {
|
62 |
| - mem[mem[iptr+3]] = v(iptr+1, modes[0]) * v(iptr+2, modes[1]) |
| 108 | + mem[mem[iptr + 3]] = v(mem, iptr + 1, modes[0]) * v(mem, iptr + 2, modes[1]) |
63 | 109 | return iptr + 4
|
64 | 110 | }
|
65 | 111 | function put(iptr: number, mem: number[], modes: number[]) {
|
66 |
| - console.log(v(iptr+1, modes[0])) |
67 |
| - return iptr + 2 |
| 112 | + return [iptr + 2, v(mem, iptr + 1, modes[0])] |
68 | 113 | }
|
69 |
| -function get(iptr: number, mem: number[], modes: number[]) { |
70 |
| - mem[mem[iptr+1]] = input.shift() |
| 114 | +function get(iptr: number, mem: number[], modes: number[], input: number[]) { |
| 115 | + mem[mem[iptr + 1]] = input.shift() |
71 | 116 | return iptr + 2
|
72 | 117 | }
|
73 | 118 | function jnz(iptr: number, mem: number[], modes: number[]) {
|
74 |
| - if(v(iptr+1, modes[0]) !== 0) { |
75 |
| - return v(iptr+2, modes[1]) |
| 119 | + if (v(mem, iptr + 1, modes[0]) !== 0) { |
| 120 | + return v(mem, iptr + 2, modes[1]) |
76 | 121 | }
|
77 | 122 | return iptr + 3
|
78 | 123 | }
|
79 | 124 | function jz(iptr: number, mem: number[], modes: number[]) {
|
80 |
| - if(v(iptr+1, modes[0]) === 0) { |
81 |
| - return v(iptr+2, modes[1]) |
| 125 | + if (v(mem, iptr + 1, modes[0]) === 0) { |
| 126 | + return v(mem, iptr + 2, modes[1]) |
82 | 127 | }
|
83 | 128 | return iptr + 3
|
84 | 129 | }
|
85 | 130 | function lt(iptr: number, mem: number[], modes: number[]) {
|
86 |
| - const val = (v(iptr+1, modes[0]) < v(iptr+2, modes[1])) ? 1 : 0 |
87 |
| - mem[mem[iptr+3]] = val |
| 131 | + const val = (v(mem, iptr + 1, modes[0]) < v(mem, iptr + 2, modes[1])) ? 1 : 0 |
| 132 | + mem[mem[iptr + 3]] = val |
88 | 133 | return iptr + 4
|
89 | 134 | }
|
90 | 135 | function eq(iptr: number, mem: number[], modes: number[]) {
|
91 |
| - const val = (v(iptr+1, modes[0]) === v(iptr+2, modes[1])) ? 1 : 0 |
92 |
| - mem[mem[iptr+3]] = val |
| 136 | + const val = (v(mem, iptr + 1, modes[0]) === v(mem, iptr + 2, modes[1])) ? 1 : 0 |
| 137 | + mem[mem[iptr + 3]] = val |
93 | 138 | return iptr + 4
|
94 | 139 | }
|
0 commit comments