day11.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define LINE_MAX 256
  5. int arraySize = 0;
  6. char **readSeats(FILE *fp) {
  7. char **allSeats = NULL;
  8. int index = 0;
  9. while (1) {
  10. char *p = malloc(LINE_MAX);
  11. if (!p) return NULL;
  12. if (1 > fscanf(fp, "%s\n", p))
  13. return NULL;
  14. arraySize++;
  15. char **newSeats = realloc(allSeats, sizeof(char*)*arraySize);
  16. if (!newSeats) return NULL;
  17. allSeats = newSeats;
  18. allSeats[index] = p;
  19. index++;
  20. if (feof(fp)) break;
  21. }
  22. return allSeats;
  23. }
  24. size_t lineLength = 0;
  25. int occupied(char **array, int x, int y) {
  26. int columnMax = lineLength-1;
  27. int rowMax = arraySize-1;
  28. if ((x < 0 || x > rowMax) || (y < 0 || y > columnMax)) return 0;
  29. int upRow = x - 1;
  30. if (upRow < 0) upRow = 0;
  31. int downRow = x + 1;
  32. if (downRow > rowMax) downRow = rowMax;
  33. int left = y - 1;
  34. if (left < 0) left = 0;
  35. int right = y + 1;
  36. if (right > columnMax) right = columnMax;
  37. int occupiedCount = 0;
  38. for (int i = upRow; i <= downRow; i++) {
  39. for (int j = left; j <= right; j++) {
  40. if (i == x && j == y) continue;
  41. if (array[i][j] == '#') occupiedCount++;
  42. }
  43. }
  44. return occupiedCount;
  45. }
  46. void freeAllSeats(char **array) {
  47. for (int i = 0; i < arraySize; i++)
  48. free(array[i]);
  49. free(array);
  50. }
  51. int previouslyChanged = 0;
  52. int currentlyChanged = 0;
  53. char **checkBoard(char **currentBoard, char **newBoard) {
  54. currentlyChanged = 0;
  55. for (int i = 0; i < arraySize; i++) {
  56. char temp[lineLength+1];
  57. temp[lineLength] = 0;
  58. for (size_t j = 0; j < lineLength; j++) {
  59. char *current = &currentBoard[i][j];
  60. char new = *current;
  61. switch (*current) {
  62. case 'L':
  63. if (!occupied(currentBoard, i, j)) {
  64. new = '#';
  65. currentlyChanged = 1;
  66. }
  67. break;
  68. case '#':
  69. if (occupied(currentBoard, i, j) >= 4) {
  70. new = 'L';
  71. currentlyChanged = 1;
  72. }
  73. break;
  74. }
  75. temp[j] = new;
  76. }
  77. sprintf(newBoard[i], "%s", temp);
  78. }
  79. freeAllSeats(currentBoard);
  80. return newBoard;
  81. }
  82. int countOccupied(char **currentBoard) {
  83. int occupiedCount = 0;
  84. for (int i = 0; i < arraySize; i++) {
  85. for (size_t j = 0; j < lineLength; j++) {
  86. char *current = &currentBoard[i][j];
  87. if (*current == '#') {
  88. occupiedCount++;
  89. }
  90. }
  91. }
  92. return occupiedCount;
  93. }
  94. char **allocateNewBoard(int rows, int columns) {
  95. char **newBoard = malloc(sizeof(char*)*rows);
  96. if (!newBoard) return NULL;
  97. for (int i = 0; i < rows; i++) {
  98. newBoard[i] = malloc(columns);
  99. if (!newBoard[i]) return NULL;
  100. }
  101. return newBoard;
  102. }
  103. int doRounds(char **array) {
  104. char **currentBoard = array;
  105. int runs = 0;
  106. char **newBoard = NULL;
  107. while (1) {
  108. newBoard = allocateNewBoard(arraySize, lineLength+1);
  109. if (!newBoard) return -1;
  110. if (runs > 1 && ((currentlyChanged == 0) && (previouslyChanged == 0))) break;
  111. previouslyChanged = currentlyChanged;
  112. currentBoard = checkBoard(currentBoard, newBoard);
  113. runs++;
  114. }
  115. int occupied = countOccupied(currentBoard);
  116. freeAllSeats(currentBoard);
  117. freeAllSeats(newBoard);
  118. return occupied;
  119. }
  120. int occupied2(char **array, int x, int y) {
  121. int columnMax = lineLength;
  122. int rowMax = arraySize;
  123. int occupiedCount = 0;
  124. for (int i = x+1; i < rowMax; i++) {
  125. if (array[i][y] == '#') {
  126. occupiedCount++;
  127. break;
  128. }
  129. if (array[i][y] != '.') break;
  130. }
  131. for (int i = x-1; i >= 0; i--) {
  132. if (array[i][y] == '#') {
  133. occupiedCount++;
  134. break;
  135. }
  136. if (array[i][y] != '.') break;
  137. }
  138. for (int i = y+1; i < columnMax; i++) {
  139. if (array[x][i] == '#') {
  140. occupiedCount++;
  141. break;
  142. }
  143. if (array[x][i] != '.') break;
  144. }
  145. for (int i = y-1; i >= 0; i--) {
  146. if (array[x][i] == '#') {
  147. occupiedCount++;
  148. break;
  149. }
  150. if (array[x][i] != '.') break;
  151. }
  152. int currentX = x - 1;
  153. int currentY = y - 1;
  154. while ((currentX >= 0) && (currentY >= 0)) {
  155. if (array[currentX][currentY] == '#') {
  156. occupiedCount++;
  157. break;
  158. }
  159. if (array[currentX][currentY] != '.') break;
  160. currentX--;
  161. currentY--;
  162. }
  163. currentX = x + 1;
  164. currentY = y + 1;
  165. while ((currentX < rowMax) && (currentY < columnMax)) {
  166. if (array[currentX][currentY] == '#') {
  167. occupiedCount++;
  168. break;
  169. }
  170. if (array[currentX][currentY] != '.') break;
  171. currentX++;
  172. currentY++;
  173. }
  174. currentX = x - 1;
  175. currentY = y + 1;
  176. while ((currentX >= 0) && (currentY < columnMax)) {
  177. if (array[currentX][currentY] == '#') {
  178. occupiedCount++;
  179. break;
  180. }
  181. if (array[currentX][currentY] != '.') break;
  182. currentX--;
  183. currentY++;
  184. }
  185. currentX = x + 1;
  186. currentY = y - 1;
  187. while ((currentX < rowMax) && (currentY >= 0)) {
  188. if (array[currentX][currentY] == '#') {
  189. occupiedCount++;
  190. break;
  191. }
  192. if (array[currentX][currentY] != '.') break;
  193. currentX++;
  194. currentY--;
  195. }
  196. return occupiedCount;
  197. }
  198. char **checkBoard2(char **currentBoard, char **newBoard) {
  199. currentlyChanged = 0;
  200. for (int i = 0; i < arraySize; i++) {
  201. char temp[lineLength+1];
  202. temp[lineLength] = 0;
  203. for (size_t j = 0; j < lineLength; j++) {
  204. char *current = &currentBoard[i][j];
  205. char new = *current;
  206. switch (*current) {
  207. case 'L':
  208. if (!occupied2(currentBoard, i, j)) {
  209. new = '#';
  210. currentlyChanged = 1;
  211. }
  212. break;
  213. case '#':
  214. if (occupied2(currentBoard, i, j) >= 5) {
  215. new = 'L';
  216. currentlyChanged = 1;
  217. }
  218. break;
  219. }
  220. temp[j] = new;
  221. }
  222. sprintf(newBoard[i], "%s", temp);
  223. }
  224. freeAllSeats(currentBoard);
  225. return newBoard;
  226. }
  227. int doRounds2(char **array) {
  228. char **currentBoard = array;
  229. int runs = 0;
  230. char **newBoard = NULL;
  231. while (1) {
  232. newBoard = allocateNewBoard(arraySize, lineLength+1);
  233. if (!newBoard) return -1;
  234. if (runs > 1 && ((currentlyChanged == 0) && (previouslyChanged == 0))) break;
  235. previouslyChanged = currentlyChanged;
  236. currentBoard = checkBoard2(currentBoard, newBoard);
  237. runs++;
  238. }
  239. int occupied = countOccupied(currentBoard);
  240. freeAllSeats(currentBoard);
  241. freeAllSeats(newBoard);
  242. return occupied;
  243. }
  244. char **copyBoard(char** array, int rows, int columns) {
  245. char **newBoard = malloc(sizeof(char*)*rows);
  246. if (!newBoard) return NULL;
  247. for (int i = 0; i < rows; i++) {
  248. newBoard[i] = malloc(columns);
  249. if (!newBoard[i]) return NULL;
  250. sprintf(newBoard[i], "%s", array[i]);
  251. }
  252. return newBoard;
  253. }
  254. int main(int argc, char **argv)
  255. {
  256. if (argc < 2) {
  257. puts("You need to specify path to file!");
  258. return -1;
  259. }
  260. FILE *fp = fopen(argv[1], "r");
  261. if (!fp) {
  262. puts("Can't open file!");
  263. return -1;
  264. }
  265. char **currentBoard = readSeats(fp);
  266. if (!currentBoard) {
  267. puts("Can't read numbers!");
  268. fclose(fp);
  269. return -1;
  270. }
  271. fclose(fp);
  272. lineLength = strlen(currentBoard[arraySize-1]);
  273. char **originalBoard = copyBoard(currentBoard, arraySize, lineLength+1);
  274. if (!originalBoard) return -1;
  275. printf("Part1: %d\n", doRounds(currentBoard));
  276. printf("Part2: %d\n", doRounds2(originalBoard));
  277. }