From 007234f7b2c56683347451165702e98c42648a22 Mon Sep 17 00:00:00 2001 From: Sijmen Schoon Date: Tue, 18 Dec 2018 15:07:03 +0100 Subject: [PATCH] Clean up day 16 --- Day16/Day16B.c | 75 ++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/Day16/Day16B.c b/Day16/Day16B.c index 3ff0515..cdd5c7e 100644 --- a/Day16/Day16B.c +++ b/Day16/Day16B.c @@ -16,44 +16,32 @@ typedef struct { } Sample; enum { - ADDR, ADDI, MULR, MULI, - BANR, BANI, BORR, BORI, - SETR, SETI, GTIR, GTRI, - GTRR, EQIR, EQRI, EQRR, + ADDR, ADDI, MULR, MULI, BANR, BANI, BORR, BORI, + SETR, SETI, GTIR, GTRI, GTRR, EQIR, EQRI, EQRR, }; +#ifdef DEBUG const char *names[] = { - "addr", "addi", "mulr", "muli", - "banr", "bani", "borr", "bori", - "setr", "seti", "gtir", "gtri", - "gtrr", "eqir", "eqri", "eqrr", -}; - -uint16_t table[16] = { - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + "addr", "addi", "mulr", "muli", "banr", "bani", "borr", "bori", + "setr", "seti", "gtir", "gtri", "gtrr", "eqir", "eqri", "eqrr", }; +#endif int opcodes[16]; int sample_read(Sample *s, FILE *file) { int read = 0; - read = - fscanf(file, "Before: [%u, %u, %u, %u]\n", - &s->before[0], &s->before[1], &s->before[2], &s->before[3]); + read = fscanf(file, "Before: [%u, %u, %u, %u]\n", + &s->before[0], &s->before[1], &s->before[2], &s->before[3]); if (read != 4) return 0; Instruction *i = &s->instruction; - read = fscanf(file, "%" SCNu8 " %u %u %u\n", - &i->opcode, &i->a, &i->b, &i->c); + read = fscanf(file, "%" SCNu8 " %u %u %u\n", &i->opcode, &i->a, &i->b, &i->c); if (read != 4) return 0; - read = - fscanf(file, "After: [%u, %u, %u, %u]\n\n", - &s->after[0], &s->after[1], &s->after[2], &s->after[3]); + read = fscanf(file, "After: [%u, %u, %u, %u]\n\n", + &s->after[0], &s->after[1], &s->after[2], &s->after[3]); if (read != 4) return 0; return 1; @@ -63,25 +51,32 @@ uint16_t sample_possible_opcodes(const Sample s) { uint16_t possible_opcodes = 0; Instruction i = s.instruction; + // Addition if (s.after[i.c] == s.before[i.a] + s.before[i.b]) possible_opcodes |= 1 << ADDR; if (s.after[i.c] == s.before[i.a] + i.b) possible_opcodes |= 1 << ADDI; + // Multiplication if (s.after[i.c] == s.before[i.a] * s.before[i.b]) possible_opcodes |= 1 << MULR; if (s.after[i.c] == s.before[i.a] * i.b) possible_opcodes |= 1 << MULI; + // Bitwise AND if (s.after[i.c] == (s.before[i.a] & s.before[i.b])) possible_opcodes |= 1 << BANR; if (s.after[i.c] == (s.before[i.a] & i.b)) possible_opcodes |= 1 << BANI; + // Bitwise OR if (s.after[i.c] == (s.before[i.a] | s.before[i.b])) possible_opcodes |= 1 << BORR; if (s.after[i.c] == (s.before[i.a] | i.b)) possible_opcodes |= 1 << BORI; + // Assignment if (s.after[i.c] == s.before[i.a]) possible_opcodes |= 1 << SETR; if (s.after[i.c] == i.a) possible_opcodes |= 1 << SETI; + // Greater-than testing if (s.after[i.c] == (i.a > s.before[i.b])) possible_opcodes |= 1 << GTIR; if (s.after[i.c] == (s.before[i.a] > i.b)) possible_opcodes |= 1 << GTRI; if (s.after[i.c] == (s.before[i.a] > s.before[i.b])) possible_opcodes |= 1 << GTRR; + // Equality testing if (s.after[i.c] == (i.a == s.before[i.b])) possible_opcodes |= 1 << EQIR; if (s.after[i.c] == (s.before[i.a] == i.b)) possible_opcodes |= 1 << EQRI; @@ -101,8 +96,19 @@ int bits_set(uint16_t n) { return bit; } -void find_opcodes() { +void find_opcodes(FILE *file) { int unknown = 16; + uint16_t table[16] = { + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, + }; + + Sample sample; + while (sample_read(&sample, file)) { + uint16_t possible_opcodes = sample_possible_opcodes(sample); + table[sample.instruction.opcode] &= possible_opcodes; + } + while (unknown > 0) { for (int opcode = 0; opcode < 16; opcode++) { int bit = bits_set(table[opcode]); @@ -117,9 +123,10 @@ void find_opcodes() { } } - for (int i = 0; i < 16; i++) { +#ifdef DEBUG + for (int i = 0; i < 16; i++) printf("%d: %s\n", i, names[opcodes[i]]); - } +#endif } int instruction_read(Instruction *i, FILE *file) { @@ -170,25 +177,27 @@ int main(int argc, char **argv) { } FILE *file = fopen(argv[1], "r"); - Sample sample = {0}; - - while (sample_read(&sample, file)) { - uint16_t possible_opcodes = sample_possible_opcodes(sample); - table[sample.instruction.opcode] &= possible_opcodes; - } - find_opcodes(); + find_opcodes(file); uint32_t registers[4] = {0}; Instruction instruction = {0}; while (instruction_read(&instruction, file)) { +#ifdef DEBUG const char *name = names[opcodes[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); + +#ifdef DEBUG printf("registers: %d %d %d %d\n", registers[0], registers[1], registers[2], registers[3]); +#endif } fclose(file); + + printf("%d\n", registers[0]); return EXIT_SUCCESS; }