C first intcode problem
This commit is contained in:
parent
5987591a2a
commit
68cd93cbed
36
c/2019/2/1202_program_alarm.c
Normal file
36
c/2019/2/1202_program_alarm.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../lib/intcode.h"
|
||||
|
||||
#define EXPECTED_OUTPUT 19690720
|
||||
|
||||
int main() {
|
||||
ic_load_rom_from_input();
|
||||
|
||||
IC *c = ic_new_computer();
|
||||
ic_poke(c, 1, 12);
|
||||
ic_poke(c, 2, 2);
|
||||
ic_run(c);
|
||||
|
||||
printf("Part 1: %d\n", ic_peek(c, 0));
|
||||
|
||||
int noun, verb;
|
||||
for (noun = 0; noun < 100; noun++) {
|
||||
for (verb = 0; verb < 100; verb++) {
|
||||
ic_reset(c);
|
||||
ic_poke(c, 1, noun);
|
||||
ic_poke(c, 2, verb);
|
||||
ic_run(c);
|
||||
if (ic_peek(c, 0) == EXPECTED_OUTPUT) goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
printf("Part 2: %d\n", noun * 100 + verb);
|
||||
|
||||
aoc_free();
|
||||
return 0;
|
||||
}
|
109
c/lib/intcode.h
Normal file
109
c/lib/intcode.h
Normal file
@ -0,0 +1,109 @@
|
||||
#include <stdbool.h>
|
||||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user