Day12
This commit is contained in:
BIN
day12/c/day12
Executable file
BIN
day12/c/day12
Executable file
Binary file not shown.
203
day12/c/day12.c
Normal file
203
day12/c/day12.c
Normal file
@@ -0,0 +1,203 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_DIMENSION 1024
|
||||
#define MAX_REGION 1024
|
||||
|
||||
void fill(char **map, int x, int y, int **region, int rows, int columns);
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
|
||||
char **map = calloc(MAX_DIMENSION, sizeof(map[0]));
|
||||
int rows = 0, columns, i = 0;
|
||||
map[rows] = calloc(MAX_DIMENSION, sizeof(map[0][0]));
|
||||
|
||||
while ((c = getchar()) != EOF) {
|
||||
map[rows][i] = c;
|
||||
i++;
|
||||
if (c != '\n') {
|
||||
continue;
|
||||
}
|
||||
|
||||
columns = i - 1;
|
||||
i = 0;
|
||||
rows++;
|
||||
map[rows] = calloc(MAX_DIMENSION, sizeof(map[0][0]));
|
||||
}
|
||||
|
||||
int **visited = calloc(rows, sizeof(visited[0]));
|
||||
for (i = 0; i < rows; i++) {
|
||||
visited[i] = calloc(columns, sizeof(visited[0][0]));
|
||||
}
|
||||
int ***regions = calloc(MAX_REGION, sizeof(regions[0]));
|
||||
int region_count = 0;
|
||||
|
||||
int cost = 0;
|
||||
int cost2 = 0;
|
||||
for (i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < columns; j++) {
|
||||
if (visited[i][j]) {
|
||||
continue;
|
||||
}
|
||||
// Create new region
|
||||
regions[region_count] = calloc(rows, sizeof(regions[0][0]));
|
||||
for (int k = 0; k < rows; k++) {
|
||||
regions[region_count][k] = calloc(columns, sizeof(regions[0][0][0]));
|
||||
}
|
||||
|
||||
// Fill new region
|
||||
fill(map, i, j, regions[region_count], rows, columns);
|
||||
|
||||
int area = 0;
|
||||
// Copy to visited
|
||||
for (int k = 0; k < rows; k++) {
|
||||
for (int l = 0; l < columns; l++) {
|
||||
visited[k][l] |= regions[region_count][k][l];
|
||||
area += regions[region_count][k][l];
|
||||
}
|
||||
}
|
||||
// Calculate perimeter
|
||||
int perimeter = 0;
|
||||
for (int k = 0; k < rows; k++) {
|
||||
for (int l = 0; l < columns; l++) {
|
||||
if (!regions[region_count][k][l]) {
|
||||
continue;
|
||||
}
|
||||
int row;
|
||||
int column;
|
||||
// Up
|
||||
row = k - 1;
|
||||
column = l;
|
||||
if (row < 0 || !regions[region_count][row][column]) {
|
||||
perimeter += 1;
|
||||
}
|
||||
// Down
|
||||
row = k + 1;
|
||||
column = l;
|
||||
if (row >= rows || !regions[region_count][row][column]) {
|
||||
perimeter += 1;
|
||||
}
|
||||
// Left
|
||||
row = k;
|
||||
column = l + 1;
|
||||
if (column >= columns || !regions[region_count][row][column]) {
|
||||
perimeter += 1;
|
||||
}
|
||||
// Right
|
||||
row = k;
|
||||
column = l - 1;
|
||||
if (column < 0 || !regions[region_count][row][column]) {
|
||||
perimeter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cost += area * perimeter;
|
||||
|
||||
// Calculate perimeter task two
|
||||
perimeter = 0;
|
||||
for (int k = 0; k < rows; k++) {
|
||||
for (int l = 0; l < columns; l++) {
|
||||
if (!regions[region_count][k][l]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (k == 0) {
|
||||
if (l == 0 || !regions[region_count][k][l-1]) {
|
||||
perimeter++;
|
||||
}
|
||||
} else if (!regions[region_count][k-1][l]) {
|
||||
if (l == 0 || !regions[region_count][k][l-1] || (regions[region_count][k][l-1] && regions[region_count][k][l-1] == regions[region_count][k-1][l-1])) {
|
||||
perimeter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (k == rows - 1) {
|
||||
if (l == 0 || !regions[region_count][k][l-1]) {
|
||||
perimeter++;
|
||||
}
|
||||
} else if (!regions[region_count][k+1][l]) {
|
||||
if (l == 0 || !regions[region_count][k][l-1] || (regions[region_count][k][l-1] && regions[region_count][k][l-1] == regions[region_count][k+1][l-1])) {
|
||||
perimeter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (l == 0) {
|
||||
if (k == 0 || !regions[region_count][k-1][l]) {
|
||||
perimeter++;
|
||||
}
|
||||
} else if (!regions[region_count][k][l-1]) {
|
||||
if (k == 0 || !regions[region_count][k-1][l] || (regions[region_count][k-1][l] && regions[region_count][k-1][l] == regions[region_count][k-1][l-1])) {
|
||||
perimeter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (l == columns - 1) {
|
||||
if (k == 0 || !regions[region_count][k-1][l]) {
|
||||
perimeter++;
|
||||
}
|
||||
} else if (!regions[region_count][k][l+1]) {
|
||||
if (k == 0 || !regions[region_count][k-1][l] || (regions[region_count][k-1][l] && regions[region_count][k-1][l] == regions[region_count][k-1][l+1])) {
|
||||
perimeter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cost2 += area * perimeter;
|
||||
|
||||
region_count++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%i\n", cost);
|
||||
printf("%i\n", cost2);
|
||||
|
||||
for (i = 0; i < region_count; i++) {
|
||||
for (int j = 0; j < rows; j++) {
|
||||
free(regions[i][j]);
|
||||
}
|
||||
free(regions[i]);
|
||||
}
|
||||
free(regions);
|
||||
for (i = 0; i < rows; i++) {
|
||||
free(visited[i]);
|
||||
}
|
||||
free(visited);
|
||||
for (i = 0; i < rows + 1; i++) {
|
||||
free(map[i]);
|
||||
}
|
||||
free(map);
|
||||
}
|
||||
|
||||
void fill(char **map, int x, int y, int **region, int rows, int columns) {
|
||||
region[x][y] = 1;
|
||||
|
||||
int row;
|
||||
int column;
|
||||
// Up
|
||||
row = x - 1;
|
||||
column = y;
|
||||
if (row >= 0 && map[row][column] == map[x][y] && !region[row][column]) {
|
||||
fill(map, row, column, region, rows, columns);
|
||||
}
|
||||
// Down
|
||||
row = x + 1;
|
||||
column = y;
|
||||
if (row < rows && map[row][column] == map[x][y] && !region[row][column]) {
|
||||
fill(map, row, column, region, rows, columns);
|
||||
}
|
||||
// Left
|
||||
row = x;
|
||||
column = y + 1;
|
||||
if (column < columns && map[row][column] == map[x][y] && !region[row][column]) {
|
||||
fill(map, row, column, region, rows, columns);
|
||||
}
|
||||
// Right
|
||||
row = x;
|
||||
column = y - 1;
|
||||
if (column >= 0 && map[row][column] == map[x][y] && !region[row][column]) {
|
||||
fill(map, row, column, region, rows, columns);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user