diff options
Diffstat (limited to '6/2.c')
-rw-r--r-- | 6/2.c | 89 |
1 files changed, 89 insertions, 0 deletions
@@ -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); +} |