aoc

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

22a.c (1313B)


      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 	for (int x = b[i][0]; x <= b[i][3]; x++)
     25 		for (int y = b[i][1]; y <= b[i][4]; y++)
     26 			if (cube[x][y][z-1])
     27 				return false;
     28 	return true;
     29 }
     30 
     31 void set(int n, int c) {
     32 	for (int i = b[n][0]; i <= b[n][3]; i++)
     33 		for (int j = b[n][1]; j <= b[n][4]; j++)
     34 			for (int k = b[n][2]; k <= b[n][5]; k++)
     35 				cube[i][j][k] = c;
     36 }
     37 
     38 void dobreak(int n) { set(n, 0); }
     39 void unbreak(int n) { set(n, n+1); }
     40 
     41 void drop(int i) {
     42 	dobreak(i);
     43 	b[i][2]--;
     44 	b[i][5]--;
     45 	unbreak(i);
     46 }
     47 
     48 int disintegratable(int i) {
     49 	int ret = 1;
     50 	dobreak(i);
     51 	for (int j = 0; j < n; j++)
     52 		if (j != i && droppable(j))
     53 			ret = 0;
     54 	unbreak(i);
     55 	return ret;
     56 }
     57 
     58 int main() {
     59 	for (n = 0; fgets(line, N, stdin) != NULL; n++) {
     60 		readl(b[n], line);
     61 		unbreak(n);
     62 	}
     63 
     64 	for (int i = 0; i < N; i++)
     65 		for (int j = 0; j < n; j++)
     66 			while (droppable(j))
     67 				drop(j);
     68 
     69 	for (int i = 0; i < n; i++)
     70 		x += disintegratable(i);
     71 
     72 	printf("%d\n", x);
     73 	return 0;
     74 }