#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;
}

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;
    char *raw_hand;
    //debug_printf("raw line: %s\n", line);
    
    sscanf(line, "Game %d: %m[0-9a-z,; ]\n", &game_id, &raw_hand);

    gameArray[linesProcessed] = (Game){game_id, 0, {(Hand){0,0,0,0}}, (Hand){0,0,0,0}, 1};
    debug_printf("Reconstruct: ~~Game %d: %s~~\n", game_id, raw_hand);

    int hand_index = 0;
    char count_buf[10] = "";
    memset(count_buf, '\0', sizeof(count_buf));
    for (int i = 0; i<=strlen(raw_hand); i++){
      char current_char = raw_hand[i];
      //debug_printf("i: %d.%d, hand_index: %d; count_buf:~%s~; current_char: %c\n", i, strlen(raw_hand), hand_index, count_buf, current_char);
      if (current_char == ';' || i == strlen(raw_hand)){
        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));
      }
    }
    free(raw_hand);
    linesProcessed++;
  }
  printf("\n Ingested %d Lines\n", linesProcessed);
  printf("===================================\n");

  int gamesProcessed = 0;
  int sum_of_valid_games = 0;
  for (int i=0; i<100; i++){
    if (gameArray[i].id != 0){
      gameArray[i].valid = validateGame(gameArray[i], bag_limits);
      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, hands[]={ %s} )\n", gameArray[i].id, gameArray[i].num_hands, gameArray[i].valid, hands_stringify);

      if (gameArray[i].valid == 1){
        sum_of_valid_games+=gameArray[i].id;
      }
      gamesProcessed++;
    }
  }

  printf("\n Processed %d Games\n", gamesProcessed);
  printf("===================================\n");

  

  printf("Answer: \n%d\n", sum_of_valid_games);
}

