105 lines
2.9 KiB
C
105 lines
2.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
|
|
int vis(const char *outpath, const char *in, size_t w, size_t h, size_t stride) {
|
|
int fd = open(outpath, O_CREAT | O_RDWR | O_NONBLOCK, 0644);
|
|
if (fd == -1) return 1;
|
|
|
|
char head[128];
|
|
size_t ps = snprintf(head, 128, "P6\n%lu %lu\n255\n", w, h);
|
|
if (ps >= 128) return 1;
|
|
size_t mapsiz = ps + w * h * 3;
|
|
ftruncate(fd, mapsiz);
|
|
unsigned char *o = mmap(NULL, mapsiz, PROT_WRITE, MAP_SHARED, fd, 0);
|
|
if (o == MAP_FAILED) return 1;
|
|
unsigned char *out = o;
|
|
strncpy((char*)out, head, ps);
|
|
out += ps;
|
|
|
|
for(size_t y = 0; y < h; y++) {
|
|
for (size_t x = 0; x < w; x++) {
|
|
int val = in[stride * y + x] - '0';
|
|
float v = val * 0.75 / 10.0;
|
|
unsigned char *b = out + w * y * 3 + x * 3;
|
|
*b++ = 180 * v / 3;
|
|
*b++ = 220 * v;
|
|
*b++ = 150 * v / 1.8;
|
|
}
|
|
}
|
|
|
|
munmap(o, mapsiz);
|
|
return close(fd);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
if (argc < 2) return 1;
|
|
|
|
struct stat s;
|
|
if (stat(argv[1], &s) == -1) return 1;
|
|
int fd = open(argv[1], O_RDONLY);
|
|
if (fd == -1) return 1;
|
|
|
|
char *in = mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
|
if (in == MAP_FAILED) return 1;
|
|
|
|
size_t w = strchr(in, '\n') - in;
|
|
size_t stride = w + 1;
|
|
size_t h = s.st_size / stride;
|
|
size_t visible = w * 2 + (h - 2) * 2;
|
|
size_t maxscore = 0;
|
|
|
|
if (argc > 2) {
|
|
printf("Writing %s... ", argv[2]);
|
|
fflush(stdout);
|
|
if (vis(argv[2], in, w, h, stride)) {
|
|
perror("");
|
|
return 1;
|
|
}
|
|
printf("Done!\n");
|
|
}
|
|
|
|
#pragma omp parallel for reduction(+:visible) reduction(max:maxscore) schedule(runtime)
|
|
for (size_t y = 1; y < h - 1; y++) {
|
|
for (size_t x = 1; x < w - 1; x++) {
|
|
size_t i, score = 0;
|
|
char val = in[stride * y + x];
|
|
int vis = 0;
|
|
|
|
for (i = 1; i <= y; i++)
|
|
if (val <= in[stride * (y - i) + x])
|
|
break;
|
|
vis += i == y + 1;
|
|
score = i - (i == y + 1);
|
|
|
|
for (i = y + 1; i < h; i++)
|
|
if (val <= in[stride * i + x])
|
|
break;
|
|
vis += i == h;
|
|
score *= i - y - (i == h);
|
|
|
|
for (i = 1; i <= x; i++)
|
|
if (val <= in[stride * y + x - i])
|
|
break;
|
|
vis += i == x + 1;
|
|
score *= i - (i == x + 1);
|
|
|
|
for (i = x + 1; i < w; i++)
|
|
if (val <= in[stride * y + i])
|
|
break;
|
|
score *= i - x - (i == w);
|
|
|
|
if (score > maxscore)
|
|
maxscore = score;
|
|
|
|
visible += vis || i == w;
|
|
}
|
|
}
|
|
|
|
printf("Silver: %lu\nGold: %lu\n", visible, maxscore);
|
|
}
|