summaryrefslogtreecommitdiffstats
path: root/6/2.c
diff options
context:
space:
mode:
Diffstat (limited to '6/2.c')
-rw-r--r--6/2.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/6/2.c b/6/2.c
new file mode 100644
index 0000000..c9d1083
--- /dev/null
+++ b/6/2.c
@@ -0,0 +1,89 @@
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+enum {
+ WIDTH = 1000,
+ HEIGHT = 1000,
+};
+
+struct instr {
+ signed char db;
+ 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];
+ signed char db;
+ unsigned short v;
+
+ assert(i != NULL);
+ assert(f != NULL);
+
+ if (fread(buf, sizeof buf, 1, f) != 1)
+ return false;
+ if (buf[0] <= 127)
+ db = buf[0];
+ else {
+ db = -0x80;
+ db += buf[0] - 0x80;
+ }
+ if (db < -1 || db > 2) {
+ fprintf(stderr, "this db is crazy: %d -> %d\n", buf[0], db);
+ return false;
+ }
+ i->db = db;
+
+#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)
+{
+ int screen[WIDTH][HEIGHT] = { 0 };
+ unsigned long long total;
+ struct instr i;
+ 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++) {
+ screen[x][y] += i.db;
+ if (screen[x][y] < 0)
+ screen[x][y] = 0;
+ }
+ }
+ }
+
+ fclose(f);
+
+ total = 0;
+ for (int y = 0; y < HEIGHT; y++)
+ for (int x = 0; x < WIDTH; x++)
+ total += screen[x][y];
+ printf("%llu\n", total);
+}