2024-12-04 06:19:26 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
struct grid {
|
|
|
|
char** A;
|
|
|
|
int x, y;
|
|
|
|
};
|
|
|
|
|
|
|
|
void* xrealloc(void* ptr, size_t size) {
|
|
|
|
if (size == 0) {
|
|
|
|
size = 1;
|
|
|
|
}
|
|
|
|
ptr = realloc(ptr, size);
|
|
|
|
if (ptr == NULL) {
|
|
|
|
fprintf(stderr, "fatal: alloc(%zd) failed", size);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int readfile(const char* filename, struct grid* out) {
|
|
|
|
FILE *fp = fopen(filename, "r");
|
|
|
|
if (fp == NULL) {
|
|
|
|
perror("fopen");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int len = 0;
|
|
|
|
int cap = 100;
|
|
|
|
char* data = xrealloc(NULL, cap);
|
|
|
|
for (;;) {
|
|
|
|
if (len >= cap) {
|
|
|
|
cap *= 2;
|
|
|
|
data = xrealloc(data, cap);
|
|
|
|
}
|
|
|
|
int c = fgetc(fp);
|
|
|
|
if (c == -1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
data[len] = c;
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
int i, nl=0;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
if (data[i] == '\n') {
|
|
|
|
nl++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// split on newlines
|
|
|
|
char** lines = xrealloc(NULL, nl * sizeof(char*));
|
|
|
|
char* p = data;
|
|
|
|
int mincol = INT_MAX;
|
|
|
|
i = 0;
|
|
|
|
while (p != NULL && p < data+len) {
|
|
|
|
lines[i++] = p;
|
|
|
|
char* q = memchr(p, '\n', (data+len)-p);
|
|
|
|
if (!q) {
|
|
|
|
break; // TODO: final line?
|
|
|
|
}
|
|
|
|
int col = q - p;
|
|
|
|
if (mincol > col && col > 0) {
|
|
|
|
mincol = col;
|
|
|
|
}
|
|
|
|
p = q+1; // skip newline
|
|
|
|
}
|
|
|
|
|
|
|
|
out->A = lines;
|
|
|
|
out->x = mincol;
|
|
|
|
out->y = nl;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool search(struct grid *g, int x, int y, int dx, int dy, const char* word) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; word[i] != '\0'; i++) {
|
|
|
|
if (!(0 <= x && x < g->x && 0 <= y && y < g->y)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (g->A[y][x] != word[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
x += dx;
|
|
|
|
y += dy;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int solve(struct grid *g) {
|
|
|
|
int x, y;
|
|
|
|
int count = 0;
|
|
|
|
const char *word = "XMAS";
|
|
|
|
for (y = 0; y < g->y; y++)
|
|
|
|
for (x = 0; x < g->x; x++) {
|
|
|
|
if (g->A[y][x] != 'X') continue;
|
|
|
|
if (search(g, x, y, 0, +1, word)) { count++; }
|
|
|
|
if (search(g, x, y, +1, 0, word)) { count++; }
|
|
|
|
if (search(g, x, y, -1, 0, word)) { count++; }
|
|
|
|
if (search(g, x, y, 0, -1, word)) { count++; }
|
|
|
|
if (search(g, x, y, +1, +1, word)) { count++; }
|
|
|
|
if (search(g, x, y, -1, -1, word)) { count++; }
|
|
|
|
if (search(g, x, y, +1, -1, word)) { count++; }
|
|
|
|
if (search(g, x, y, -1, +1, word)) { count++; }
|
|
|
|
}
|
|
|
|
printf("%d\n", count);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-12-04 06:22:21 +00:00
|
|
|
int solve2(struct grid *g) {
|
|
|
|
int x, y;
|
|
|
|
int count = 0;
|
|
|
|
const char *word = "MAS";
|
|
|
|
for (y = 0; y < g->y; y++)
|
|
|
|
for (x = 0; x < g->x; x++) {
|
|
|
|
if (g->A[y][x] != 'A') continue;
|
|
|
|
int mas = 0;
|
|
|
|
if (search(g, x-1, y-1, +1, +1, word)) { mas++; }
|
|
|
|
if (search(g, x+1, y+1, -1, -1, word)) { mas++; }
|
|
|
|
if (search(g, x-1, y+1, +1, -1, word)) { mas++; }
|
|
|
|
if (search(g, x+1, y-1, -1, +1, word)) { mas++; }
|
|
|
|
if (mas == 2) { count++; }
|
|
|
|
}
|
|
|
|
printf("%d\n", count);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-12-04 06:19:26 +00:00
|
|
|
int main() {
|
|
|
|
struct grid g;
|
|
|
|
//readfile("sample2.in", &g);
|
|
|
|
readfile("input", &g);
|
|
|
|
printf("%d %d\n", g.x, g.y);
|
|
|
|
solve(&g);
|
2024-12-04 06:22:21 +00:00
|
|
|
solve2(&g);
|
2024-12-04 06:19:26 +00:00
|
|
|
}
|