|
@@ -0,0 +1,347 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
+#define LINE_MAX 256
|
|
|
+
|
|
|
+int arraySize = 0;
|
|
|
+
|
|
|
+char **readSeats(FILE *fp) {
|
|
|
+ char **allSeats = NULL;
|
|
|
+ int index = 0;
|
|
|
+ while (1) {
|
|
|
+ char *p = malloc(LINE_MAX);
|
|
|
+ if (!p) return NULL;
|
|
|
+
|
|
|
+ if (1 > fscanf(fp, "%s\n", p))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ arraySize++;
|
|
|
+ char **newSeats = realloc(allSeats, sizeof(char*)*arraySize);
|
|
|
+ if (!newSeats) return NULL;
|
|
|
+
|
|
|
+ allSeats = newSeats;
|
|
|
+ allSeats[index] = p;
|
|
|
+ index++;
|
|
|
+
|
|
|
+ if (feof(fp)) break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return allSeats;
|
|
|
+}
|
|
|
+
|
|
|
+size_t lineLength = 0;
|
|
|
+
|
|
|
+int occupied(char **array, int x, int y) {
|
|
|
+ int columnMax = lineLength-1;
|
|
|
+ int rowMax = arraySize-1;
|
|
|
+ if ((x < 0 || x > rowMax) || (y < 0 || y > columnMax)) return 0;
|
|
|
+
|
|
|
+ int upRow = x - 1;
|
|
|
+ if (upRow < 0) upRow = 0;
|
|
|
+ int downRow = x + 1;
|
|
|
+ if (downRow > rowMax) downRow = rowMax;
|
|
|
+
|
|
|
+ int left = y - 1;
|
|
|
+ if (left < 0) left = 0;
|
|
|
+ int right = y + 1;
|
|
|
+ if (right > columnMax) right = columnMax;
|
|
|
+
|
|
|
+ int occupiedCount = 0;
|
|
|
+ for (int i = upRow; i <= downRow; i++) {
|
|
|
+ for (int j = left; j <= right; j++) {
|
|
|
+ if (i == x && j == y) continue;
|
|
|
+ if (array[i][j] == '#') occupiedCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return occupiedCount;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void freeAllSeats(char **array) {
|
|
|
+ for (int i = 0; i < arraySize; i++)
|
|
|
+ free(array[i]);
|
|
|
+
|
|
|
+ free(array);
|
|
|
+}
|
|
|
+
|
|
|
+int previouslyChanged = 0;
|
|
|
+int currentlyChanged = 0;
|
|
|
+
|
|
|
+char **checkBoard(char **currentBoard, char **newBoard) {
|
|
|
+ currentlyChanged = 0;
|
|
|
+ for (int i = 0; i < arraySize; i++) {
|
|
|
+ char temp[lineLength+1];
|
|
|
+ temp[lineLength] = 0;
|
|
|
+ for (size_t j = 0; j < lineLength; j++) {
|
|
|
+ char *current = ¤tBoard[i][j];
|
|
|
+ char new = *current;
|
|
|
+
|
|
|
+ switch (*current) {
|
|
|
+ case 'L':
|
|
|
+ if (!occupied(currentBoard, i, j)) {
|
|
|
+ new = '#';
|
|
|
+ currentlyChanged = 1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '#':
|
|
|
+ if (occupied(currentBoard, i, j) >= 4) {
|
|
|
+ new = 'L';
|
|
|
+ currentlyChanged = 1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ temp[j] = new;
|
|
|
+ }
|
|
|
+ sprintf(newBoard[i], "%s", temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ freeAllSeats(currentBoard);
|
|
|
+
|
|
|
+ return newBoard;
|
|
|
+}
|
|
|
+
|
|
|
+int countOccupied(char **currentBoard) {
|
|
|
+ int occupiedCount = 0;
|
|
|
+ for (int i = 0; i < arraySize; i++) {
|
|
|
+ for (size_t j = 0; j < lineLength; j++) {
|
|
|
+ char *current = ¤tBoard[i][j];
|
|
|
+ if (*current == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return occupiedCount;
|
|
|
+}
|
|
|
+
|
|
|
+char **allocateNewBoard(int rows, int columns) {
|
|
|
+ char **newBoard = malloc(sizeof(char*)*rows);
|
|
|
+ if (!newBoard) return NULL;
|
|
|
+
|
|
|
+ for (int i = 0; i < rows; i++) {
|
|
|
+ newBoard[i] = malloc(columns);
|
|
|
+ if (!newBoard[i]) return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return newBoard;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int doRounds(char **array) {
|
|
|
+ char **currentBoard = array;
|
|
|
+ int runs = 0;
|
|
|
+ char **newBoard = NULL;
|
|
|
+ while (1) {
|
|
|
+ newBoard = allocateNewBoard(arraySize, lineLength+1);
|
|
|
+ if (!newBoard) return -1;
|
|
|
+
|
|
|
+ if (runs > 1 && ((currentlyChanged == 0) && (previouslyChanged == 0))) break;
|
|
|
+ previouslyChanged = currentlyChanged;
|
|
|
+
|
|
|
+ currentBoard = checkBoard(currentBoard, newBoard);
|
|
|
+ runs++;
|
|
|
+ }
|
|
|
+
|
|
|
+ int occupied = countOccupied(currentBoard);
|
|
|
+ freeAllSeats(currentBoard);
|
|
|
+ freeAllSeats(newBoard);
|
|
|
+ return occupied;
|
|
|
+}
|
|
|
+
|
|
|
+int occupied2(char **array, int x, int y) {
|
|
|
+ int columnMax = lineLength;
|
|
|
+ int rowMax = arraySize;
|
|
|
+
|
|
|
+ int occupiedCount = 0;
|
|
|
+ for (int i = x+1; i < rowMax; i++) {
|
|
|
+ if (array[i][y] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[i][y] != '.') break;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = x-1; i >= 0; i--) {
|
|
|
+ if (array[i][y] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[i][y] != '.') break;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = y+1; i < columnMax; i++) {
|
|
|
+ if (array[x][i] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[x][i] != '.') break;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = y-1; i >= 0; i--) {
|
|
|
+ if (array[x][i] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[x][i] != '.') break;
|
|
|
+ }
|
|
|
+
|
|
|
+ int currentX = x - 1;
|
|
|
+ int currentY = y - 1;
|
|
|
+ while ((currentX >= 0) && (currentY >= 0)) {
|
|
|
+ if (array[currentX][currentY] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[currentX][currentY] != '.') break;
|
|
|
+
|
|
|
+ currentX--;
|
|
|
+ currentY--;
|
|
|
+ }
|
|
|
+
|
|
|
+ currentX = x + 1;
|
|
|
+ currentY = y + 1;
|
|
|
+ while ((currentX < rowMax) && (currentY < columnMax)) {
|
|
|
+ if (array[currentX][currentY] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[currentX][currentY] != '.') break;
|
|
|
+ currentX++;
|
|
|
+ currentY++;
|
|
|
+ }
|
|
|
+
|
|
|
+ currentX = x - 1;
|
|
|
+ currentY = y + 1;
|
|
|
+ while ((currentX >= 0) && (currentY < columnMax)) {
|
|
|
+ if (array[currentX][currentY] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[currentX][currentY] != '.') break;
|
|
|
+ currentX--;
|
|
|
+ currentY++;
|
|
|
+ }
|
|
|
+
|
|
|
+ currentX = x + 1;
|
|
|
+ currentY = y - 1;
|
|
|
+ while ((currentX < rowMax) && (currentY >= 0)) {
|
|
|
+ if (array[currentX][currentY] == '#') {
|
|
|
+ occupiedCount++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (array[currentX][currentY] != '.') break;
|
|
|
+ currentX++;
|
|
|
+ currentY--;
|
|
|
+ }
|
|
|
+
|
|
|
+ return occupiedCount;
|
|
|
+}
|
|
|
+
|
|
|
+char **checkBoard2(char **currentBoard, char **newBoard) {
|
|
|
+ currentlyChanged = 0;
|
|
|
+ for (int i = 0; i < arraySize; i++) {
|
|
|
+ char temp[lineLength+1];
|
|
|
+ temp[lineLength] = 0;
|
|
|
+ for (size_t j = 0; j < lineLength; j++) {
|
|
|
+ char *current = ¤tBoard[i][j];
|
|
|
+ char new = *current;
|
|
|
+
|
|
|
+ switch (*current) {
|
|
|
+ case 'L':
|
|
|
+ if (!occupied2(currentBoard, i, j)) {
|
|
|
+ new = '#';
|
|
|
+ currentlyChanged = 1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case '#':
|
|
|
+ if (occupied2(currentBoard, i, j) >= 5) {
|
|
|
+ new = 'L';
|
|
|
+ currentlyChanged = 1;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ temp[j] = new;
|
|
|
+ }
|
|
|
+ sprintf(newBoard[i], "%s", temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ freeAllSeats(currentBoard);
|
|
|
+
|
|
|
+ return newBoard;
|
|
|
+}
|
|
|
+
|
|
|
+int doRounds2(char **array) {
|
|
|
+ char **currentBoard = array;
|
|
|
+ int runs = 0;
|
|
|
+ char **newBoard = NULL;
|
|
|
+ while (1) {
|
|
|
+ newBoard = allocateNewBoard(arraySize, lineLength+1);
|
|
|
+ if (!newBoard) return -1;
|
|
|
+
|
|
|
+ if (runs > 1 && ((currentlyChanged == 0) && (previouslyChanged == 0))) break;
|
|
|
+ previouslyChanged = currentlyChanged;
|
|
|
+
|
|
|
+ currentBoard = checkBoard2(currentBoard, newBoard);
|
|
|
+ runs++;
|
|
|
+ }
|
|
|
+
|
|
|
+ int occupied = countOccupied(currentBoard);
|
|
|
+ freeAllSeats(currentBoard);
|
|
|
+ freeAllSeats(newBoard);
|
|
|
+ return occupied;
|
|
|
+}
|
|
|
+
|
|
|
+char **copyBoard(char** array, int rows, int columns) {
|
|
|
+ char **newBoard = malloc(sizeof(char*)*rows);
|
|
|
+ if (!newBoard) return NULL;
|
|
|
+
|
|
|
+ for (int i = 0; i < rows; i++) {
|
|
|
+ newBoard[i] = malloc(columns);
|
|
|
+ if (!newBoard[i]) return NULL;
|
|
|
+ sprintf(newBoard[i], "%s", array[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return newBoard;
|
|
|
+}
|
|
|
+
|
|
|
+int main(int argc, char **argv)
|
|
|
+{
|
|
|
+ if (argc < 2) {
|
|
|
+ puts("You need to specify path to file!");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ FILE *fp = fopen(argv[1], "r");
|
|
|
+ if (!fp) {
|
|
|
+ puts("Can't open file!");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ char **currentBoard = readSeats(fp);
|
|
|
+ if (!currentBoard) {
|
|
|
+ puts("Can't read numbers!");
|
|
|
+ fclose(fp);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ fclose(fp);
|
|
|
+
|
|
|
+ lineLength = strlen(currentBoard[arraySize-1]);
|
|
|
+ char **originalBoard = copyBoard(currentBoard, arraySize, lineLength+1);
|
|
|
+ if (!originalBoard) return -1;
|
|
|
+
|
|
|
+ printf("Part1: %d\n", doRounds(currentBoard));
|
|
|
+ printf("Part2: %d\n", doRounds2(originalBoard));
|
|
|
+}
|