#include #include "./aoc.h" #define ROM_LENGTH 1000 int rom[ROM_LENGTH]; int rom_count; typedef struct IC { int *rom; int *data; int program_counter; bool halted; } IC; int ic_peek(IC *c, int address) { return c->data[address]; } void ic_poke(IC *c, int address, int value) { c->data[address] = value; } int ic_read(IC *c) { return ic_peek(c, c->program_counter++); } void ic_write(IC *c, int value) { ic_poke(c, ic_peek(c, c->program_counter++), value); } void ic_halt(IC *c) { c->halted = true; } void ic_instruction_add(IC *c) { int x = ic_read(c); int y = ic_read(c); ic_write(c, ic_peek(c, x) + ic_peek(c, y)); } void ic_instruction_multiply(IC *c) { int x = ic_read(c); int y = ic_read(c); ic_write(c, ic_peek(c, x) * ic_peek(c, y)); } void ic_instruction_halt(IC *c) { ic_halt(c); } int ic_execute_instruction(IC *c) { int opcode = ic_read(c); switch(opcode) { case 1: ic_instruction_add(c); break; case 2: ic_instruction_multiply(c); break; case 99: ic_instruction_halt(c); break; default: printf("Invalid opcode [%d] encountered at %d\n", opcode, c->program_counter - 1); ic_instruction_halt(c); break; } } void ic_print(IC *c) { printf("PC: %d\n", c->program_counter); for (int i = 0; i < rom_count; i++) { printf("%6d ", c->data[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); } void ic_reset(IC *c) { memcpy(c->data, c->rom, rom_count * sizeof(int)); c->program_counter = 0; c->halted = true; } void ic_run(IC *c) { c->halted = false; while (!c->halted) ic_execute_instruction(c); } IC *ic_new_computer(void) { IC *c = malloc(sizeof(IC)); c->rom = rom; c->data = malloc(rom_count * sizeof(int)); ic_reset(c); return c; } int ic_load_rom_from_input(void) { char *input = aoc_read_input(); char *token = strtok(input, ","); while (token != NULL) { rom[rom_count++] = atoi(token); token = strtok(NULL, ","); } return rom_count; }