summaryrefslogtreecommitdiffstats
path: root/2.c
blob: 1edf10c58aefda5edf0719d173c27a6e3d1a78ca (plain)
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);
}