#include #include #include #include struct counts { int red, green, blue; }; int main(void) { static const struct counts limits = { 12, 13, 14 }; bool possible = false; int c, id = -1, count = -1, p1 = 0, p2 = 0; struct counts counts, max; enum state { START, GAME_ID, CUBE_COUNT, CUBE_SPACE, CUBE_COLOUR, CUBE_SEP, SUBSET_SEP, } state = START; while (c = getchar(), c != EOF) { enum state prev = state; switch (state) { case START: if (isdigit(c)) state = GAME_ID; break; case GAME_ID: if (!isdigit(c)) state = SUBSET_SEP; break; case CUBE_COUNT: if (!isdigit(c)) state = CUBE_SPACE; break; case CUBE_SPACE: if (isalpha(c)) state = CUBE_COLOUR; break; case CUBE_COLOUR: switch (c) { case ',': state = CUBE_SEP; break; case ';': state = SUBSET_SEP; break; case '\n': state = START; break; } break; case SUBSET_SEP: case CUBE_SEP: if (isdigit(c)) state = CUBE_COUNT; break; } if (prev == START && state == GAME_ID) { id = 0; max = (struct counts){0, 0, 0}; possible = true; } if (state == GAME_ID) { id *= 10; id += c - '0'; } if (prev == SUBSET_SEP && state == CUBE_COUNT) counts = (struct counts){0, 0, 0}; if (prev != CUBE_COUNT && state == CUBE_COUNT) count = 0; if (state == CUBE_COUNT) { count *= 10; count += c - '0'; } if (prev == CUBE_SPACE && state == CUBE_COLOUR) { switch (c) { case 'r': counts.red = count; break; case 'g': counts.green = count; break; case 'b': counts.blue = count; break; default: assert(false && "Unexpected colour"); break; } } if (prev == CUBE_COLOUR && (state == SUBSET_SEP || state == START)) { if (counts.red > max.red) max.red = counts.red; if (counts.green > max.green) max.green = counts.green; if (counts.blue > max.blue) max.blue = counts.blue; if (counts.red > limits.red || counts.green > limits.green || counts.blue > limits.blue) possible = false; } if (prev != START && state == START) { if (possible) p1 += id; p2 += max.red * max.green * max.blue; } } printf("%d\n%d\n", p1, p2); }