Day17
This commit is contained in:
1
day17/input.txt
Normal file
1
day17/input.txt
Normal file
File diff suppressed because one or more lines are too long
207
day17/jet.c
Normal file
207
day17/jet.c
Normal file
@@ -0,0 +1,207 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_JET_PATTERN 16*1024
|
||||
#define MAX_STATINARY_ROCK_LAYERS 2*1024*1024
|
||||
#define ROW_WIDTH 7
|
||||
#define ROCK_TYPE_COUNT 5
|
||||
#define ROCK_THRESHOLD 1000000000000ULL
|
||||
|
||||
typedef enum direction {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
} DIRECTION;
|
||||
|
||||
// Each rock will consist a maximum of 5 elements
|
||||
// The elements array contains relative positions to the refElement
|
||||
// By convention the refElement is always the position that is
|
||||
// the bottom left corner of the rock's enclosing rectangle
|
||||
// (Not always part of the rock itself)
|
||||
// The refElement is used for universal spawning of the rocks
|
||||
typedef struct rock {
|
||||
int element_count;
|
||||
int refElement[2];
|
||||
int elements[5][2];
|
||||
} ROCK;
|
||||
|
||||
int main() {
|
||||
char c;
|
||||
|
||||
DIRECTION *jetPattern;
|
||||
jetPattern = (DIRECTION*)malloc(MAX_JET_PATTERN * sizeof(DIRECTION));
|
||||
memset(jetPattern, 0, MAX_JET_PATTERN * sizeof(DIRECTION));
|
||||
unsigned jetPattern_count = 0, currJet = 0;
|
||||
|
||||
while ((c = getchar()) != EOF) {
|
||||
switch (c) {
|
||||
case '<':
|
||||
jetPattern[jetPattern_count] = LEFT;
|
||||
break;
|
||||
case '>':
|
||||
jetPattern[jetPattern_count] = RIGHT;
|
||||
break;
|
||||
default:
|
||||
jetPattern_count--;
|
||||
}
|
||||
jetPattern_count++;
|
||||
}
|
||||
|
||||
// We will store the stationary rocks by row
|
||||
int **rocks = (int**)malloc(MAX_STATINARY_ROCK_LAYERS * sizeof(int*));
|
||||
for (int i = 0; i < MAX_STATINARY_ROCK_LAYERS; i++) {
|
||||
rocks[i] = (int*)malloc(ROW_WIDTH * sizeof(int));
|
||||
memset(rocks[i], 0, ROW_WIDTH * sizeof(int));
|
||||
}
|
||||
|
||||
// Highest rock layer
|
||||
long highestLayer = -1;
|
||||
|
||||
// Define every rock type
|
||||
ROCK rockTypes[ROCK_TYPE_COUNT] = {
|
||||
{ .element_count = 4, .refElement = {0, 0}, .elements = {{0,0}, {0,1}, {0,2}, {0,3}}},
|
||||
{ .element_count = 5, .refElement = {0, 0}, .elements = {{1,0}, {0,1}, {1,1}, {2,1}, {1,2}}},
|
||||
{ .element_count = 5, .refElement = {0, 0}, .elements = {{0,0}, {0,1}, {0,2}, {1,2}, {2,2}}},
|
||||
{ .element_count = 4, .refElement = {0, 0}, .elements = {{0,0}, {1,0}, {2,0}, {3,0}}},
|
||||
{ .element_count = 4, .refElement = {0, 0}, .elements = {{0,0}, {0,1}, {1,0}, {1,1}}}
|
||||
};
|
||||
|
||||
int currentRock = 0;
|
||||
unsigned long long rockBottomCount = 0ULL, cumHighestLayer = 0ULL;
|
||||
|
||||
while (rockBottomCount != ROCK_THRESHOLD) {
|
||||
// Handle overflow
|
||||
if (currentRock == ROCK_TYPE_COUNT) {
|
||||
currentRock = 0;
|
||||
}
|
||||
// Spawn new rock
|
||||
rockTypes[currentRock].refElement[0] = highestLayer + 4;
|
||||
rockTypes[currentRock].refElement[1] = 2;
|
||||
|
||||
// Fall
|
||||
int bottom = 0;
|
||||
do {
|
||||
if (currJet == jetPattern_count) {
|
||||
currJet = 0;
|
||||
}
|
||||
// Jet
|
||||
ROCK currentPosition = rockTypes[currentRock];
|
||||
// Move to jet direction
|
||||
int xdirection = 0;
|
||||
switch (jetPattern[currJet]) {
|
||||
case LEFT:
|
||||
xdirection = -1;
|
||||
break;
|
||||
case RIGHT:
|
||||
xdirection = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
rockTypes[currentRock].refElement[1] += xdirection;
|
||||
|
||||
int collision = 0;
|
||||
if (rockTypes[currentRock].refElement[1] == -1) {
|
||||
collision = 1;
|
||||
}
|
||||
if (!collision) {
|
||||
for (int i = 0; i < rockTypes[currentRock].element_count; i++) {
|
||||
if (rockTypes[currentRock].refElement[1] + rockTypes[currentRock].elements[i][1] == ROW_WIDTH) {
|
||||
collision = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rocks[rockTypes[currentRock].refElement[0]+rockTypes[currentRock].elements[i][0]][rockTypes[currentRock].refElement[1]+rockTypes[currentRock].elements[i][1]]) {
|
||||
collision = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collision) {
|
||||
rockTypes[currentRock] = currentPosition;
|
||||
}
|
||||
|
||||
collision = 0;
|
||||
// Fall
|
||||
if (rockTypes[currentRock].refElement[0] == 0) {
|
||||
collision = 1;
|
||||
}
|
||||
if (!collision) {
|
||||
for (int i = 0; i < rockTypes[currentRock].element_count; i++) {
|
||||
if (rocks[rockTypes[currentRock].refElement[0]+rockTypes[currentRock].elements[i][0]-1][rockTypes[currentRock].refElement[1]+rockTypes[currentRock].elements[i][1]]) {
|
||||
collision = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collision) {
|
||||
bottom = 1;
|
||||
} else {
|
||||
rockTypes[currentRock].refElement[0]--;
|
||||
}
|
||||
|
||||
currJet++;
|
||||
} while(!bottom);
|
||||
|
||||
rockBottomCount++;
|
||||
// Freeze rock
|
||||
for (int i = 0; i < rockTypes[currentRock].element_count; i++) {
|
||||
rocks[rockTypes[currentRock].refElement[0] + rockTypes[currentRock].elements[i][0]][rockTypes[currentRock].refElement[1] + rockTypes[currentRock].elements[i][1]] = 1;
|
||||
if (rockTypes[currentRock].refElement[0] + rockTypes[currentRock].elements[i][0] > highestLayer) {
|
||||
highestLayer = rockTypes[currentRock].refElement[0] + rockTypes[currentRock].elements[i][0];
|
||||
}
|
||||
}
|
||||
|
||||
currentRock++;
|
||||
|
||||
int repeating;
|
||||
|
||||
// The commented out code below calculates the repeat period (2597)
|
||||
// in rock layers. After that you can get the number of rocks in the
|
||||
// period (1705). It also outputs the offset (302) which can also be
|
||||
// converted to number of rocks (205)
|
||||
if (rockBottomCount == 205) {
|
||||
rockBottomCount += ((ROCK_THRESHOLD-205)/1705)*1705;
|
||||
cumHighestLayer += ((ROCK_THRESHOLD-205)/1705)*2597;
|
||||
}
|
||||
|
||||
// We have reached our memory limit, we must find the repeating pattern
|
||||
// if (highestLayer >= (MAX_STATINARY_ROCK_LAYERS) - 10) {
|
||||
// for (long long j = 2; j <= MAX_STATINARY_ROCK_LAYERS/32; j++) {
|
||||
// for (long long i = 0; i < j; i++) {
|
||||
// repeating = 1;
|
||||
// for (long long k = 1; k < (MAX_STATINARY_ROCK_LAYERS-i)/j; k++) {
|
||||
// for (long long l = 0; l < j; l++) {
|
||||
// if (memcmp(rocks[i+l], rocks[i+k*j+l], ROW_WIDTH) != 0) {
|
||||
// repeating = 0;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (repeating) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (repeating) {
|
||||
// printf("Repeat period: %lli Repeat offset: %lli\n", j, i);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (repeating) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (repeating) {
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
printf("%llu\n", cumHighestLayer + (unsigned long long)highestLayer + 1ULL);
|
||||
|
||||
free(jetPattern);
|
||||
for (int i = 0; i < MAX_STATINARY_ROCK_LAYERS; i++) {
|
||||
free(rocks[i]);
|
||||
}
|
||||
free(rocks);
|
||||
}
|
||||
Reference in New Issue
Block a user