#include #include #include #include #include #include "../libs/buffered_reader.h" #include "../libs/data_structures.h" #define MAX_RED 12 #define MAX_GREEN 13 #define MAX_BLUE 14 int decodea(char *str); int decodeb(char *str); int get_color(const char *str); bool validate_round(char *str, int dice[]); // SEPARATORS const char *GAME_SEP = ":"; const char *COLOR_SEP = ","; const char *ROUND_SEP = ";"; // COLOR const char *RED = "red"; const char *GREEN = "green"; const char *BLUE = "blue"; list *stack; enum Color { Red = 0, Green = 1, Blue = 2 }; int main(int argc, char *argv[]) { if (argc < 3) { printf("usage: day2 INPUT_FILE a|b\n"); exit(1); } char part = *argv[2]; filelines *lines = flines(argv[1]); if (lines == NULL) { printf("Failed to read file"); exit(1); } // init stack initList(&stack); int sum = 0; for (int i = 0; i < lines->size; i++) { int d = 0; //based on cli input change function switch (part) { case 'a': d = decodea(get(lines, i)); break; case 'b': d = decodeb(get(lines, i)); break; } /* if (d == 0) { printf("^^^^ Game %d ^^^^^\n", i + 1); } else { printf("---- Game %d -----\n", i + 1); } */ sum += d; } printf("Sum: %d\n", sum); } int decodea(char *str) { // find semicolon int game_split = strcspn(str, GAME_SEP); char *game_str = str + game_split + 1; if (!*game_str || str == game_str) { printf("Could not find game separator.\n"); exit(1); } // parse colors char *token; token = strtok(game_str, ";"); filelines *rounds; initFileLines(&rounds); // Get rounds while (token) { insert(rounds, token); token = strtok(NULL, ";"); } // validate rounds for (int i = 0; i < rounds->size; i++) { int dice[] = {0, 0, 0}; if (!validate_round(get(rounds, i), dice)) { return 0; } } freeLines(rounds); clears(stack); int space_index = strcspn(str, " "); for (int i = space_index + 1; i < game_split; i++) { pushs(stack, *(str + i)); } return atoi(contents(stack)); } int decodeb(char *str) { // find semicolon int game_split = strcspn(str, GAME_SEP); char *game_str = str + game_split + 1; if (!*game_str || str == game_str) { printf("Could not find game separator.\n"); exit(1); } // parse colors char *token; token = strtok(game_str, ";"); filelines *rounds; initFileLines(&rounds); // Get rounds while (token) { insert(rounds, token); token = strtok(NULL, ";"); } int min[] = {0,0,0}; // validate rounds for (int i = 0; i < rounds->size; i++) { int dice[] = {0, 0, 0}; validate_round(get(rounds, i), dice); min[Red] = dice[Red] >= min[Red] ? dice[Red] : min[Red]; min[Green] = dice[Green] >= min[Green] ? dice[Green] : min[Green]; min[Blue] = dice[Blue] >= min[Blue] ? dice[Blue] : min[Blue]; } return min[Red] * min[Green] * min[Blue]; } int get_color(const char *str) { if (strstr(str, RED)) { return Red; } if (strstr(str, GREEN)) { return Green; } if (strstr(str, BLUE)) { return Blue; } return -1; } bool validate_round(char *str, int dice[]) { list *color_list; initList(&color_list); char *token; token = strtok(str, ","); while (token) { // trim leading whitespace while (isspace(*token)) token++; // printf("%s,", token); // actually do the stuff clears(color_list); char *c = token; while (c) { if (isspace(*c)) { break; } pushs(color_list, *c); c++; } enum Color color = get_color(token); dice[color] += atoi(contents(color_list)); token = strtok(NULL, ","); } // printf("\n"); freelist(color_list); return dice[Red] <= MAX_RED && dice[Green] <= MAX_GREEN && dice[Blue] <= MAX_BLUE; }