Clean up day 16
This commit is contained in:
parent
1c227f6906
commit
007234f7b2
1 changed files with 42 additions and 33 deletions
|
@ -16,44 +16,32 @@ 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;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue