DEV Community

Discussion on: AoC Day 9: Marble Mania

Collapse
 
hoelzro profile image
Rob Hoelz

I did today's entry in C, both for fun and because writing linked lists just feels natural in C!

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

struct node {
    int64_t value;
    struct node *next;
    struct node *prev;
};

int
main(int argc, char **argv)
{
    int num_players;
    int last_marble;

    int i;
    struct node *current_node;
    struct node *node_pool;
    int current_player;
    int64_t *scores;
    int64_t max_score;

    if(argc < 3) {
        fprintf(stderr, "usage: %s [num players] [high score marble]\n", argv[0]);
        return 1;
    }

    num_players = atoi(argv[1]);
    last_marble = atoi(argv[2]);

    node_pool = malloc(sizeof(struct node) * (last_marble + 1));

    current_node = node_pool++;
    current_node->value = 0;
    current_node->next = current_node;
    current_node->prev = current_node;

    scores = malloc(sizeof(int64_t) * num_players);
    memset(scores, 0, sizeof(int64_t) * num_players);

    current_player = 0;

    for(i = 1; i <= last_marble; i++) {
        if(i % 23 == 0) {
            int j;
            struct node *prev;
            struct node *next;

            for(j = 0; j < 7; j++) {
                current_node = current_node->prev;
            }

            scores[current_player] += i;
            scores[current_player] += current_node->value;

            prev = current_node->prev;
            next = current_node->next;

            prev->next = next;
            next->prev = prev;

            current_node = next;

        } else {
            struct node *new_node;

            current_node = current_node->next;

            new_node = node_pool++;

            new_node->value = i;
            new_node->prev = current_node;
            new_node->next = current_node->next;
            current_node->next->prev = new_node;
            current_node->next = new_node;

            current_node = new_node;
        }

        current_player = (current_player + 1) % num_players;
    }

    max_score = 0;
    for(i = 0; i < num_players; i++) {
        if(scores[i] > max_score) {
            max_score = scores[i];
        }
    }

    printf("%ld\n", max_score);

    return 0;
}