Skip to content

Instantly share code, notes, and snippets.

@erikaderstedt
Created December 9, 2019 06:52
Show Gist options
  • Save erikaderstedt/c4d3b4ac86f5a8b75959052154aefc91 to your computer and use it in GitHub Desktop.
Save erikaderstedt/c4d3b4ac86f5a8b75959052154aefc91 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define IMMEDIATE (1)
#define POSITIONAL (0)
#define RELATIVE (2)
#define ARG0_ADDR (p[i+1] + ((modes[0] == RELATIVE) ? relative_base : 0))
#define ARG1_ADDR (p[i+2] + ((modes[1] == RELATIVE) ? relative_base : 0))
#define ARG2_ADDR (p[i+3] + ((modes[2] == RELATIVE) ? relative_base : 0))
#define ARG0 ((modes[0]==IMMEDIATE) ? p[i+1] : p[ARG0_ADDR])
#define ARG1 ((modes[1]==IMMEDIATE) ? p[i+2] : p[ARG1_ADDR])
int64_t run_program_and_wait(int64_t *p,
int64_t *instr,
int64_t length,
const int64_t *__restrict input,
size_t num_inputs,
bool *waiting_for_input,
int64_t *output_buf) {
int64_t i = *instr, output = 0;
size_t used_inputs = 0;
int64_t relative_base = 0;
*waiting_for_input = false;
while (p[i] != 99) {
int64_t modes[4] = { 100,1000,10000,10000};
int64_t instruction = p[i] % 100;
for (size_t j = 0; j < 4; j++) modes[j] = (p[i] / modes[j]) % 10;
switch (instruction) {
case 1: p[ARG2_ADDR] = ARG0 + ARG1; i += 4; break;
case 2: p[ARG2_ADDR] = ARG0 * ARG1; i += 4; break;
case 7: p[ARG2_ADDR] = (ARG0 < ARG1) ? 1 : 0; i += 4; break;
case 8: p[ARG2_ADDR] = (ARG0 == ARG1) ? 1 : 0; i += 4; break;
case 4: output_buf[output++] = ARG0; i += 2; break;
case 5: i = (ARG0 != 0) ? ARG1 : (i+3); break;
case 6: i = (ARG0 == 0) ? ARG1 : (i+3); break;
case 9: relative_base += ARG0; i += 2; break;
case 3:
if (used_inputs == num_inputs) {
// Pause, wait for more inputs
*waiting_for_input = true;
*instr = i;
return output;
}
p[ARG0_ADDR] = input[used_inputs++];
i += 2; break;
default: fprintf(stderr, "Invalid opcode %lld.\n", p[i]); exit(1);
}
}
return output;
}
int main(int argc, char **argv) {
int64_t a[1000024], output[10000];
size_t length = 0;
FILE *fp = fopen(argv[1], "r");
while(fscanf(fp, "%lld,", a + length++) > 0);
fclose(fp);
length--;
bool wait;
int64_t ip = 0;
int64_t input = 2;
int64_t m = run_program_and_wait(a, &ip, length, &input, 1, &wait, output); // Input phase
for (int64_t x = 0; x < m-1; x++) {
printf("%lld,", output[x]);
}
if (m > 0) printf("%lld", output[m-1]);
printf("\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment