Browse Source

day 5 part 1

master
red 4 years ago
parent
commit
eddb0a89f6
4 changed files with 174 additions and 1 deletions
  1. +2
    -1
      CMakeLists.txt
  2. +15
    -0
      day5.c
  3. +130
    -0
      intcode.c
  4. +27
    -0
      intcode.h

+ 2
- 1
CMakeLists.txt View File

@@ -6,4 +6,5 @@ set(CMAKE_C_STANDARD 99)
add_executable(day1 day1.c)
add_executable(day2 day2.c)
add_executable(day3 day3.c)
add_executable(day4 day4.c)
add_executable(day4 day4.c)
add_executable(day5 day5.c intcode.c)

+ 15
- 0
day5.c View File

@@ -0,0 +1,15 @@
//
// Created by red on 05/12/19.
//

#include <stdio.h>
#include <stdlib.h>
#include "intcode.h"

int main(int argc, char **argv) {
char* filename = argv[1];
intcode* v = read_file(filename, 2048);
int input[1] = { 1 };
v->input_tape = input;
run(v);
}

+ 130
- 0
intcode.c View File

@@ -0,0 +1,130 @@
//
// Created by red on 05/12/19.
//

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "intcode.h"

ival out_val(int n) {
ival v;
v.type = IVAL_OUT;
v.num = n;
return v;
}

ival err_val(int n) {
ival v;
v.type = IVAL_ERR;
v.err = n;
return v;
}

ival end_val() {
ival v;
v.type = IVAL_END;
return v;
}

ival cont_val() {
ival v;
v.type = IVAL_CONT;
return v;
}

void ival_print(ival v) {
switch (v.type) {
case IVAL_ERR: {
switch (v.err) {
case IERR_OUT_OF_BOUNDS: printf("error: read/write out of bounds\n");
break;
case IERR_BAD_OP: printf("error: bad opcode\n");
break;
}
}
case IVAL_OUT: {
printf("Output value: %d\n", v.num);
}
}
}

ival step (intcode* m) {
int opcode = m->tape[m->index];
int addr_mode[2];
addr_mode[0] = (opcode / 100) % 10;
addr_mode[1] = (opcode / 1000) % 10;
opcode = opcode % 100;
switch (opcode) {
case 99: return end_val();
case 4: {
int v;
if (addr_mode[0] == 0) { v = m->tape[m->tape[m->index+1]]; }
else { v = m->tape[m->index+1]; }
m->index += 2;
return out_val(v);
}
case 3: {
int i = m->tape[m->index+1];
m->index += 2;
m->tape[i] = m->input_tape[0];
m->input_tape = m->input_tape+1;
return cont_val();
}
default: {
int a;
int b;
if (opcode != 1 && opcode != 2) return err_val(IERR_BAD_OP);
if (addr_mode[0] == 0) { a = m->tape[m->tape[m->index+1]]; }
else { a = m->tape[m->index+1]; }
if (addr_mode[1] == 0) { b = m->tape[m->tape[m->index+2]]; }
else { b = m->tape[m->index+2]; }
switch (opcode) {
case 1: {
m->tape[m->tape[m->index+3]] = a+b;
m->index += 4;
break;
}
case 2: {
m->tape[m->tape[m->index+3]] = a*b;
m->index += 4;
break;
}
}
}
return cont_val();
}
}

ival run (intcode* m) {
for (;;) {
size_t i = m->index;
printf("DEBUG: next 4 values: %d %d %d %d\n", m->tape[i], m->tape[i+1], m->tape[i+2], m->tape[i+3]);
ival v = step(m);
switch (v.type) {
case IVAL_ERR:
case IVAL_END: return v;
case IVAL_OUT: ival_print(v);
break;
default: break;
}
}
};

intcode *read_file(char *filename, size_t buf_size) {
int* tape = calloc(buf_size, sizeof(int));
memset((void*) tape, 0, sizeof(int)*buf_size);
FILE* file = fopen(filename, "r");
size_t i;
for (i = 0; i < buf_size; i++) {
int a;
int err = fscanf(file, "%d,", &a);
if (err == EOF) break;
tape[i] = a;
}
static intcode v;
v.tape = tape;
v.index = 0;
v.tape_l = i;
return &v;
}

+ 27
- 0
intcode.h View File

@@ -0,0 +1,27 @@
//
// Created by red on 05/12/19.
//

#include <stddef.h>

#ifndef AOC2019_INTCODE_H
#define AOC2019_INTCODE_H


enum {IERR_BAD_OP, IERR_OUT_OF_BOUNDS};
enum {IVAL_OUT, IVAL_ERR, IVAL_END, IVAL_CONT};
typedef struct {
int type;
int num;
int err;
} ival;
typedef struct {
int* tape;
size_t tape_l;
size_t index;
int* input_tape;
} intcode;
ival step (intcode* m);
ival run (intcode* m);
intcode* read_file(char* filename, size_t buf_size);
#endif //AOC2019_INTCODE_H

Loading…
Cancel
Save