>>106582693
>day 12 pt2
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define NBOR(i, di) \
((i) + d[di][1]*w + d[di][0])
#define SAME(i, c) \
((i) >= 0 && (i) < n && (buf[i] == c || buf[i] == '\1'))
static char *buf;
static int n, w;
static int area, perimeter, sides;
static const int d[][2] = {
{0, 1}, {0, -1}, {1, 0}, {-1, 0},
};
static void
measure(int i) {
int c, di, j, k, l;
c = buf[i];
buf[i] = '\1';
for (di = 0; di < 4; di++) {
j = NBOR(i, di);
if (!SAME(j, c)) {
k = NBOR(i, (di+2)%4);
l = NBOR(k, di);
if (!SAME(k, c) || (SAME(k, c) && SAME(l, c)))
sides++;
perimeter++;
}
else if (buf[j] != '\1')
measure(j);
}
area++;
}
static void
clear(int i) {
int di, j;
buf[i] = '\0';
for (di = 0; di < 4; di++) {
j = NBOR(i, di);
if (SAME(j, '\1'))
clear(j);
}
}
int
main(void) {
int silver, gold;
struct stat s;
int i, j;
fstat(0, &s);
n = s.st_size;
buf = mmap(NULL, n, PROT_READ|PROT_WRITE, MAP_PRIVATE, 0, 0);
for (w = 0; buf[w++] != '\n'; );
silver = gold = 0;
for (i = 0; i < n; i++)
if (buf[i] && buf[i] != '\n') {
area = perimeter = sides = 0;
measure(i);
silver += area*perimeter;
gold += area*sides;
clear(i);
}
printf("%d\n%d\n", silver, gold);
}