#include #include #include #include #include "../../lib/aoc.h" typedef int Position[2]; typedef struct Map { char *grid; int width; int height; char signal; int antennas[1000]; int antenna_count; } Map; void position_from_index(Map *map, int index, Position *p) { (*p)[0] = index % map->width; (*p)[1] = index / map->width; } int index_from_position(Map *map, Position p) { return p[0] + p[1] * map->width; } bool position_inbounds(Map *map, Position p) { return p[0] >= 0 && p[1] >= 0 && p[0] < map->width - 1 && p[1] < map->height; } void calculate_antinodes(Map *map, char *antinodes_grid, bool resonant) { int index; for (int i = 0; i < map->antenna_count; i++) { Position first_antenna; position_from_index(map, map->antennas[i], &first_antenna); for (int j = 0; j < i; j++) { Position second_antenna; position_from_index(map, map->antennas[j], &second_antenna); if (resonant) { Position antinode; antinode[0] = first_antenna[0]; antinode[1] = first_antenna[1]; while (position_inbounds(map, antinode)) { index = index_from_position(map, antinode); antinodes_grid[index] = '#'; antinode[0] = antinode[0] + first_antenna[0] - second_antenna[0]; antinode[1] = antinode[1] + first_antenna[1] - second_antenna[1]; } antinode[0] = second_antenna[0]; antinode[1] = second_antenna[1]; while (position_inbounds(map, antinode)) { index = index_from_position(map, antinode); antinodes_grid[index] = '#'; antinode[0] = antinode[0] + second_antenna[0] - first_antenna[0]; antinode[1] = antinode[1] + second_antenna[1] - first_antenna[1]; } } else { Position first_antinode, second_antinode; first_antinode[0] = first_antenna[0] + first_antenna[0] - second_antenna[0]; first_antinode[1] = first_antenna[1] + first_antenna[1] - second_antenna[1]; if (position_inbounds(map, first_antinode)) { index = index_from_position(map, first_antinode); antinodes_grid[index] = '#'; } second_antinode[0] = second_antenna[0] + second_antenna[0] - first_antenna[0]; second_antinode[1] = second_antenna[1] + second_antenna[1] - first_antenna[1]; if (position_inbounds(map, second_antinode)) { index = index_from_position(map, second_antinode); antinodes_grid[index] = '#'; } } } } } int main() { char *input = aoc_read_input(); int input_size = strlen(input); Map master_map; master_map.grid = input; master_map.width = strchr(input, '\n') - input + 1; master_map.height = input_size / master_map.width; char *empty_grid = malloc(input_size + 1); for (int i = 0; i < input_size; i++) { empty_grid[i] = '.'; if (i % master_map.width == master_map.width - 1) empty_grid[i] = '\n'; } empty_grid[input_size] = '\0'; char *antinode_grid = malloc(input_size + 1); strcpy(antinode_grid, empty_grid); char *resonant_antinode_grid = malloc(input_size + 1); strcpy(resonant_antinode_grid, empty_grid); Map maps[64]; for (int i = 0; i < 64; i++) { maps[i].grid = malloc(input_size + 1); strcpy(maps[i].grid, empty_grid); maps[i].width = master_map.width; maps[i].height = master_map.height; if (i < 26) { maps[i].signal = i + 'a'; } else if (i < 52) { maps[i].signal = i - 26 + 'A'; } else { maps[i].signal = i - 52 + '0'; } } for (int i = 0; i < input_size; i++) { char c = master_map.grid[i]; if (c == '.' || c == '\n') continue; int map_index; if (c >= 'a' && c <= 'z') map_index = c - 'a'; else if (c >= 'A' && c <= 'Z') map_index = c + 26 - 'A'; else map_index = c + 52 - '0'; maps[map_index].antennas[maps[map_index].antenna_count++] = i; } for (int i = 0; i < 64; i++) { calculate_antinodes(&(maps[i]), antinode_grid, false); } int antinode_count = 0; for (int i = 0; i < input_size; i++) { if (antinode_grid[i] == '#') antinode_count++; } printf("Part 1: %d\n", antinode_count); for (int i = 0; i < 64; i++) { calculate_antinodes(&(maps[i]), resonant_antinode_grid, true); } int resonant_antinode_count = 0; for (int i = 0; i < input_size; i++) { if (resonant_antinode_grid[i] == '#') resonant_antinode_count++; } printf("Part 2: %d\n", resonant_antinode_count); free(empty_grid); free(antinode_grid); free(resonant_antinode_grid); for (int i = 0; i < 64; i++) free(maps[i].grid); aoc_free(); return 0; }