aoc2024/12/part2.c

151 lines
5.3 KiB
C

#include "_.h"
int count = 1;
int len = 0;
int lens = 0;
void set(int ***already, char **inputs, int y, int x) {
(*already)[y][x] = inputs[y][x];
if (inputs[y + 1] != NULL && inputs[y][x] == inputs[y + 1][x]
&& (*already)[y + 1][x] == 0) {
set(already, inputs, y + 1, x);
count++;
}
if (y > 0 && inputs[y][x] == inputs[y - 1][x]
&& (*already)[y - 1][x] == 0) {
set(already, inputs, y - 1, x);
count++;
}
if (x < strlen(inputs[y]) - 1 && inputs[y][x] == inputs[y][x + 1]
&& (*already)[y][x + 1] == 0) {
set(already, inputs, y, x + 1);
count++;
}
if (x > 0 && inputs[y][x] == inputs[y][x - 1]
&& (*already)[y][x - 1] == 0) {
set(already, inputs, y, x - 1);
count++;
}
}
int test(int ***already, int ***sides_lines, int check, int *sides, int y, int x, int h, int w, int add_y, int add_x) {
int i = 0;
int abs_y = ABS(add_y), abs_x = ABS(add_x);
for (i = 0; y >= -1 && x >= -1 && y + (i * abs_x) <= h && x + (i * abs_y) <= w && (*already)[y + (i * abs_x)][x + (i * abs_y)] != check && (*already)[y + (i * abs_x) + add_y][x + (i * abs_y) + add_x] == check && (*sides_lines)[y + (i * abs_x)][x + (i * abs_y)] == 0; i++) {
if ((i == 0 && (*sides_lines)[y + (-1 * abs_x)][x + (-1 * abs_y)] != 0) ||
(*sides_lines)[y + 1 + (i * abs_x)][x + (i * abs_y)] != 0 ||
(*sides_lines)[y + (i * abs_x)][x + 1 + (i * abs_y)] != 0 ||
(abs_x != 0 && (*sides_lines)[y + i][x - 1] != 0) ||
(abs_y != 0 && (*sides_lines)[y - 1][x + i] != 0)) {
(*sides_lines)[y][x] = 0;
for (; i >= 0; i--)
(*sides_lines)[y + i][x] = 0;
i = 0;
break;
}
(*sides_lines)[y + (i * abs_x)][x + (i * abs_y)] = *sides + 1;
}
if (i > 0) {
int top = 0, bottom = 0, left = 0, right = 0;
for (int j = 0; j < i; j++) {
top = top ? 1 : (*already)[y - 1 + (j * abs_x)][x + (j * abs_y)] == check;
if (top && add_y != 1) {
test(already, sides_lines, check, sides, y + 1, x, h, w, 0, 1);
test(already, sides_lines, check, sides, y + 1, x, h, w, 0, -1);
}
bottom = bottom ? 1 : (*already)[y + 1 + (j * abs_x)][x + (j * abs_y)] == check;
if (bottom && add_y != -1) {
test(already, sides_lines, check, sides, y - 1, x, h, w, 0, 1);
test(already, sides_lines, check, sides, y - 1, x, h, w, 0, -1);
}
right = right ? 1 : (*already)[y + (j * abs_x)][x + 1 + (j * abs_y)] == check;
if (right && add_x != 1) {
test(already, sides_lines, check, sides, y, x, h, w, 1, 0);
test(already, sides_lines, check, sides, y, x, h, w, -1, 0);
}
left = left ? 1 : (*already)[y + (j * abs_x)][x - 1 + (j * abs_y)] == check;
if (left && add_x != -1) {
test(already, sides_lines, check, sides, y, x, h, w, 1, 0);
test(already, sides_lines, check, sides, y, x, h, w, -1, 0);
}
}
*sides += (top + bottom + left + right);
return 1;
}
return 0;
}
int get_side(int ***already, int check, int h, int w) {
int **sides_lines = calloc(lens + 2, sizeof(int*));
for (int i = -2; i < len + 2; i++) {
sides_lines[i] = calloc(len + 2, sizeof(int));
for (int j = -2; j < len + 2; j++)
sides_lines[i][j] = 0;
}
int **new_already = calloc(lens + 2, sizeof(int*));
for (int i = -2; i < len + 2; i++) {
new_already[i] = calloc(len + 2, sizeof(int));
for (int j = -2; j < len + 2; j++) {
new_already[i][j] = (*already)[i][j];
}
}
int sides = 0;
for (int y = -1; y < h + 1; y++) {
for (int x = -1; x < w + 1; x++) {
if (x >= 0 && y >= 0 && x < w && y < h) {
if ((*already)[y][x] == check) {
new_already[y][x] = -1;
continue;
}
}
test(already, &sides_lines, check, &sides, y, x, h, w, 1, 0);
test(already, &sides_lines, check, &sides, y, x, h, w, -1, 0);
test(already, &sides_lines, check, &sides, y, x, h, w, 0, 1);
test(already, &sides_lines, check, &sides, y, x, h, w, 0, -1);
}
}
(*already) = new_already;
return sides;
}
int main(int argc, char **argv) {
if (argc != 2)
return 1;
char *input = argv[1];
char **inputs = str_split(strdup(input), '\n');
len = strlen(inputs[0]);
lens = strslen(inputs);
int **already = calloc(lens + 2, sizeof(int*));
for (int i = -2; i < len + 2; i++)
already[i] = calloc(len + 2, sizeof(int));
long result = 0;
for (int i = 0; inputs[i] != NULL; i++) {
for (int j = 0; inputs[i][j] != '\0'; j++) {
if (already[i][j] == 0) {
set(&already, inputs, i, j);
long side = get_side(&already, already[i][j], lens, len);
result += (count * side);
printf("side: %ld\n", side);
printf("count: %d\n\n", count);
//printf("result: %ld\n", result);
count = 1;
}
}
}
printf("result: %ld\n", result);
return 0;
}