#include #include #include #include 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); for (char *ap=algo; *ap; ap++) *ap = *ap == '#'; 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; back[y * stride + x] = algo[v]; } } } } 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); }