1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <stdbool.h>
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);
}
|