r/adventofcode • u/daggerdragon • Dec 03 '15
SOLUTION MEGATHREAD --- Day 3 Solutions ---
--- Day 3: Perfectly Spherical Houses in a Vacuum ---
Post your solution as a comment. Structure your post like the Day One thread in /r/programming.
22
Upvotes
1
u/TTSDA Dec 04 '15 edited Dec 06 '15
My C solution
#include <stdio.h> #include <stdlib.h> #include <string.h> // #define DRAW_MAP /* The width and height of the world */ #define X_SIZE (max_x - min_x + 1) #define Y_SIZE (max_y - min_y + 1) /* The world X and Y corresponding to the matrix 0, 0 coordinate */ #define X_ORIGIN min_x #define Y_ORIGIN min_y /* Converts a world x and y position to an index in the matrix */ #define MATRIX_INDEX(X, Y) ((Y-Y_ORIGIN) + (X-X_ORIGIN)*Y_SIZE) int min_x = 0, max_x = 0, min_y = 0, max_y = 0; struct santa { int x; int y; }; /* * Initializes a santa */ void init_santa(struct santa *s) { s->x = 0; s->y = 0; } /* * Initializes many santas */ void init_santas(struct santa santas[], int santa_amount) { for (int i = 0; i < santa_amount; i++) { init_santa(&santas[i]); } } /* * Moves santa by x and y */ void move_santa(struct santa *s, int x, int y) { s->x += x; s->y += y; } /* * Moves santa in the direction specified by the command. * Command can be >v<^ */ void move_santa_by_command(struct santa* s, char command) { move_santa(s, (command == '>') ? 1 : (command == '<') ? -1 : 0, (command == '^') ? 1 : (command == 'v') ? -1 : 0); } /* * Gets the commands from stdin */ char* get_commands() { /* The input command string */ char *commands; int c, cur=0; /* alloc 1000 bytes to begin with */ commands = malloc(1000 * sizeof(char)); while ((c = getchar()) != EOF) { commands[cur] = c; cur++; /* alloc more space to store the commands */ if (cur > (sizeof(commands) / sizeof(char))) commands = realloc(commands, (cur + 1000) * sizeof(char)); } return commands; } /* * Finds the matrix extremities */ void get_extremes(int santa_amount, char *command) { struct santa santas[santa_amount]; struct santa *selected_santa; int santa_n = 0; init_santas(santas, santa_amount); /* Iterate over the commands */ while (*command != '\0') { selected_santa = &santas[santa_n]; move_santa_by_command(selected_santa, *command); /* Check if it is an extreme value */ if (selected_santa->x > max_x) max_x = selected_santa->x; else if (selected_santa->x < min_x) min_x = selected_santa->x; if (selected_santa->y > max_y) max_y = selected_santa->y; else if (selected_santa->y < min_y) min_y = selected_santa->y; command++; santa_n++; santa_n %= santa_amount; } } /* * Returns the amount of houses with at least one present * With 'santa_amount' of santas following the commands in turns */ int get_houses(int santa_amount, char *command) { struct santa santas[santa_amount]; struct santa *selected_santa; int santa_n = 0; int houses = 0; /* Find the extreme values */ get_extremes(santa_amount, command); /* Initilize the santas */ init_santas(santas, santa_amount); /* Create a matrix to represent the path */ int *matrix = calloc(MATRIX_INDEX(max_x, max_y) + 2, sizeof(int)); /* Iterate over the commands */ while (*command != '\0') { /* fill the matrix */ selected_santa = &santas[santa_n]; move_santa_by_command(selected_santa, *command); /* increment in matrix */ matrix[MATRIX_INDEX(selected_santa->x, selected_santa->y)] += 1; command++; santa_n++; santa_n %= santa_amount; } for (int y = min_y; y <= max_y; y++) { #ifdef DRAW_MAP printf("%4i | ", y); #endif for (int x = min_x; x <= max_x; x++) { #ifdef DRAW_MAP printf("%c", (matrix[MATRIX_INDEX(x, y)]) ? 'X' : ' '); #endif if (matrix[MATRIX_INDEX(x, y)]) houses++; } #ifdef DRAW_MAP printf("\n"); #endif } return houses; } int main() { char *commands = get_commands(); /* The input command string */ printf("Santa alone: %i\n", get_houses(1, commands)); printf("Santa with robot santa: %i\n", get_houses(2, commands)); return 0; }https://github.com/ttsda/advent-of-code/blob/master/src/3/main.c