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