C Intcode problem 2 part 1
This commit is contained in:
parent
68cd93cbed
commit
6e9cf2c26a
19
c/2019/5/sunny_with_a_chance_of_asteroids.c
Normal file
19
c/2019/5/sunny_with_a_chance_of_asteroids.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "../../lib/intcode.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ic_load_rom_from_input();
|
||||||
|
|
||||||
|
IC *c = ic_new_computer();
|
||||||
|
ic_run(c);
|
||||||
|
|
||||||
|
printf("Part 1: %d\n", c->output_buffer[c->output_buffer_count - 1]);
|
||||||
|
// printf("Part 2: %d\n", noun * 100 + verb);
|
||||||
|
|
||||||
|
aoc_free();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -2,6 +2,10 @@
|
|||||||
#include "./aoc.h"
|
#include "./aoc.h"
|
||||||
|
|
||||||
#define ROM_LENGTH 1000
|
#define ROM_LENGTH 1000
|
||||||
|
#define OUTPUT_BUFFER_LENGTH 1000
|
||||||
|
|
||||||
|
#define POSITION_MODE 0
|
||||||
|
#define IMMEDIATE_MODE 1
|
||||||
|
|
||||||
int rom[ROM_LENGTH];
|
int rom[ROM_LENGTH];
|
||||||
int rom_count;
|
int rom_count;
|
||||||
@ -11,6 +15,8 @@ typedef struct IC {
|
|||||||
int *data;
|
int *data;
|
||||||
int program_counter;
|
int program_counter;
|
||||||
bool halted;
|
bool halted;
|
||||||
|
int output_buffer[OUTPUT_BUFFER_LENGTH];
|
||||||
|
int output_buffer_count;
|
||||||
} IC;
|
} IC;
|
||||||
|
|
||||||
int ic_peek(IC *c, int address) {
|
int ic_peek(IC *c, int address) {
|
||||||
@ -33,54 +39,105 @@ void ic_halt(IC *c) {
|
|||||||
c->halted = true;
|
c->halted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ic_instruction_add(IC *c) {
|
void ic_instruction_add(IC *c, int modes) {
|
||||||
|
bool x_mode = modes % 10;
|
||||||
|
modes /= 10;
|
||||||
|
bool y_mode = modes % 10;
|
||||||
|
modes /= 10;
|
||||||
|
|
||||||
int x = ic_read(c);
|
int x = ic_read(c);
|
||||||
|
if (x_mode == POSITION_MODE) x = ic_peek(c, x);
|
||||||
int y = ic_read(c);
|
int y = ic_read(c);
|
||||||
ic_write(c, ic_peek(c, x) + ic_peek(c, y));
|
if (y_mode == POSITION_MODE) y = ic_peek(c, y);
|
||||||
|
|
||||||
|
ic_write(c, x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ic_instruction_multiply(IC *c) {
|
void ic_instruction_multiply(IC *c, int modes) {
|
||||||
|
bool x_mode = modes % 10;
|
||||||
|
modes /= 10;
|
||||||
|
bool y_mode = modes % 10;
|
||||||
|
modes /= 10;
|
||||||
|
|
||||||
int x = ic_read(c);
|
int x = ic_read(c);
|
||||||
|
if (x_mode == POSITION_MODE) x = ic_peek(c, x);
|
||||||
int y = ic_read(c);
|
int y = ic_read(c);
|
||||||
ic_write(c, ic_peek(c, x) * ic_peek(c, y));
|
if (y_mode == POSITION_MODE) y = ic_peek(c, y);
|
||||||
|
|
||||||
|
ic_write(c, x * y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ic_instruction_halt(IC *c) {
|
void ic_instruction_input(IC *c, int _modes) {
|
||||||
|
ic_write(c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ic_instruction_output(IC *c, int modes) {
|
||||||
|
if (c->output_buffer_count >= OUTPUT_BUFFER_LENGTH) {
|
||||||
|
printf("Output buffer overflow!\n");
|
||||||
|
ic_halt(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mode = modes % 10;
|
||||||
|
modes /= 10;
|
||||||
|
int to_output = ic_read(c);
|
||||||
|
if (mode == POSITION_MODE) to_output = ic_peek(c, to_output);
|
||||||
|
c->output_buffer[c->output_buffer_count++] = to_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ic_instruction_halt(IC *c, int _modes) {
|
||||||
ic_halt(c);
|
ic_halt(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ic_execute_instruction(IC *c) {
|
int ic_execute_instruction(IC *c) {
|
||||||
int opcode = ic_read(c);
|
int instruction = ic_read(c);
|
||||||
|
int opcode = instruction % 100;
|
||||||
|
int modes = instruction / 100;
|
||||||
|
// printf("Running %d: opcode %d with modes %d\n", instruction, opcode, modes);
|
||||||
|
// printf("PC: %d\n", c->program_counter - 1);
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case 1:
|
case 1:
|
||||||
ic_instruction_add(c);
|
ic_instruction_add(c, modes);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
ic_instruction_multiply(c);
|
ic_instruction_multiply(c, modes);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ic_instruction_input(c, modes);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
ic_instruction_output(c, modes);
|
||||||
break;
|
break;
|
||||||
case 99:
|
case 99:
|
||||||
ic_instruction_halt(c);
|
ic_instruction_halt(c, modes);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Invalid opcode [%d] encountered at %d\n", opcode, c->program_counter - 1);
|
printf("Invalid opcode [%d] encountered at %d\n", opcode, c->program_counter - 1);
|
||||||
ic_instruction_halt(c);
|
ic_instruction_halt(c, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ic_print(IC *c) {
|
void ic_print(IC *c) {
|
||||||
printf("PC: %d\n", c->program_counter);
|
printf("PC: %d\n", c->program_counter);
|
||||||
|
|
||||||
for (int i = 0; i < rom_count; i++) {
|
for (int i = 0; i < rom_count; i++) {
|
||||||
printf("%6d ", c->data[i]);
|
printf("%6d ", c->data[i]);
|
||||||
if (i % 8 == 7) printf("\n");
|
if (i % 8 == 7) printf("\n");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Output buffer: ");
|
||||||
|
for (int i = 0; i < c->output_buffer_count; i++) {
|
||||||
|
printf("[%d] ", c->output_buffer[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ic_reset(IC *c) {
|
void ic_reset(IC *c) {
|
||||||
memcpy(c->data, c->rom, rom_count * sizeof(int));
|
memcpy(c->data, c->rom, rom_count * sizeof(int));
|
||||||
c->program_counter = 0;
|
c->program_counter = 0;
|
||||||
c->halted = true;
|
c->halted = true;
|
||||||
|
c->output_buffer_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ic_run(IC *c) {
|
void ic_run(IC *c) {
|
||||||
|
Loading…
Reference in New Issue
Block a user