diff options
author | Thomas Voss <thomasvoss@live.com> | 2021-10-29 23:02:39 +0200 |
---|---|---|
committer | Thomas Voss <thomasvoss@live.com> | 2021-10-29 23:02:39 +0200 |
commit | e7c9108b95e39d7ea5a29ae06d619c4727f11027 (patch) | |
tree | 237261eef3afd0720be77dbcbb9599fa66a24b67 /2020/11/puzzles.c |
Initial commit
Diffstat (limited to '2020/11/puzzles.c')
-rw-r--r-- | 2020/11/puzzles.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/2020/11/puzzles.c b/2020/11/puzzles.c new file mode 100644 index 0000000..7c579b9 --- /dev/null +++ b/2020/11/puzzles.c @@ -0,0 +1,158 @@ +#include <err.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +#define ROWCNT 98 +#define ROWLEN 98 + +#ifdef PART2 + #define IS_SEAT(a, b) \ + if (rows[a][b] == '.') \ + continue + #define IS_OCC(a, b) \ + if (rows[a][b] == '#') \ + adjecent++ +#endif + +bool changed; +char rows[ROWCNT][ROWLEN + 1]; +char temp[ROWCNT][ROWLEN + 1]; + +/* Check and update a seat at the given index */ +static void +check_seat(int const i, int const j) +{ + if (rows[i][j] == '.') + return; + + int adjecent = 0; + +#ifdef PART2 + /* Up */ + for (int h = i - 1; h >= 0; h--) { + IS_SEAT(h, j); + IS_OCC(h, j); + break; + } + /* Down */ + for (int h = i + 1; h < ROWCNT; h++) { + IS_SEAT(h, j); + IS_OCC(h, j); + break; + } + /* Left */ + for (int h = j - 1; h >= 0; h--) { + IS_SEAT(i, h); + IS_OCC(i, h); + break; + } + /* Right */ + for (int h = j + 1; h < ROWLEN; h++) { + IS_SEAT(i, h); + IS_OCC(i, h); + break; + } + /* Up-Left */ + for (int h = i - 1, k = j - 1; h >= 0 && k >= 0; h--, k--) { + IS_SEAT(h, k); + IS_OCC(h, k); + break; + } + /* Up-Right */ + for (int h = i - 1, k = j + 1; h >= 0 && k < ROWLEN; h--, k++) { + IS_SEAT(h, k); + IS_OCC(h, k); + break; + } + /* Down-Left */ + for (int h = i + 1, k = j - 1; h < ROWCNT && k >= 0; h++, k--) { + IS_SEAT(h, k); + IS_OCC(h, k); + break; + } + /* Down-Right */ + for (int h = i + 1, k = j + 1; h < ROWCNT && k < ROWLEN; h++, k++) { + IS_SEAT(h, k); + IS_OCC(h, k); + break; + } +#else + for (int h = i - 1; h <= i + 1; h++) { + if (h < 0 || h > ROWCNT - 1) + continue; + for (int k = j - 1; k <= j + 1; k++) { + if (k < 0 || k > ROWCNT - 1 || (h == i && k == j)) + continue; + if (rows[h][k] == '#') + adjecent++; + } + } +#endif + /* Edit seats as needed */ + if (rows[i][j] == 'L' && adjecent == 0) { + temp[i][j] = '#'; + changed = true; +#ifdef PART2 + } else if (rows[i][j] == '#' && adjecent >= 5) { +#else + } else if (rows[i][j] == '#' && adjecent >= 4) { +#endif + temp[i][j] = 'L'; + changed = true; + } else + temp[i][j] = rows[i][j]; +} + +int +main(void) +{ + /* Initialize the temp array to be all floor */ + int i, j; + for (i = 0; i < ROWCNT; i++) { + for (j = 0; j < ROWLEN; j++) + temp[i][j] = '.'; + } + + FILE *fp; + if (!(fp = fopen("input", "r"))) + err(EXIT_FAILURE, "fopen"); + + /* Read in seats */ + i = j = 0; + char c; + while ((c = fgetc(fp)) != EOF) { + if (c == '\n') { + i = 0; + j++; + } else + rows[j][i++] = c; + } + fclose(fp); + + /* Update the seats until they don't change anymore */ + do { + changed = false; + for (i = 0; i < ROWCNT; i++) { + for (j = 0; j < ROWLEN; j++) + check_seat(i, j); + } + + for (i = 0; i < ROWCNT; i++) { + for (j = 0; j < ROWLEN; j++) + rows[i][j] = temp[i][j]; + } + } while (changed); + + /* Calculate filled seats */ + int count = 0; + for (i = 0; i < ROWCNT; i++) { + for (j = 0; j < ROWLEN; j++) { + if (rows[i][j] == '#') + count++; + } + } + + printf("%d\n", count); + return EXIT_SUCCESS; +} |