advent-of-code

advent of code attempts
git clone git://bvnf.space/advent-of-code.git
Log | Files | Refs

b.c (2523B)


      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#define NUM_STACKS 9

struct stack {
    char c;
    struct stack *next;
};

struct stack *stacks[NUM_STACKS];

void
stack_init(unsigned n) {
    /* NULL means bottom of the stack. */
    stacks[n-1] = NULL;
}

char
stack_pop(unsigned n) {
    char c;
    struct stack *old;

    if (stacks[n-1] == NULL) {
        fprintf(stderr, "stack underflow!\n");
        exit(1);
    }

    c = stacks[n-1]->c;
    old = stacks[n-1];
    stacks[n-1] = stacks[n-1]->next;
    free(old);
    return c;
}

void
stack_push(unsigned n, char c) {
    struct stack *new = malloc(sizeof (struct stack));
    if (new == NULL) {
        perror("malloc");
        exit(1);
    }
    new->c = c;
    new->next = stacks[n-1];
    stacks[n-1] = new;
}

void
stack_destroy(unsigned n) {
    struct stack *j, *i = stacks[n-1];
    while (i != NULL) {
        j = i->next;
        free(i);
        i = j;
    }
}

int
main(int argc, char **argv) {
    char *buf = NULL;
    size_t buflen = 0;
    ssize_t n;
    FILE *f;

    for (int i = 1; i <= NUM_STACKS; i++)
        stack_init(i);

    if (argc != 2) {
        fprintf(stderr, "usage: %s input\n", argv[0]);
        return 1;
    }

    f = fopen(argv[1], "r");
    if (f == NULL) {
        perror(argv[1]);
        return 1;
    }

    /* initialise stacks */
    char inits[][9] = {
        "QMGCL",
        "RDLCTFHG",
        "VJFNMTWR",
        "JFDVQP",
        "NFMSLBT",
        "RNVHCDP",
        "HCT",
        "GSJVZNHP",
        "ZFHG"};
    for (unsigned i = 0; i < sizeof(inits)/sizeof(inits[0]); i++) {
        for (int j = 0; inits[i][j] != '\0'; j++) {
            stack_push(i+1, inits[i][j]);
        }
    }


    while ((n = getline(&buf, &buflen, f)) != -1) {
        if (buf[n - 1] == '\n') {
            buf[n - 1] = '\0';
            n--;
        }
        unsigned num_to_move, from, to;
        if (sscanf(buf, "move %u from %u to %u", &num_to_move, &from, &to) != 3) {
            perror("sscanf");
            free(buf);
            exit(1);
        }
        char to_push[num_to_move];
        for (unsigned i = 0; i < num_to_move; i++) {
            char c = stack_pop(from);
            to_push[i] = c;
        }
        for (int i = num_to_move-1; i >= 0; i--) {
            stack_push(to, to_push[i]);
        }
    }

    free(buf);
    fclose(f);

    for (int i = 1; i <= NUM_STACKS; i++) {
        printf("%c", stacks[i-1]->c);
        stack_destroy(i);
    }
    printf("\n");

    return 0;
}