Add solution for day 5 2019

[?]
Jun 23, 2021, 2:12 AM
GVGU5AS3DPNSAFM6YD5Z3YZLWDBIFERKA3PU3ZX44SHIB3MSTYUQC

Dependencies

Change contents

  • file addition: day5.c (----------)
    [2.7]
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <limits.h>
    typedef struct ll {
    int val;
    struct ll *nxt;
    } ll;
    int step(int *prog, int proglen, int *pc, FILE *input, int stage);
    int read_prog(int *prog, int proglen, int pos, int mode);
    void write_prog(int *prog, int proglen, int pos, int value);
    int* do_read(int *len, FILE *source);
    int ll_length(ll *head);
    ll* ll_read(FILE *);
    void ll_free(ll *head);
    int* to_a(ll *head, int *len);
    int main(int argc, char **argv) {
    int proglen = 0;
    int pc = 0;
    int *prog = NULL;
    int stage = 0;
    if(argc != 4) {
    fprintf(stderr, "Usage: day5 <part> <program> <input>\n");
    return 1;
    }
    sscanf(argv[1], "%d", &stage);
    FILE *src = strcmp(argv[2], "-") == 0 ? stdin : fopen(argv[2], "r");
    FILE *input = strcmp(argv[3], "-") == 0 ? stdin: fopen(argv[3], "r");
    if(src == input) {
    fprintf(stderr, "Only one of <program> and <input> can be stdin\n");
    return 1;
    }
    prog = do_read(&proglen, src);
    while(step(prog, proglen, &pc, input, stage)) {}
    printf("\n");
    }
    static inline unsigned int pow_i(int base, unsigned int p) {
    int a = 1;
    int b = base;
    unsigned int x = 1;
    while(x) {
    if(x & p) {
    a *= b;
    }
    b *= base;
    x = x << 1;
    }
    return a;
    }
    static inline int get_mode(int opcode, int argn) {
    return (opcode / pow_i(10, argn + 1)) % 10;
    }
    #define ARG(n) read_prog(prog, proglen, (*pc) + n, get_mode(prog[*pc], n))
    int step(int *prog, int proglen, int *pc, FILE *input, int stage) {
    static int delimiter = 0;
    int n = 0;
    if(*pc >= proglen) return 0;
    switch(prog[*pc] % 10) {
    case 1:
    write_prog(prog, proglen, (*pc) + 3, ARG(1) + ARG(2));
    *pc += 4;
    return 1;
    case 2:
    write_prog(prog, proglen, (*pc) + 3, ARG(1) * ARG(2));
    *pc += 4;
    return 1;
    case 3:
    fscanf(input, "%d", &n);
    fscanf(input, ",");
    write_prog(prog, proglen,(*pc) + 1, n);
    *pc += 2;
    return 1;
    case 4:
    printf("%s%d", delimiter ? ", " : "", ARG(1));
    delimiter = 1;
    *pc += 2;
    return 1;
    case 5:
    if(stage >= 2) {
    if(ARG(1) != 0) {
    *pc = ARG(2);
    } else {
    *pc += 3;
    }
    return 1;
    } else {
    return 0;
    }
    case 6:
    if(stage >= 2) {
    if(ARG(1) == 0) {
    *pc = ARG(2);
    } else {
    *pc += 3;
    }
    return 1;
    } else {
    return 0;
    }
    case 7:
    if(stage >= 2) {
    write_prog(prog, proglen, (*pc) + 3, ARG(1) < ARG(2));
    *pc += 4;
    return 1;
    } else {
    return 0;
    }
    case 8:
    if(stage >= 2) {
    write_prog(prog, proglen, (*pc) + 3, ARG(1) == ARG(2));
    *pc += 4;
    return 1;
    } else {
    return 0;
    }
    default:
    return 0;
    }
    }
    int read_prog(int *prog, int proglen, int pos, int mode) {
    if(pos < 0 || pos >= proglen) {
    return 0;
    }
    if(mode) {
    return prog[pos];
    } else {
    return read_prog(prog, proglen, prog[pos], 1);
    }
    }
    void write_prog(int *prog, int proglen, int pos, int value) {
    if(pos <= proglen) {
    int real_pos = prog[pos];
    if(real_pos <= proglen) {
    prog[real_pos] = value;
    }
    }
    }
    int* do_read(int *len, FILE *source) {
    ll* as_list = NULL;
    int *r = NULL;
    as_list = ll_read(source);
    r = to_a(as_list, len);
    ll_free(as_list);
    return r;
    }
    int* to_a(ll *head, int *len) {
    int *r = NULL;
    int i = 0;
    if(!head)
    return NULL;
    *len = ll_length(head);
    r = malloc(*len * sizeof(int));
    while(head) {
    r[i++] = head->val;
    head = head->nxt;
    }
    return r;
    }
    ll* ll_read(FILE *source) {
    ll *head = NULL;
    ll *cur = NULL;
    ll *tmp = NULL;
    int x;
    while(!feof(source)) {
    fscanf(source, "%d", &x);
    fscanf(source, ",");
    tmp = malloc(sizeof(ll));
    tmp->val = x;
    if(!head) {
    head = tmp;
    }
    if(cur) {
    cur->nxt = tmp;
    }
    cur = tmp;
    }
    return head;
    }
    int ll_length(ll *head) {
    int r = 0;
    while(head) {
    r++;
    head = head->nxt;
    }
    return r;
    }
    void ll_free(ll *head) {
    ll *nxt;
    while(head) {
    nxt = head->nxt;
    free(head);
    head = nxt;
    }
    }