101 lines
2.1 KiB
C
101 lines
2.1 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
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);
|
|
}
|