summaryrefslogtreecommitdiffstats
path: root/6/1.c
diff options
context:
space:
mode:
Diffstat (limited to '6/1.c')
-rw-r--r--6/1.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/6/1.c b/6/1.c
new file mode 100644
index 0000000..2a8504e
--- /dev/null
+++ b/6/1.c
@@ -0,0 +1,92 @@
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+enum {
+ WIDTH = 1000,
+ HEIGHT = 1000,
+};
+
+struct instr {
+ enum action {
+ A_OFF,
+ A_ON,
+ A_TOGGLE,
+ } act;
+ struct pos {
+ unsigned short x, y;
+ } start, end;
+};
+
+unsigned short read_be16(void *_buf)
+{
+ unsigned char *buf = _buf;
+ return (buf[0] << 8) | buf[1];
+}
+
+bool read_instr(struct instr *i, FILE *f)
+{
+ unsigned char buf[9];
+ unsigned short v;
+
+ assert(i != NULL);
+ assert(f != NULL);
+
+ if (fread(buf, sizeof buf, 1, f) != 1)
+ return false;
+ switch (buf[0]) {
+ case 0xff: i->act = A_OFF; break;
+ case 1: i->act = A_ON; break;
+ case 2: i->act = A_TOGGLE; break;
+ default: return false;
+ }
+
+#define SET(f, p) { \
+ v = read_be16(&buf[p]); \
+ if (v > 999) \
+ return false; \
+ i->f = v; \
+ }
+ SET(start.x, 1);
+ SET(start.y, 3);
+ SET(end.x, 5);
+ SET(end.y, 7);
+
+ return true;
+}
+
+int main(void)
+{
+ char *map[] = { "turn off", "turn on", "toggle" };
+ bool screen[WIDTH][HEIGHT] = { 0 };
+ struct instr i;
+ int count = 0;
+ FILE *f;
+
+ f = fopen("inputbin", "rb");
+ if (f == NULL)
+ exit(EXIT_FAILURE);
+
+ while (read_instr(&i, f)) {
+ for (int y = i.start.y; y <= i.end.y; y++) {
+ for (int x = i.start.x; x <= i.end.x; x++) {
+ switch (i.act) {
+ case A_OFF: screen[x][y] = false; break;
+ case A_ON: screen[x][y] = true; break;
+ case A_TOGGLE:
+ screen[x][y] = !screen[x][y];
+ break;
+ }
+ }
+ }
+ }
+
+ fclose(f);
+
+ for (int y = 0; y < HEIGHT; y++)
+ for (int x = 0; x < WIDTH; x++)
+ count += screen[x][y];
+
+ printf("%d\n", count);
+}