diff --git a/2021/day11/aoc-c.c b/2021/day11/aoc-c.c new file mode 100644 index 0000000..9e0adaa --- /dev/null +++ b/2021/day11/aoc-c.c @@ -0,0 +1,176 @@ +/* aoc-c.c: Advent of Code 2021, day 11 parts 1 & 2 + * + * Copyright (C) 2021 Bruno Raoult ("br") + * Licensed under the GNU General Public License v3.0 or later. + * Some rights reserved. See COPYING. + * + * You should have received a copy of the GNU General Public License along with this + * program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "bits.h" + +#define MAX_GRID 10 + +static int grid[MAX_GRID][MAX_GRID]; +static int gsize; /* grid size */ + +static int stack[MAX_GRID * MAX_GRID]; /* flashing stack */ +static int nstack; /* current stack size */ + +#define loop_for_grid(l, c, val) \ + for (l = 1; l <= gsize; ++l) \ + for (c = 1; c <= gsize; ++c) \ + val = grid[l][c]; + +#define VALID(x, y) ((x) >= 0 && (y) >= 0 && (x) < gsize && (y) < gsize) + +inline static int push(int l, int c) +{ + return ((stack[nstack++] = l * gsize + c)); +} + +inline static int pop() +{ + if (!nstack) + return -1; + return stack[--nstack]; +} + +static void print_grid(int (*arr)[MAX_GRID], int step) +{ + log_f(3, "step = %d\n", step); + for (int l = 0; l < gsize; ++l) { + for (int c = 0; c < gsize; ++c) { + log(3, "%2d ", arr[l][c]); + } + log(3, "\n"); + } +} + +inline static int inc_cell(int l, int c) +{ + if (VALID(l, c) && ++grid[l][c] == 10) { + push(l, c); + return 1; + } + return 0; +} + +void flash_grid(int (*arr)[MAX_GRID], int step) +{ + log_f(3, "step = %d\n", step); + for (int l = 1; l <= gsize; ++l) { + for (int c = 1; c <= gsize; ++c) { + log(3, "%2d ", arr[l][c]); + } + log(3, "\n"); + } +} + +/* run 1 step */ +static void step(int nsteps) +{ + int vpop; + int flash = 0; + //int flashed[MAX_GRID][MAX_GRID]; + + //init_grid(flashed); + /* create an empty grid */ + + for (int step = 1; step <= nsteps; ++step) { + /* 1) increase all energy levels */ + for (int l = 0; l < gsize; ++l) { + for (int c = 0; c < gsize; ++c) { + flash += inc_cell(l, c); + } + } + + /* 2) perform BFS until stack is empty */ + while ((vpop = pop()) != -1) { + int pl = vpop / gsize, pc = vpop % gsize; + for (int l = -1; l <= 1; ++l) + for (int c = -1; c <= 1; ++c) + flash += inc_cell(pl + l, pc + c); + } + //print_grid(grid, 1); + + /* 3) cleanup flashed cells */ + for (int l = 0; l < gsize; ++l) { + for (int c = 0; c < gsize; ++c) { + if (grid[l][c] > 9) + grid[l][c] = 0; + } + } + print_grid(grid, step); + printf("step = %d flashed = %d\n", step, flash); + } +} + +static s64 doit(int part) +{ + int l = 0, c; + ssize_t len; + size_t alloc = 0; + char *buf = NULL, *p; + + len = getline(&buf, &alloc, stdin); + gsize = len - 1; + for (l = 0; l < gsize; ++l) { + buf[gsize] = 0; + log_f(10, "len = %d str = [%s]\n", grid, buf); + for (c = 0, p = buf; c < gsize; c++, p++) + grid[l][c] = *p - '0'; + getline(&buf, &alloc, stdin); + } + free(buf); + print_grid(grid, 0); + step(100); + print_grid(grid, 1); + return part; +} + +static int usage(char *prg) +{ + fprintf(stderr, "Usage: %s [-d debug_level] [-p part]\n", prg); + return 1; +} + +int main(int ac, char **av) +{ + int opt; + u32 exercise = 1, debug = 1; + s64 res; + + while ((opt = getopt(ac, av, "d:p:")) != -1) { + switch (opt) { + case 'd': + debug = atoi(optarg); + break; + case 'p': /* 1 or 2 */ + exercise = atoi(optarg); + if (exercise < 1 || exercise > 2) + return usage(*av); + break; + default: + return usage(*av); + } + } + debug_level_set(debug); + if (optind < ac) + return usage(*av); + + //init_borders(); + res = doit(exercise); + printf("%s : res=%lu\n", *av, res); + exit (0); +}