Clean up day 16

This commit is contained in:
Sijmen 2018-12-18 15:07:03 +01:00
parent 1c227f6906
commit 007234f7b2

View file

@ -16,43 +16,31 @@ typedef struct {
} Sample; } Sample;
enum { enum {
ADDR, ADDI, MULR, MULI, ADDR, ADDI, MULR, MULI, BANR, BANI, BORR, BORI,
BANR, BANI, BORR, BORI, SETR, SETI, GTIR, GTRI, GTRR, EQIR, EQRI, EQRR,
SETR, SETI, GTIR, GTRI,
GTRR, EQIR, EQRI, EQRR,
}; };
#ifdef DEBUG
const char *names[] = { const char *names[] = {
"addr", "addi", "mulr", "muli", "addr", "addi", "mulr", "muli", "banr", "bani", "borr", "bori",
"banr", "bani", "borr", "bori", "setr", "seti", "gtir", "gtri", "gtrr", "eqir", "eqri", "eqrr",
"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,
}; };
#endif
int opcodes[16]; int opcodes[16];
int sample_read(Sample *s, FILE *file) { int sample_read(Sample *s, FILE *file) {
int read = 0; int read = 0;
read = read = fscanf(file, "Before: [%u, %u, %u, %u]\n",
fscanf(file, "Before: [%u, %u, %u, %u]\n",
&s->before[0], &s->before[1], &s->before[2], &s->before[3]); &s->before[0], &s->before[1], &s->before[2], &s->before[3]);
if (read != 4) return 0; if (read != 4) return 0;
Instruction *i = &s->instruction; Instruction *i = &s->instruction;
read = fscanf(file, "%" SCNu8 " %u %u %u\n", read = fscanf(file, "%" SCNu8 " %u %u %u\n", &i->opcode, &i->a, &i->b, &i->c);
&i->opcode, &i->a, &i->b, &i->c);
if (read != 4) return 0; if (read != 4) return 0;
read = read = fscanf(file, "After: [%u, %u, %u, %u]\n\n",
fscanf(file, "After: [%u, %u, %u, %u]\n\n",
&s->after[0], &s->after[1], &s->after[2], &s->after[3]); &s->after[0], &s->after[1], &s->after[2], &s->after[3]);
if (read != 4) return 0; if (read != 4) return 0;
@ -63,25 +51,32 @@ uint16_t sample_possible_opcodes(const Sample s) {
uint16_t possible_opcodes = 0; uint16_t possible_opcodes = 0;
Instruction i = s.instruction; Instruction i = s.instruction;
// Addition // 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] + s.before[i.b]) possible_opcodes |= 1 << ADDR;
if (s.after[i.c] == s.before[i.a] + i.b) possible_opcodes |= 1 << ADDI; if (s.after[i.c] == s.before[i.a] + i.b) possible_opcodes |= 1 << ADDI;
// Multiplication // 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] * s.before[i.b]) possible_opcodes |= 1 << MULR;
if (s.after[i.c] == s.before[i.a] * i.b) possible_opcodes |= 1 << MULI; if (s.after[i.c] == s.before[i.a] * i.b) possible_opcodes |= 1 << MULI;
// Bitwise AND // 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] & s.before[i.b])) possible_opcodes |= 1 << BANR;
if (s.after[i.c] == (s.before[i.a] & i.b)) possible_opcodes |= 1 << BANI; if (s.after[i.c] == (s.before[i.a] & i.b)) possible_opcodes |= 1 << BANI;
// Bitwise OR // 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] | s.before[i.b])) possible_opcodes |= 1 << BORR;
if (s.after[i.c] == (s.before[i.a] | i.b)) possible_opcodes |= 1 << BORI; if (s.after[i.c] == (s.before[i.a] | i.b)) possible_opcodes |= 1 << BORI;
// Assignment // Assignment
if (s.after[i.c] == s.before[i.a]) possible_opcodes |= 1 << SETR; if (s.after[i.c] == s.before[i.a]) possible_opcodes |= 1 << SETR;
if (s.after[i.c] == i.a) possible_opcodes |= 1 << SETI; if (s.after[i.c] == i.a) possible_opcodes |= 1 << SETI;
// Greater-than testing // Greater-than testing
if (s.after[i.c] == (i.a > s.before[i.b])) possible_opcodes |= 1 << GTIR; 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] > i.b)) possible_opcodes |= 1 << GTRI;
if (s.after[i.c] == (s.before[i.a] > s.before[i.b])) possible_opcodes |= 1 << GTRR; if (s.after[i.c] == (s.before[i.a] > s.before[i.b])) possible_opcodes |= 1 << GTRR;
// Equality testing // Equality testing
if (s.after[i.c] == (i.a == s.before[i.b])) possible_opcodes |= 1 << EQIR; 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; 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; return bit;
} }
void find_opcodes() { void find_opcodes(FILE *file) {
int unknown = 16; 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) { while (unknown > 0) {
for (int opcode = 0; opcode < 16; opcode++) { for (int opcode = 0; opcode < 16; opcode++) {
int bit = bits_set(table[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]]); printf("%d: %s\n", i, names[opcodes[i]]);
} #endif
} }
int instruction_read(Instruction *i, FILE *file) { int instruction_read(Instruction *i, FILE *file) {
@ -170,25 +177,27 @@ int main(int argc, char **argv) {
} }
FILE *file = fopen(argv[1], "r"); FILE *file = fopen(argv[1], "r");
Sample sample = {0}; find_opcodes(file);
while (sample_read(&sample, file)) {
uint16_t possible_opcodes = sample_possible_opcodes(sample);
table[sample.instruction.opcode] &= possible_opcodes;
}
find_opcodes();
uint32_t registers[4] = {0}; uint32_t registers[4] = {0};
Instruction instruction = {0}; Instruction instruction = {0};
while (instruction_read(&instruction, file)) { while (instruction_read(&instruction, file)) {
#ifdef DEBUG
const char *name = names[opcodes[instruction.opcode]]; const char *name = names[opcodes[instruction.opcode]];
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instruction.opcode, printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instruction.opcode,
name, instruction.a, instruction.b, instruction.c); name, instruction.a, instruction.b, instruction.c);
#endif
instruction_execute(&instruction, registers); instruction_execute(&instruction, registers);
#ifdef DEBUG
printf("registers: %d %d %d %d\n", registers[0], registers[1], printf("registers: %d %d %d %d\n", registers[0], registers[1],
registers[2], registers[3]); registers[2], registers[3]);
#endif
} }
fclose(file); fclose(file);
printf("%d\n", registers[0]);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }