advent-of-code/day-02/src/part02.c

165 lines
5.6 KiB
C

#include <ctype.h>
#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#define debug_printf(...) do{ fprintf( stderr, __VA_ARGS__ ); } while( 0 )
#else
#define debug_printf(...) do{ } while ( 0 )
#endif
#define LINE_MAX 160
#define GAME_MAX 101
#define GAME_MAX_HANDS 10
typedef struct Hand {
int red;
int green;
int blue;
int set;
} Hand;
typedef struct Game {
int id;
int num_hands;
Hand hands[GAME_MAX_HANDS];
Hand min_cubes;
int valid;
} Game;
Game gameArray[GAME_MAX];
Hand bag_limits = {12, 13, 14, 1};
//Takes a game as a param, returns if the game is valid 0 or 1
int validateGame(Game game, Hand limit){
if (game.id == 0) return 0;
if (game.num_hands == 0) return 0;
for (int i=0; i<game.num_hands; i++){
if (game.hands[i].red > limit.red) return 0;
if (game.hands[i].green > limit.green) return 0;
if (game.hands[i].blue > limit.blue) return 0;
}
return 1;
}
//Takes a game as a param, returns hand of min size for inputs
Hand minCubes(Game game){
Hand min = (Hand){0,0,0,0};
if (game.id == 0) return min;
if (game.num_hands == 0) return min;
for (int i=0; i<game.num_hands; i++){
if (game.hands[i].red > min.red) min.red = game.hands[i].red;
if (game.hands[i].green > min.green) min.green = game.hands[i].green;
if (game.hands[i].blue > min.blue) min.blue = game.hands[i].blue;
}
min.set = 1;
return min;
}
void genHandString(char* dest, Game game){
int offset = 0;
for (int i=0; i<game.num_hands; i++){
offset += sprintf(dest+offset, "{r:%02d, g:%02d, b:%02d}, ", game.hands[i].red, game.hands[i].green, game.hands[i].blue);
}
}
int main(int argc, char *argv[]){
int linesProcessed = 0;
char line[LINE_MAX];
//debug_printf("size of game: %dbytes\n", (int)sizeof(Game));
while (fgets(line, LINE_MAX, stdin) != NULL) {
int game_id;
//debug_printf("raw line: %s\n", line);
char id_buf[4];
int colon_index = (int)(strchr(line, ':') - line);
strncpy(id_buf, &line[5], colon_index-5);
game_id = atoi(id_buf);
//debug_printf("id_buf: -%s- game_id: %d\n", id_buf, game_id);
gameArray[linesProcessed] = (Game){game_id, 0, {(Hand){0,0,0,0}}, (Hand){0,0,0,0}, 1};
char raw_hand_buffer[LINE_MAX]; //make a buffer to hold the rest of the game info for parsing later
memset(raw_hand_buffer, '\0', sizeof(raw_hand_buffer));
int end_index = (int)(strchr(line, '\n') - line); //debug_printf("endIndex: %d\n", end_index);
strncpy(raw_hand_buffer, &line[colon_index+2], end_index-(colon_index+2));
//debug_printf("game_id: %d; raw_hand_buffer: ~~%s~~\n", game_id, raw_hand_buffer);
debug_printf("Reconstruct: ~~Game %d: %s~~\n", game_id, raw_hand_buffer);
int hand_index = 0;
char count_buf[10] = "";
memset(count_buf, '\0', sizeof(count_buf));
for (int i = 0; i<=strlen(raw_hand_buffer); i++){
char current_char = raw_hand_buffer[i];
//debug_printf("i: %d.%d, hand_index: %d; count_buf:~%s~; current_char: %c\n", i, strlen(raw_hand_buffer), hand_index, count_buf, current_char);
if (current_char == ';' || i == strlen(raw_hand_buffer)){
memset(count_buf, '\0', sizeof(count_buf));
gameArray[linesProcessed].hands[hand_index].set = 1;
gameArray[linesProcessed].num_hands = hand_index+1;
debug_printf("Commited game %d hand %d: {r:%d g:%d b:%d}\n", game_id, hand_index, gameArray[linesProcessed].hands[hand_index].red, gameArray[linesProcessed].hands[hand_index].green, gameArray[linesProcessed].hands[hand_index].blue);
hand_index++;
} else if (isdigit(current_char)){
strncat(count_buf, &current_char, 1);
} else if (isalpha(current_char)){
debug_printf("count_buf: %s; setting hand %c: %d\n", count_buf, current_char, atoi(count_buf));
if (current_char == 'r'){
gameArray[linesProcessed].hands[hand_index].red = atoi(count_buf);
i+=2;
} else if (current_char == 'g'){
gameArray[linesProcessed].hands[hand_index].green = atoi(count_buf);
i+=4;
} else if (current_char == 'b'){
gameArray[linesProcessed].hands[hand_index].blue = atoi(count_buf);
i+=3;
}
memset(count_buf, '\0', sizeof(count_buf));
}
}
linesProcessed++;
}
printf("\n Ingested %d Lines\n", linesProcessed);
printf("===================================\n");
int gamesProcessed = 0;
int sum_of_valid_games = 0;
int sum_of_powers_of_min_cubes = 0;
for (int i=0; i<100; i++){
if (gameArray[i].id != 0){
gameArray[i].valid = validateGame(gameArray[i], bag_limits);
gameArray[i].min_cubes = minCubes(gameArray[i]);
char hands_stringify[22*GAME_MAX_HANDS];
memset(hands_stringify, '\0', sizeof(hands_stringify));
genHandString(hands_stringify, gameArray[i]);
printf("Game( id=%03d, num_hands=%d, valid=%d, min_cubes={ r:%02d, g:%02d, b:%02d }, hands[]={ %s} )\n", gameArray[i].id, gameArray[i].num_hands, gameArray[i].valid, gameArray[i].min_cubes.red, gameArray[i].min_cubes.green, gameArray[i].min_cubes.blue, hands_stringify);
if (gameArray[i].valid == 1){
sum_of_valid_games+=gameArray[i].id;
}
if (gameArray[i].min_cubes.set == 1){
sum_of_powers_of_min_cubes+=gameArray[i].min_cubes.red*gameArray[i].min_cubes.green*gameArray[i].min_cubes.blue;
}
gamesProcessed++;
}
}
printf("\n Processed %d Games\n", gamesProcessed);
printf("===================================\n");
printf("sum_of_valid_games: \n%d\n", sum_of_valid_games);
printf("sum_of_powers_of_min_cubes: \n%d\n", sum_of_powers_of_min_cubes);
}