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