diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ff4ad4d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "typeindex": "c", + "typeinfo": "c" + } +} \ No newline at end of file diff --git a/Day19/Day19A.c b/Day19/Day19A.c index 1a92b46..4b254b9 100644 --- a/Day19/Day19A.c +++ b/Day19/Day19A.c @@ -40,50 +40,57 @@ int instruction_read(Instruction *i, FILE *file) { return 0; } -void instruction_execute(const Instruction *i, uint32_t *r, uint32_t *ip, uint32_t *ip_r) { - if (*ip_r != -1) - r[*ip_r] = *ip; +void instruction_execute(const Instruction* instructions, uint32_t* r, uint32_t* ip_r) { + const Instruction i = instructions[r[*ip_r]]; - 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 - case ADDR: r[i->c] = r[i->a] + r[i->b]; break; - case ADDI: r[i->c] = r[i->a] + 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; // Multiplication - case MULR: r[i->c] = r[i->a] * r[i->b]; break; - case MULI: r[i->c] = r[i->a] * 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; // Bitwise AND - case BANR: r[i->c] = (r[i->a] & r[i->b]); break; - case BANI: r[i->c] = (r[i->a] & 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; // Bitwise OR - case BORR: r[i->c] = (r[i->a] | r[i->b]); break; - case BORI: r[i->c] = (r[i->a] | 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; // Assignment - case SETR: r[i->c] = r[i->a]; break; - case SETI: r[i->c] = i->a; break; + case SETR: r[i.c] = r[i.a]; break; + case SETI: r[i.c] = i.a; break; // Greater-than testing - case GTIR: r[i->c] = (i->a > r[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 GTIR: r[i.c] = (i.a > r[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; // Equality testing - case EQIR: r[i->c] = (i->a == r[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 IP: *ip_r = i->a; *ip -= 1; break; + case EQIR: r[i.c] = (i.a == r[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; default: assert(0); } - if (*ip_r != -1) - *ip = r[*ip_r]; +#ifdef DEBUG + 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) { @@ -94,35 +101,41 @@ int main(int argc, char **argv) { FILE *file = fopen(argv[1], "r"); - uint32_t registers[6] = {0}; - uint32_t ip_reg = -1; +#ifdef DEBUG + puts("================="); + puts(" READING INPUT"); + puts("================="); +#endif + uint32_t registers[6] = {1, 0}; + uint32_t ip_reg = 0; size_t instr_count = 0; for (instr_count = 0; instr_count < 1024 && instruction_read(&instructions[instr_count], file); instr_count++) { -#ifdef DEBUG - printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instructions[instr_count].opcode, - names[instructions[instr_count].opcode], instructions[instr_count].a, instructions[instr_count].b, - instructions[instr_count].c); -#endif - } - - for (uint32_t i = 0; i < instr_count;) { - Instruction instruction = instructions[i]; -#ifdef DEBUG - const char *name = names[instruction.opcode]; - 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); + const Instruction instr = instructions[instr_count]; + if (instr.opcode == IP) { + // Assuming that an #ip can only occur once here + ip_reg = instr.a; + instr_count -= 1; + } #ifdef DEBUG - printf("registers: %d %d %d %d %d %d\n", registers[0], registers[1], - registers[2], registers[3], registers[4], registers[5]); + printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instr.opcode, names[instr.opcode], instr.a, instr.b, instr.c); #endif } 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]); return EXIT_SUCCESS; } diff --git a/Day19/reverse.txt b/Day19/reverse.txt new file mode 100644 index 0000000..8057ff7 --- /dev/null +++ b/Day19/reverse.txt @@ -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] diff --git a/Day19/reversed.c b/Day19/reversed.c new file mode 100644 index 0000000..273a19b --- /dev/null +++ b/Day19/reversed.c @@ -0,0 +1,11 @@ +#include +#include +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); +}