#include #include #include typedef struct { bool has_exactly_two; bool has_exactly_three; } ChecksumResult; bool is_off_by_one(const char *id1, const char *id2) { bool miss = false; while(*id1 > 0 && *id2 > 0) { if (*id1 != *id2) { if (miss) return false; miss = true; } id1++; id2++; } return miss; } void off_by_one_intersection(const char *id1, const char *id2, char *intersection) { int i = 0; while(*id1 > 0 && *id2 > 0) { if (*id1 == *id2) { intersection[i] = *id1; i++; } id1++; id2++; } intersection[i] = 0; } void checksum(const char *id, ChecksumResult *result) { result->has_exactly_two = false; result->has_exactly_three = false; int char_counts[26] = {0}; while(*id > 0) { char_counts[*id - 'a'] ++; id++; } for (int i = 0; i < 26; i++) { if(char_counts[i] == 2) result->has_exactly_two = true; if(char_counts[i] == 3) result->has_exactly_three = true; } } typedef char Line[27]; int part_1(FILE *input) { rewind(input); ChecksumResult result = {0}; int twos = 0; int threes = 0; Line line_buffer; while(fscanf(input, "%s", line_buffer) > 0) { checksum(line_buffer, &result); if (result.has_exactly_two) twos++; if (result.has_exactly_three) threes++; } return twos * threes; } void part_2(FILE *input) { rewind(input); Line lines[250] = {0}; Line buffer; int line_number = 0; while(fscanf(input, "%s", buffer) > 0) { strcpy(lines[line_number++], buffer); } bool found = false; for(int i = 0; !found && i < 250; i++) { for(int j = i; !found && j < 250; j++) { if(is_off_by_one(lines[i], lines[j])) { found = true; off_by_one_intersection(lines[i], lines[j], buffer); } } } printf("Part 2: %s\n", buffer); } int main() { char *input_file_path = "../data/2018/2/input.txt"; FILE *input = fopen(input_file_path, "r"); if (input == NULL) { printf("Can't open file %s\n", input_file_path); return 1; } printf("Part 1: %d\n", part_1(input)); part_2(input); // This is a string and I don't want to malloc it fclose(input); }