132 lines
3.4 KiB
C
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;
|
|
}
|
|
}
|