summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2023-12-02 22:35:29 +0000
committerTomasz Kramkowski <tomasz@kramkow.ski>2023-12-02 22:35:29 +0000
commit3bc9b83494916ed3928556dae7773664e70c6f21 (patch)
treebdd4cfe26bf07d38f59cf5165132992e732e27eb
parent86eea5204564fb161faa96fcdd9580d7bd6e0d47 (diff)
downloadaoc2023-3bc9b83494916ed3928556dae7773664e70c6f21.tar.gz
aoc2023-3bc9b83494916ed3928556dae7773664e70c6f21.tar.xz
aoc2023-3bc9b83494916ed3928556dae7773664e70c6f21.zip
day 2 in C
-rw-r--r--2.c92
-rw-r--r--Makefile1
2 files changed, 93 insertions, 0 deletions
diff --git a/2.c b/2.c
new file mode 100644
index 0000000..1edf10c
--- /dev/null
+++ b/2.c
@@ -0,0 +1,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);
+}
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3511ed7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1 @@
+CFLAGS += -std=c11