mirror of
https://github.com/peter-tanner/advent-of-code-2021.git
synced 2024-11-30 11:10:20 +08:00
Attempt at 24 (Bad time complexity - could be done manually)
This commit is contained in:
parent
f2e692b7e1
commit
181ce8379f
170
24/24-1.c
Normal file
170
24/24-1.c
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define PROGRAM_SIZE 512
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
INP = 0,
|
||||||
|
ADD,
|
||||||
|
MUL,
|
||||||
|
DIV,
|
||||||
|
MOD,
|
||||||
|
EQL,
|
||||||
|
|
||||||
|
SUB,
|
||||||
|
} OPCODE;
|
||||||
|
|
||||||
|
const OPCODE INVERSE[] = {
|
||||||
|
INP,
|
||||||
|
SUB,
|
||||||
|
DIV,
|
||||||
|
MUL,
|
||||||
|
MOD, //
|
||||||
|
EQL,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *OPCODE_STRINGS[] = {
|
||||||
|
"inp",
|
||||||
|
"add",
|
||||||
|
"mul",
|
||||||
|
"div",
|
||||||
|
"mod",
|
||||||
|
"eql",
|
||||||
|
};
|
||||||
|
|
||||||
|
OPCODE str2opcode(char *str)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (strcmp(str, OPCODE_STRINGS[i]) != 0)
|
||||||
|
i++;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef long int NUMBER;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
UNDEFINED = 0,
|
||||||
|
LITERAL,
|
||||||
|
VARIABLE,
|
||||||
|
} VALUE_TYPE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
NUMBER value;
|
||||||
|
VALUE_TYPE type;
|
||||||
|
} VALUE;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
OPCODE opcode;
|
||||||
|
VALUE v1;
|
||||||
|
VALUE v2;
|
||||||
|
} INSTRUCTION;
|
||||||
|
|
||||||
|
void print_instruction(INSTRUCTION instruction)
|
||||||
|
{
|
||||||
|
printf("%s\t|", OPCODE_STRINGS[instruction.opcode]);
|
||||||
|
if (instruction.v1.type == VARIABLE)
|
||||||
|
putchar(instruction.v1.value + 'w');
|
||||||
|
else
|
||||||
|
printf("%li", instruction.v1.value);
|
||||||
|
putchar('\t');
|
||||||
|
if (instruction.v2.type == VARIABLE)
|
||||||
|
putchar(instruction.v2.value + 'w');
|
||||||
|
else
|
||||||
|
printf("%li", instruction.v2.value);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CRASH(condition) \
|
||||||
|
if (condition) \
|
||||||
|
{ \
|
||||||
|
printf("CRASH AT %d\n", __LINE__); \
|
||||||
|
exit(EXIT_FAILURE); \
|
||||||
|
}
|
||||||
|
|
||||||
|
NUMBER run_program(INSTRUCTION *program, NUMBER program_size, NUMBER *rom)
|
||||||
|
{
|
||||||
|
|
||||||
|
NUMBER rom_ptr = 0;
|
||||||
|
NUMBER registers[4] = {0};
|
||||||
|
|
||||||
|
#define GET_VALUE(instruction, registers) (instruction.v2.type == VARIABLE ? registers[instruction.v2.value] : instruction.v2.value)
|
||||||
|
for (NUMBER i = 0; i < program_size; i++)
|
||||||
|
{
|
||||||
|
INSTRUCTION instruction = program[i];
|
||||||
|
CRASH(instruction.v1.type == UNDEFINED);
|
||||||
|
CRASH(instruction.v1.type != VARIABLE);
|
||||||
|
switch (instruction.opcode)
|
||||||
|
{
|
||||||
|
case INP:
|
||||||
|
registers[instruction.v1.value] = rom[rom_ptr];
|
||||||
|
rom_ptr++;
|
||||||
|
break;
|
||||||
|
case ADD:
|
||||||
|
CRASH(instruction.v2.type == UNDEFINED);
|
||||||
|
registers[instruction.v1.value] += GET_VALUE(instruction, registers);
|
||||||
|
break;
|
||||||
|
case MUL:
|
||||||
|
CRASH(instruction.v2.type == UNDEFINED);
|
||||||
|
registers[instruction.v1.value] *= GET_VALUE(instruction, registers);
|
||||||
|
break;
|
||||||
|
case DIV:
|
||||||
|
CRASH(instruction.v2.type == UNDEFINED);
|
||||||
|
CRASH(instruction.v2.value == 0);
|
||||||
|
registers[instruction.v1.value] /= GET_VALUE(instruction, registers);
|
||||||
|
break;
|
||||||
|
case MOD:
|
||||||
|
CRASH(instruction.v2.type == UNDEFINED);
|
||||||
|
CRASH(instruction.v2.value <= 0);
|
||||||
|
registers[instruction.v1.value] %= GET_VALUE(instruction, registers);
|
||||||
|
break;
|
||||||
|
case EQL:
|
||||||
|
CRASH(instruction.v2.type == UNDEFINED);
|
||||||
|
registers[instruction.v1.value] = (registers[instruction.v1.value] == GET_VALUE(instruction, registers));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef GET_VALUE
|
||||||
|
return registers[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char const *argv[])
|
||||||
|
{
|
||||||
|
FILE *p_file = fopen("input", "r");
|
||||||
|
char buf[BUFSIZ];
|
||||||
|
INSTRUCTION program[PROGRAM_SIZE];
|
||||||
|
NUMBER program_size = 0;
|
||||||
|
|
||||||
|
#define STR2VALUE(token, instruction, val) \
|
||||||
|
token = strtok(NULL, " "); \
|
||||||
|
if (token != NULL) \
|
||||||
|
{ \
|
||||||
|
(instruction).val.type = (isdigit(token[0]) || token[0] == '-') ? LITERAL : VARIABLE; \
|
||||||
|
if ((instruction).val.type == VARIABLE) \
|
||||||
|
(instruction).val.value = token[0] - 'w'; \
|
||||||
|
else \
|
||||||
|
(instruction).val.value = strtol(token, NULL, 0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(buf, sizeof buf, p_file) != NULL)
|
||||||
|
{
|
||||||
|
// READ INSTRUCTION
|
||||||
|
buf[strcspn(buf, "\n")] = '\0'; // DELETE TRAILING \n
|
||||||
|
|
||||||
|
char *token = strtok(buf, " ");
|
||||||
|
program[program_size].opcode = str2opcode(token);
|
||||||
|
STR2VALUE(token, program[program_size], v1);
|
||||||
|
STR2VALUE(token, program[program_size], v2);
|
||||||
|
#undef STR2VALUE
|
||||||
|
program_size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user