#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 * abs_x)][x + (i * abs_y)] = 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 != 0) { for (int w = 0; ((*already)[y + w][x + 1] == check ||(*already)[y + w][x - 1] == check) && y + w < h && (*already)[y + w][x] != check ; w++) (*sides_lines)[y + w][x] = *sides + 1; } bottom = bottom ? 1 : (*already)[y + 1 + (j * abs_x)][x + (j * abs_y)] == check; if (bottom && add_y != 0) { for (int w = 0; ((*already)[y + 1][x - w] == check ||(*already)[y - 1][x - w] == check) && y + w < h && (*already)[y][x - w] != check ; w++) (*sides_lines)[y - w][x] = *sides + 1; } right = right ? 1 : (*already)[y + (j * abs_x)][x + 1 + (j * abs_y)] == check; if (right && add_x != 1) { } left = left ? 1 : (*already)[y + (j * abs_x)][x - 1 + (j * abs_y)] == check; if (left && add_x != -1) { } } *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; } } if (test(already, &sides_lines, check, &sides, y, x, h, w, 1, 0)) continue; if (test(already, &sides_lines, check, &sides, y, x, h, w, -1, 0)) continue; if (test(already, &sides_lines, check, &sides, y, x, h, w, 0, 1)) continue; if (test(already, &sides_lines, check, &sides, y, x, h, w, 0, -1)) continue; } } (*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; }