aoc

My solutions for the Advent of Code
git clone https://git.tronto.net/aoc
Download | Log | Files | Refs | README

22b.c (1503B)


      1 #include <stdbool.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 
      5 #define N 1500
      6 #define M 340
      7 
      8 #define isnum(c) (c == '-' || (c >= '0' && c <= '9'))
      9 
     10 char line[N];
     11 int n, x, b[N][6], cube[M][M][M];
     12 
     13 void readl(int nums[], char *buf) {
     14 	for (int i = 0; i < 6; i++) {
     15 		nums[i] = atoi(buf);
     16 		while (isnum(*buf)) buf++;
     17 		buf++;
     18 	}
     19 }
     20 
     21 bool droppable(int i) {
     22 	int z = b[i][2];
     23 	if (z == 1) return false;
     24 	if (!cube[b[i][0]][b[i][1]][b[i][2]]) return false; /* Already dropping */
     25 	for (int x = b[i][0]; x <= b[i][3]; x++)
     26 		for (int y = b[i][1]; y <= b[i][4]; y++)
     27 			if (cube[x][y][z-1])
     28 				return false;
     29 	return true;
     30 }
     31 
     32 void set(int n, int c) {
     33 	for (int i = b[n][0]; i <= b[n][3]; i++)
     34 		for (int j = b[n][1]; j <= b[n][4]; j++)
     35 			for (int k = b[n][2]; k <= b[n][5]; k++)
     36 				cube[i][j][k] = c;
     37 }
     38 
     39 void dobreak(int n) { set(n, 0); }
     40 void unbreak(int n) { set(n, n+1); }
     41 
     42 void drop(int i) {
     43 	dobreak(i);
     44 	b[i][2]--;
     45 	b[i][5]--;
     46 	unbreak(i);
     47 }
     48 
     49 int howmanyfall(int i) {
     50 	int k = 0, q[N];
     51 	q[k++] = i;
     52 	dobreak(i);
     53 	for (int t = 0; t < k; t++) {
     54 		for (int j = 0; j < n; j++) {
     55 			if (j != q[t] && droppable(j)) {
     56 				q[k++] = j;
     57 				dobreak(j);
     58 			}
     59 		}
     60 	}
     61 	for (int s = 0; s < k; s++)
     62 		unbreak(q[s]);
     63 	return k-1;
     64 }
     65 
     66 int main() {
     67 	for (n = 0; fgets(line, N, stdin) != NULL; n++) {
     68 		readl(b[n], line);
     69 		unbreak(n);
     70 	}
     71 
     72 	for (int i = 0; i < N; i++)
     73 		for (int j = 0; j < n; j++)
     74 			while (droppable(j))
     75 				drop(j);
     76 
     77 	for (int i = 0; i < n; i++)
     78 		x += howmanyfall(i);
     79 
     80 	printf("%d\n", x);
     81 	return 0;
     82 }