2021-12-20 12:57:05 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
static void pbm(char *front, size_t stride) {
|
|
|
|
printf("P1\n%lu %lu\n", stride, stride);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < stride * stride; i++) {
|
|
|
|
putchar(front[i] ? '1' : '0');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
int vis = 0, opt;
|
|
|
|
long long maxiter = 50;
|
|
|
|
|
|
|
|
while ((opt = getopt(argc, argv, "vi:")) != -1) {
|
|
|
|
switch (opt) {
|
|
|
|
case 'v':
|
|
|
|
vis = 1;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
maxiter = atoll(optarg);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage:
|
|
|
|
fprintf(stderr, "Usage: %s [-v] [-i iterations] input\n\n"
|
|
|
|
"-v output is NetPBM, readable by FFmpeg\n",
|
|
|
|
argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (optind >= argc)
|
|
|
|
goto usage;
|
|
|
|
|
|
|
|
char *algo = NULL, *front = NULL, *back = NULL, *s;
|
|
|
|
size_t stride = 0, S = 0, G = 0;
|
|
|
|
|
|
|
|
FILE *fp = fopen(argv[optind], "r");
|
|
|
|
if(!fp) {
|
|
|
|
fprintf(stderr, "%s: Could not open file '%s': ",
|
|
|
|
argv[0], argv[optind]);
|
|
|
|
perror("");
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fscanf(fp, "%ms", &algo);
|
2021-12-20 13:31:29 +01:00
|
|
|
for (char *ap=algo; *ap; ap++)
|
|
|
|
*ap = *ap == '#';
|
2021-12-20 12:57:05 +01:00
|
|
|
|
|
|
|
while (fscanf(fp, "%ms\n", &s) == 1) {
|
|
|
|
size_t len = strlen(s);
|
|
|
|
char *dst;
|
|
|
|
|
|
|
|
if (!stride) {
|
|
|
|
stride = len * 3;
|
|
|
|
front = calloc(stride * stride, 1);
|
|
|
|
dst = front + stride * len;
|
|
|
|
}
|
|
|
|
|
|
|
|
dst += len;
|
|
|
|
for (size_t c = 0; c < len; c++)
|
|
|
|
*dst++ = s[c] == '#';
|
|
|
|
dst += len;
|
|
|
|
|
|
|
|
free(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
back = malloc(stride * stride);
|
|
|
|
memcpy(back, front, stride * stride);
|
|
|
|
|
|
|
|
for (long long iter = 0; iter < maxiter; iter++) {
|
|
|
|
if (vis && iter & 1) pbm(front, stride);
|
|
|
|
|
|
|
|
if (iter == 2) {
|
|
|
|
for (int p = 0; p < stride * stride; p++)
|
|
|
|
S += front[p];
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
for (size_t y = 0; y < stride; y++) {
|
|
|
|
for (size_t x = 0; x < stride; x++) {
|
|
|
|
int v = 0;
|
|
|
|
|
|
|
|
for (int yy = -1; yy <= 1; yy++) {
|
|
|
|
for (int xx = -1; xx <= 1; xx++) {
|
|
|
|
v <<= 1;
|
|
|
|
|
|
|
|
if (y + yy > 0 && y + yy < stride &&
|
|
|
|
x + xx > 0 && x + xx < stride)
|
|
|
|
v |= front[(y + yy) * stride + x + xx];
|
|
|
|
else
|
|
|
|
v |= iter & 1;
|
|
|
|
|
2021-12-20 13:31:29 +01:00
|
|
|
back[y * stride + x] = algo[v];
|
2021-12-20 12:57:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char *tmp=front;
|
|
|
|
front=back;
|
|
|
|
back=tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t p = 0; p < stride * stride; p++)
|
|
|
|
G += front[p];
|
|
|
|
|
|
|
|
fprintf(stderr, "Silver: %lu\nGold: %lu\n", S, G);
|
|
|
|
|
|
|
|
free(front);
|
|
|
|
free(algo);
|
|
|
|
free(back);
|
|
|
|
}
|