Files
adventofcode2023/day11/c/day11.c
2023-12-12 22:54:08 +01:00

132 lines
3.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_MAX_LENGTH 256
#define MAX_GALAXIES 1024
#define abs(a) ((a) > 0 ? (a) : -(a))
#define PART2 1
#define EXPANSION_RATE (PART2 ? 999999 : 1)
typedef enum tile {
EMPTY,
GALAXY
} tile_t;
typedef struct position {
int x;
int y;
} position_t;
void expand_universe(int universe_x, int universe_y, tile_t universe[LINE_MAX_LENGTH][LINE_MAX_LENGTH], position_t galaxies[], int galaxies_num, int expansion_rate);
int main() {
char *p, *buf, c;
buf = (char *)malloc(LINE_MAX_LENGTH);
memset(buf, 0, LINE_MAX_LENGTH);
p = buf;
tile_t universe[LINE_MAX_LENGTH][LINE_MAX_LENGTH];
memset(universe, 0, LINE_MAX_LENGTH*LINE_MAX_LENGTH*sizeof(tile_t));
position_t galaxies[MAX_GALAXIES];
memset(galaxies, 0, MAX_GALAXIES*sizeof(position_t));
int x = 0, y = 0, galaxies_num = 0;
while ((c = getchar()) != EOF) {
*p++ = c;
if (c == '\n') {
x = 0;
p = buf;
while (*p != '\n') {
switch (*p) {
case '.':
universe[x][y] = EMPTY;
break;
case '#':
universe[x][y] = GALAXY;
galaxies[galaxies_num].x = x;
galaxies[galaxies_num].y = y;
galaxies_num++;
break;
}
x++;
p++;
}
y++;
memset(buf, 0, LINE_MAX_LENGTH);
p = buf;
}
}
expand_universe(x, y, universe, galaxies, galaxies_num, EXPANSION_RATE);
unsigned long part1 = 0;
for (int i = 0; i < galaxies_num; i++) {
for (int j = i; j < galaxies_num; j++) {
part1 += abs(galaxies[i].x - galaxies[j].x);
part1 += abs(galaxies[i].y - galaxies[j].y);
}
}
printf("%lu\n", part1);
free(buf);
}
void expand_universe(int universe_x, int universe_y, tile_t universe[LINE_MAX_LENGTH][LINE_MAX_LENGTH], position_t galaxies[], int galaxies_num, int expansion_rate) {
int empty;
position_t galaxy_offsets[MAX_GALAXIES];
memset(galaxy_offsets, 0, MAX_GALAXIES*sizeof(position_t));
// Empty rows
for (int i = 0; i < universe_y; i++) {
empty = 1;
for (int j = 0; j < universe_x; j++) {
if (universe[j][i] != EMPTY) {
empty = 0;
break;
}
}
if (empty) {
// Shift existing galaxies
for (int k = 0; k < galaxies_num; k++) {
if (galaxies[k].y > i) {
galaxy_offsets[k].y += expansion_rate;
}
}
}
}
// Empty columns
for (int i = 0; i < universe_x; i++) {
empty = 1;
for (int j = 0; j < universe_y; j++) {
if (universe[i][j] != EMPTY) {
empty = 0;
break;
}
}
if (empty) {
// Shift existing galaxies
for (int k = 0; k < galaxies_num; k++) {
if (galaxies[k].x > i) {
galaxy_offsets[k].x += expansion_rate;
}
}
}
}
for (int i = 0; i < galaxies_num; i++) {
galaxies[i].x += galaxy_offsets[i].x;
galaxies[i].y += galaxy_offsets[i].y;
}
}