Day22 C
This commit is contained in:
BIN
day22/c/day22
Executable file
BIN
day22/c/day22
Executable file
Binary file not shown.
140
day22/c/day22.c
Normal file
140
day22/c/day22.c
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <omp.h>
|
||||
|
||||
#define LINE_MAX_LENGTH 256
|
||||
#define MAX_BRICKS 2048
|
||||
#define NUM_0_CHARCODE 48
|
||||
#define NUM_9_CHARCODE NUM_0_CHARCODE + 9
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define in_range(c,a,b) ((c) <= max(a,b) && (c) >= min(a,b))
|
||||
|
||||
typedef struct corner {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
} corner_t;
|
||||
|
||||
typedef struct brick {
|
||||
corner_t corners[2];
|
||||
int fallen;
|
||||
} brick_t;
|
||||
|
||||
int fall(brick_t bricks[], int bricks_num);
|
||||
int intersect(brick_t brick_a, brick_t brick_b);
|
||||
|
||||
int main() {
|
||||
char *p, *buf, c;
|
||||
|
||||
buf = (char *)malloc(LINE_MAX_LENGTH);
|
||||
memset(buf, 0, LINE_MAX_LENGTH);
|
||||
p = buf;
|
||||
|
||||
brick_t bricks[MAX_BRICKS];
|
||||
int bricks_num = 0;
|
||||
|
||||
while ((c = getchar()) != EOF) {
|
||||
*p++ = c;
|
||||
if (c == '\n') {
|
||||
p = buf;
|
||||
sscanf(p, "%i", &bricks[bricks_num].corners[0].x);
|
||||
while (*p != ',') p++;
|
||||
p++;
|
||||
sscanf(p, "%i", &bricks[bricks_num].corners[0].y);
|
||||
while (*p != ',') p++;
|
||||
p++;
|
||||
sscanf(p, "%i", &bricks[bricks_num].corners[0].z);
|
||||
while (*p != '~') p++;
|
||||
p++;
|
||||
sscanf(p, "%i", &bricks[bricks_num].corners[1].x);
|
||||
while (*p != ',') p++;
|
||||
p++;
|
||||
sscanf(p, "%i", &bricks[bricks_num].corners[1].y);
|
||||
while (*p != ',') p++;
|
||||
p++;
|
||||
sscanf(p, "%i", &bricks[bricks_num].corners[1].z);
|
||||
bricks_num++;
|
||||
memset(buf, 0, LINE_MAX_LENGTH);
|
||||
p = buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (fall(bricks, bricks_num));
|
||||
for (int i = 0; i < bricks_num; i++) {
|
||||
bricks[i].fallen = 0;
|
||||
}
|
||||
|
||||
int part1 = 0;
|
||||
int part2 = 0;
|
||||
#pragma omp parallel for schedule(dynamic)
|
||||
for (int i = 0; i < bricks_num; i++) {
|
||||
brick_t bricks_copy[MAX_BRICKS];
|
||||
memcpy(bricks_copy, bricks, sizeof(bricks));
|
||||
bricks_copy[i].corners[0].z = 0;
|
||||
bricks_copy[i].corners[1].z = 0;
|
||||
int fallen = 0;
|
||||
while (fall(bricks_copy, bricks_num));
|
||||
for (int j = 0; j < bricks_num; j++) {
|
||||
fallen += bricks_copy[j].fallen;
|
||||
}
|
||||
#pragma omp critical
|
||||
{
|
||||
if (fallen == 0) {
|
||||
part1++;
|
||||
}
|
||||
part2 += fallen;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%i\n", part1);
|
||||
printf("%i\n", part2);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
int fall(brick_t bricks[], int bricks_num) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < bricks_num; i++) {
|
||||
int fallen = 0;
|
||||
for (;;) {
|
||||
bricks[i].corners[0].z--;
|
||||
bricks[i].corners[1].z--;
|
||||
if (bricks[i].corners[0].z <= 0 || bricks[i].corners[1].z <= 0) {
|
||||
break;
|
||||
}
|
||||
int collision = 0;
|
||||
for (int j = 0; j < bricks_num; j++) {
|
||||
if (i == j) continue;
|
||||
if (intersect(bricks[i], bricks[j])) {
|
||||
collision = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (collision) {
|
||||
break;
|
||||
}
|
||||
bricks[i].fallen = 1;
|
||||
fallen = 1;
|
||||
}
|
||||
bricks[i].corners[0].z++;
|
||||
bricks[i].corners[1].z++;
|
||||
result += fallen;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int intersect(brick_t brick_a, brick_t brick_b) {
|
||||
if (
|
||||
(in_range(brick_b.corners[0].x, brick_a.corners[0].x, brick_a.corners[1].x) || in_range(brick_b.corners[1].x, brick_a.corners[0].x, brick_a.corners[1].x) || in_range(brick_a.corners[1].x, brick_b.corners[0].x, brick_b.corners[1].x) || in_range(brick_a.corners[0].x, brick_b.corners[0].x, brick_b.corners[1].x)) &&
|
||||
(in_range(brick_b.corners[0].y, brick_a.corners[0].y, brick_a.corners[1].y) || in_range(brick_b.corners[1].y, brick_a.corners[0].y, brick_a.corners[1].y) || in_range(brick_a.corners[1].y, brick_b.corners[0].y, brick_b.corners[1].y) || in_range(brick_a.corners[0].y, brick_b.corners[0].y, brick_b.corners[1].y)) &&
|
||||
(in_range(brick_b.corners[0].z, brick_a.corners[0].z, brick_a.corners[1].z) || in_range(brick_b.corners[1].z, brick_a.corners[0].z, brick_a.corners[1].z) || in_range(brick_a.corners[1].z, brick_b.corners[0].z, brick_b.corners[1].z) || in_range(brick_a.corners[0].z, brick_b.corners[0].z, brick_b.corners[1].z))
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
1439
day22/input.txt
Normal file
1439
day22/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
7
day22/sample.txt
Normal file
7
day22/sample.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
1,0,1~1,2,1
|
||||
0,0,2~2,0,2
|
||||
0,2,3~2,2,3
|
||||
0,0,4~0,2,4
|
||||
2,0,5~2,2,5
|
||||
0,1,6~2,1,6
|
||||
1,1,8~1,1,9
|
||||
Reference in New Issue
Block a user