Solve day 19 part 2
This commit is contained in:
parent
c31d6e53c2
commit
069a2b6298
4 changed files with 146 additions and 45 deletions
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"typeindex": "c",
|
||||||
|
"typeinfo": "c"
|
||||||
|
}
|
||||||
|
}
|
101
Day19/Day19A.c
101
Day19/Day19A.c
|
@ -40,50 +40,57 @@ int instruction_read(Instruction *i, FILE *file) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void instruction_execute(const Instruction *i, uint32_t *r, uint32_t *ip, uint32_t *ip_r) {
|
void instruction_execute(const Instruction* instructions, uint32_t* r, uint32_t* ip_r) {
|
||||||
if (*ip_r != -1)
|
const Instruction i = instructions[r[*ip_r]];
|
||||||
r[*ip_r] = *ip;
|
|
||||||
|
|
||||||
switch (i->opcode) {
|
#ifdef DEBUG
|
||||||
|
const char *name = names[i.opcode];
|
||||||
|
printf(
|
||||||
|
"ip=%2u [%10u, %10u, %10u, %10u, %10u, %10u] %4s %2u %2u %2u ",
|
||||||
|
r[*ip_r], r[0], r[1], r[2], r[3], r[4], r[5], name, i.a, i.b, i.c
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (i.opcode) {
|
||||||
// Addition
|
// Addition
|
||||||
case ADDR: r[i->c] = r[i->a] + r[i->b]; break;
|
case ADDR: r[i.c] = r[i.a] + r[i.b]; break;
|
||||||
case ADDI: r[i->c] = r[i->a] + i->b; break;
|
case ADDI: r[i.c] = r[i.a] + i.b; break;
|
||||||
|
|
||||||
// Multiplication
|
// Multiplication
|
||||||
case MULR: r[i->c] = r[i->a] * r[i->b]; break;
|
case MULR: r[i.c] = r[i.a] * r[i.b]; break;
|
||||||
case MULI: r[i->c] = r[i->a] * i->b; break;
|
case MULI: r[i.c] = r[i.a] * i.b; break;
|
||||||
|
|
||||||
// Bitwise AND
|
// Bitwise AND
|
||||||
case BANR: r[i->c] = (r[i->a] & r[i->b]); break;
|
case BANR: r[i.c] = (r[i.a] & r[i.b]); break;
|
||||||
case BANI: r[i->c] = (r[i->a] & i->b); break;
|
case BANI: r[i.c] = (r[i.a] & i.b); break;
|
||||||
|
|
||||||
// Bitwise OR
|
// Bitwise OR
|
||||||
case BORR: r[i->c] = (r[i->a] | r[i->b]); break;
|
case BORR: r[i.c] = (r[i.a] | r[i.b]); break;
|
||||||
case BORI: r[i->c] = (r[i->a] | i->b); break;
|
case BORI: r[i.c] = (r[i.a] | i.b); break;
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
case SETR: r[i->c] = r[i->a]; break;
|
case SETR: r[i.c] = r[i.a]; break;
|
||||||
case SETI: r[i->c] = i->a; break;
|
case SETI: r[i.c] = i.a; break;
|
||||||
|
|
||||||
// Greater-than testing
|
// Greater-than testing
|
||||||
case GTIR: r[i->c] = (i->a > r[i->b]); break;
|
case GTIR: r[i.c] = (i.a > r[i.b]); break;
|
||||||
case GTRI: r[i->c] = (r[i->a] > i->b); break;
|
case GTRI: r[i.c] = (r[i.a] > i.b); break;
|
||||||
case GTRR: r[i->c] = (r[i->a] > r[i->b]); break;
|
case GTRR: r[i.c] = (r[i.a] > r[i.b]); break;
|
||||||
|
|
||||||
// Equality testing
|
// Equality testing
|
||||||
case EQIR: r[i->c] = (i->a == r[i->b]); break;
|
case EQIR: r[i.c] = (i.a == r[i.b]); break;
|
||||||
case EQRI: r[i->c] = (r[i->a] == i->b); break;
|
case EQRI: r[i.c] = (r[i.a] == i.b); break;
|
||||||
case EQRR: r[i->c] = (r[i->a] == r[i->b]); break;
|
case EQRR: r[i.c] = (r[i.a] == r[i.b]); break;
|
||||||
|
|
||||||
case IP: *ip_r = i->a; *ip -= 1; break;
|
|
||||||
|
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*ip_r != -1)
|
#ifdef DEBUG
|
||||||
*ip = r[*ip_r];
|
printf("[%10u, %10u, %10u, %10u, %10u, %10u]\r", r[0], r[1], r[2], r[3], r[4], r[5]);
|
||||||
|
#endif
|
||||||
|
getchar();
|
||||||
|
|
||||||
*ip += 1;
|
r[*ip_r] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
@ -94,35 +101,41 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
FILE *file = fopen(argv[1], "r");
|
FILE *file = fopen(argv[1], "r");
|
||||||
|
|
||||||
uint32_t registers[6] = {0};
|
#ifdef DEBUG
|
||||||
uint32_t ip_reg = -1;
|
puts("=================");
|
||||||
|
puts(" READING INPUT");
|
||||||
|
puts("=================");
|
||||||
|
#endif
|
||||||
|
uint32_t registers[6] = {1, 0};
|
||||||
|
uint32_t ip_reg = 0;
|
||||||
size_t instr_count = 0;
|
size_t instr_count = 0;
|
||||||
for (instr_count = 0; instr_count < 1024 && instruction_read(&instructions[instr_count], file); instr_count++) {
|
for (instr_count = 0; instr_count < 1024 && instruction_read(&instructions[instr_count], file); instr_count++) {
|
||||||
#ifdef DEBUG
|
const Instruction instr = instructions[instr_count];
|
||||||
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instructions[instr_count].opcode,
|
if (instr.opcode == IP) {
|
||||||
names[instructions[instr_count].opcode], instructions[instr_count].a, instructions[instr_count].b,
|
// Assuming that an #ip can only occur once here
|
||||||
instructions[instr_count].c);
|
ip_reg = instr.a;
|
||||||
#endif
|
instr_count -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < instr_count;) {
|
|
||||||
Instruction instruction = instructions[i];
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
const char *name = names[instruction.opcode];
|
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instr.opcode, names[instr.opcode], instr.a, instr.b, instr.c);
|
||||||
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instruction.opcode,
|
|
||||||
name, instruction.a, instruction.b, instruction.c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
instruction_execute(&instruction, registers, &i, &ip_reg);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("registers: %d %d %d %d %d %d\n", registers[0], registers[1],
|
|
||||||
registers[2], registers[3], registers[4], registers[5]);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
puts("");
|
||||||
|
puts("=======================");
|
||||||
|
puts(" STARTING SIMULATION");
|
||||||
|
puts("=======================");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (registers[ip_reg] < instr_count) {
|
||||||
|
instruction_execute(instructions, registers, &ip_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
printf("%d\n", registers[0]);
|
printf("%d\n", registers[0]);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
71
Day19/reverse.txt
Normal file
71
Day19/reverse.txt
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
r5 += 16;
|
||||||
|
r1 += 2;
|
||||||
|
r1 *= r1;
|
||||||
|
r1 = r5 * r1;
|
||||||
|
r1 *= 11;
|
||||||
|
r4 += 7;
|
||||||
|
r4 = r4 * r5;
|
||||||
|
r4 += 20;
|
||||||
|
r1 += r4;
|
||||||
|
r5 += r0;
|
||||||
|
r4 = r5;
|
||||||
|
r4 = r4 * r5;
|
||||||
|
r4 = r5 * r4;
|
||||||
|
r4 = r5 * r4;
|
||||||
|
r4 = r4 * 14;
|
||||||
|
r4 = r4 * r5;
|
||||||
|
r1 += r4;
|
||||||
|
r0 = 0;
|
||||||
|
r5 = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int R0 = 0;
|
||||||
|
int R1 = 10551410;
|
||||||
|
for (int R3 = 1; R3 <= R1; R3++) {
|
||||||
|
for (int R2 = 1; R2 <= R1; R2++) {
|
||||||
|
if (R3 * R2 == R1)
|
||||||
|
R0 += R3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("%d", R0);
|
||||||
|
|
||||||
|
┌──────── 0 addi ip 16 ip
|
||||||
|
┌───│───────> 1 seti 1 0 3 ; R3 = 1
|
||||||
|
│ ┌─│───────> 2 seti 1 2 2 ; R2 = 1
|
||||||
|
│ │ │ ┌─────> 3 mulr 3 2 4 ; R4 = R3 * R2
|
||||||
|
│ │ │ │ 4 eqrr 4 1 4 ; ⎫
|
||||||
|
│ │ │ │ ┌─? 5 addr 4 ip ip ; ⎬ if (R4 == R1)
|
||||||
|
│ │ │ │ ┌─│── 6 addi ip 1 ip ; │ R0 += R3
|
||||||
|
│ │ │ │ │ └─> 7 addr 3 0 0 ; ⎭
|
||||||
|
│ │ │ │ └───> 8 addi 2 1 2 ; R2 += 1
|
||||||
|
│ │ │ │ 9 gtrr 2 1 4 ; ⎫
|
||||||
|
│ │ │ │ ┌─? 10 addr ip 4 ip ; ⎬ if (R2 > R1)
|
||||||
|
│ │ │ └───│── 11 seti 2 7 ip ; ⎭ break;
|
||||||
|
│ │ │ └─> 12 addi 3 1 3 ; R3 += 1
|
||||||
|
│ │ │ 13 gtrr 3 1 4 ; ⎫ if (R3 > R1)
|
||||||
|
│ │ │ ┌─? 14 addr 4 ip ip ; ⎬ exit;
|
||||||
|
│ └─│─────│── 15 seti 1 3 ip ; │ else
|
||||||
|
│ │ └─╳ 16 mulr ip ip ip ; ⎭ continue;
|
||||||
|
│ └───────> 17 addi 1 2 1 ; ⎫
|
||||||
|
│ 18 mulr 1 1 1 ; │
|
||||||
|
│ 19 mulr ip 1 1 ; ⎬ R1 = (R1 + 2)^2 * 11
|
||||||
|
│ 20 muli 1 11 1 ; ⎭
|
||||||
|
│ 21 addi 4 7 4 ; ⎫
|
||||||
|
│ 22 mulr 4 ip 4 ; ⎬ R4 = (R4 + 7) * 22 + 20
|
||||||
|
│ 23 addi 4 20 4 ; ⎭
|
||||||
|
│ 24 addr 1 4 1 ; R1 += R4
|
||||||
|
│ ┌── 25 addr ip 0 ip ; IP += 1 (given in assignment)
|
||||||
|
├─────────│── 26 seti 0 4 ip
|
||||||
|
│ └─> 27 setr ip 9 4 ; ⎫
|
||||||
|
│ 28 mulr 4 ip 4 ; │
|
||||||
|
│ 29 addr ip 4 4 ; │
|
||||||
|
│ 30 mulr ip 4 4 ; ⎬ R4 = 10550400 (constant)
|
||||||
|
│ 31 muli 4 14 4 ; │
|
||||||
|
│ 32 mulr 4 ip 4 ; ⎭
|
||||||
|
│ 33 addr 1 4 1 ; R1 = 10550400 + R1
|
||||||
|
│ 34 seti 0 2 0 ; R0 = 0
|
||||||
|
└──────────── 35 seti 0 ip ip ; IP = 0
|
||||||
|
|
||||||
|
|
||||||
|
R0 = 0 --> [ 0, 1010, 0, 0, 174, 0]
|
||||||
|
R0 = 1 --> [ 0, 10551410, 0, 0, 10550400, 0]
|
11
Day19/reversed.c
Normal file
11
Day19/reversed.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
int main() {
|
||||||
|
uint64_t result = 0;
|
||||||
|
uint64_t target = 10551410;
|
||||||
|
for (uint64_t i = 1; i <= target; i++) {
|
||||||
|
if (target % i == 0)
|
||||||
|
result += target / i;
|
||||||
|
}
|
||||||
|
printf("%d\n", result);
|
||||||
|
}
|
Loading…
Reference in a new issue