#include #include #include #include #include "../../lib/aoc.h" char *target_string = "XMAS"; #define TARGET_STRING_LENGTH 4 typedef struct Puzzle { char *text; int width; int height; } Puzzle; char puzzle_char_at(Puzzle *puzzle, int row, int column) { return puzzle->text[column + (puzzle->width * row)]; } bool puzzle_inbounds(Puzzle *puzzle, int row, int column) { return row < puzzle->height && row >= 0 && column >= 0 && column < puzzle->width; } int target_string_count(Puzzle *puzzle, int index) { if (puzzle->text[index] != target_string[0]) return 0; int count = 0; int row = index / puzzle->width; int column = index % puzzle->width; // right for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row, column + i)) break; if (puzzle_char_at(puzzle, row, column + i) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // down right for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row + i, column + i)) break; if (puzzle_char_at(puzzle, row + i, column + i) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // down for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row + i, column)) break; if (puzzle_char_at(puzzle, row + i, column) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // down left for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row + i, column - i)) break; if (puzzle_char_at(puzzle, row + i, column - i) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // left for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row, column - i)) break; if (puzzle_char_at(puzzle, row, column - i) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // up left for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row - i, column - i)) break; if (puzzle_char_at(puzzle, row - i, column - i) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // up for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row - i, column)) break; if (puzzle_char_at(puzzle, row - i, column) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } // up right for (int i = 1; i < TARGET_STRING_LENGTH; i++) { if (!puzzle_inbounds(puzzle, row - i, column + i)) break; if (puzzle_char_at(puzzle, row - i, column + i) != target_string[i]) break; if (i == TARGET_STRING_LENGTH - 1) count += 1; } return count; } char mas[4]; int xmas_count(Puzzle *puzzle, int index) { if (puzzle->text[index] != 'A') return 0; int row = index / puzzle->width; int column = index % puzzle->width; if ( puzzle_inbounds(puzzle, row - 1, column + 1) && puzzle_inbounds(puzzle, row + 1, column + 1) && puzzle_inbounds(puzzle, row + 1, column - 1) && puzzle_inbounds(puzzle, row - 1, column - 1) ) { mas[0] = puzzle_char_at(puzzle, row - 1, column + 1); mas[1] = puzzle_char_at(puzzle, row + 1, column + 1); mas[2] = puzzle_char_at(puzzle, row + 1, column - 1); mas[3] = puzzle_char_at(puzzle, row - 1, column - 1); if (((mas[0] == 'M' && mas[2] == 'S') || (mas[0] == 'S' && mas[2] == 'M')) && ((mas[1] == 'M' && mas[3] == 'S') || (mas[1] == 'S' && mas[3] == 'M'))) { return 1; } } return 0; } int main() { char *input = aoc_read_input(); int width = strchr(input, '\n') - input + 1; int height = strlen(input) / width; Puzzle p; p.text = input; p.width = width; p.height = height; int sum = 0; int xmas_sum = 0; for (int i = 0; i < strlen(input); i++) { sum += target_string_count(&p, i); xmas_sum += xmas_count(&p, i); } printf("Part 1: %d\n", sum); printf("Part 2: %d\n", xmas_sum); aoc_free(); return 0; }