diff --git a/11/11-1and2.c b/11/11-1and2.c new file mode 100644 index 0000000..fbe6cd5 --- /dev/null +++ b/11/11-1and2.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include "../check_alloc.h" + +#define PART_2 + +typedef struct +{ + u_int8_t energy; + bool lock; // LOCK STATE WHEN GLOWING +} OCTOPUS; + +// + +#define SPACE_SIZE 10 + +typedef OCTOPUS **SPACE; + +#define VALID_VECTOR(i, j) ((i) >= 0 && (j) >= 0 && (i) < (SPACE_SIZE) && (j) < (SPACE_SIZE)) +#define ITER_SPACE(i, j) \ + for (int i = 0; (i) < (SPACE_SIZE); (i)++) \ + for (int j = 0; (j) < (SPACE_SIZE); (j)++) +#define ITER_ADJACENT(i, j, x, y) \ + for (int x = ((i)-1); (x) <= ((i) + 1); (x)++) \ + for (int y = ((j)-1); (y) <= ((j) + 1); (y)++) \ + if (((x) != (i) || (y) != (j)) && VALID_VECTOR((x), (y))) + +bool check_sync(SPACE space) +{ + ITER_SPACE(i, j) + { + if (space[i][j].energy != 0) + return false; + } + return true; +} + +size_t flash(SPACE space) +{ + size_t n_flashes = 0; + do // This can be further optimized with a update cache. + { + n_flashes = 0; + ITER_SPACE(i, j) + { + if (space[i][j].energy > 9) + { + ITER_ADJACENT(i, j, x, y) + { + OCTOPUS *p_cell = &space[x][y]; + if (p_cell->energy > 9) + { + p_cell->lock = true; + } + else if (!p_cell->lock) + { + p_cell->energy++; + if (p_cell->energy > 9) + n_flashes++; + } + } + space[i][j].energy = 0; + space[i][j].lock = true; + } + } + } while (n_flashes > 0); + + ITER_SPACE(i, j) + { + if (space[i][j].lock) + { + n_flashes++; + space[i][j].lock = false; + } + } + return n_flashes; +} + +void increment_energy(SPACE space) +{ + ITER_SPACE(i, j) + { + space[i][j].energy++; + } +} + +void print_space(SPACE space) +{ + for (size_t i = 0; i < SPACE_SIZE; i++) + { + for (size_t j = 0; j < SPACE_SIZE; j++) + { + if (space[i][j].energy) + printf("%d ", space[i][j].energy); + else + printf("* "); + } + putchar('\n'); + } + putchar('\n'); +} + +SPACE new_space(void) +{ + SPACE space = calloc(SPACE_SIZE, sizeof(OCTOPUS *)); + CHECK_ALLOC(space); + for (size_t i = 0; i < SPACE_SIZE; i++) + { + space[i] = calloc(SPACE_SIZE, sizeof(OCTOPUS)); + CHECK_ALLOC(space[i]); + } + return space; +} + +// + +SPACE read_file(char *file) +{ + SPACE space = new_space(); + FILE *p_file = fopen(file, "r"); + CHECK_ALLOC(p_file); + char buf[BUFSIZ]; + size_t j = 0; + while (fgets(buf, sizeof buf, p_file) != NULL) + { + for (size_t i = 0; i < SPACE_SIZE; i++) + { + space[j][i].energy = buf[i] - '0'; + } + j++; + } + return space; +} + +int main(void) +{ + SPACE space = read_file("input"); + size_t total_flashes = 0; +#ifdef PART_2 + size_t step = 0; + for (; !check_sync(space); step++) +#else + for (size_t i = 0; i < 100; i++) +#endif + { + increment_energy(space); + total_flashes += flash(space); + // print_space(space); + } +#ifdef PART_2 + printf("SYNC STEP %zu\n", step); +#else + printf("FLASHES %zu\n", total_flashes); +#endif +} \ No newline at end of file