aoc

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

14b.c (1952B)


      1 #include <inttypes.h>
      2 #include <stdbool.h>
      3 #include <stdio.h>
      4 #include <string.h>
      5 
      6 #define N 102
      7 #define C 10000
      8 
      9 uint64_t h[C];
     10 char p[C][N][N];
     11 int e, c, n, t, s[N];
     12 
     13 void copy_panel(int c1, int c2) {
     14 	for (int i = 0; i < n; i++)
     15 		memcpy(p[c2][i], p[c1][i], n+2);
     16 }
     17 
     18 void tilt_north(void) {
     19 	for (int i = 0; i < n; i++) s[i] = 0;
     20 	for (int i = 0; i < n; i++) {
     21 		for (int j = 0; j < n; j++) {
     22 			if (p[c][i][j] == '#')
     23 				s[j] = i+1;
     24 			if (p[c][i][j] == 'O') {
     25 				if (s[j] != i) p[c][i][j] = '.';
     26 				p[c][s[j]++][j] = 'O';
     27 			}
     28 		}
     29 	}
     30 }
     31 
     32 void tilt_west(void) {
     33 	for (int i = 0; i < n; i++) s[i] = 0;
     34 	for (int j = 0; j < n; j++) {
     35 		for (int i = 0; i < n; i++) {
     36 			if (p[c][i][j] == '#')
     37 				s[i] = j+1;
     38 			if (p[c][i][j] == 'O') {
     39 				if (s[i] != j) p[c][i][j] = '.';
     40 				p[c][i][s[i]++] = 'O';
     41 			}
     42 		}
     43 	}
     44 }
     45 
     46 void tilt_south(void) {
     47 	for (int i = 0; i < n; i++) s[i] = n-1;
     48 	for (int i = n-1; i >= 0; i--) {
     49 		for (int j = 0; j < n; j++) {
     50 			if (p[c][i][j] == '#')
     51 				s[j] = i-1;
     52 			if (p[c][i][j] == 'O') {
     53 				if (s[j] != i) p[c][i][j] = '.';
     54 				p[c][s[j]--][j] = 'O';
     55 			}
     56 		}
     57 	}
     58 }
     59 
     60 void tilt_east(void) {
     61 	for (int i = 0; i < n; i++) s[i] = n-1;
     62 	for (int j = n-1; j >= 0; j--) {
     63 		for (int i = 0; i < n; i++) {
     64 			if (p[c][i][j] == '#')
     65 				s[i] = j-1;
     66 			if (p[c][i][j] == 'O') {
     67 				if (s[i] != j) p[c][i][j] = '.';
     68 				p[c][i][s[i]--] = 'O';
     69 			}
     70 		}
     71 	}
     72 }
     73 
     74 bool equal(int c1, int c2) {
     75 	for (int i = 0; i < n; i++)
     76 		for (int j = 0; j < n; j++)
     77 			if (p[c1][i][j] != p[c2][i][j])
     78 				return false;
     79 	return true;
     80 }
     81 
     82 int main() {
     83 	for (n = 0; fgets(p[0][n], N, stdin) != NULL; n++) ;
     84 
     85 	for (c = 1; c < C; c++) {
     86 		copy_panel(c-1, c);
     87 		tilt_north();
     88 		tilt_west();
     89 		tilt_south();
     90 		tilt_east();
     91 		for (e = 0; e < c; e++)
     92 			if (equal(e, c))
     93 				goto found;
     94 	}
     95 
     96 found:
     97 	c = (1000000000-e) % (c-e) + e;
     98 
     99 	for (int i = 0; i < n; i++)
    100 		for (int j = 0; j < n; j++)
    101 			t += (p[c][i][j] == 'O') * (n-i);
    102 
    103 	printf("%d\n", t);
    104 	return 0;
    105 }