diff options
Diffstat (limited to 'Advent-of-Code-2020/AOC-4/main.c')
-rw-r--r-- | Advent-of-Code-2020/AOC-4/main.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/Advent-of-Code-2020/AOC-4/main.c b/Advent-of-Code-2020/AOC-4/main.c new file mode 100644 index 0000000..895dd00 --- /dev/null +++ b/Advent-of-Code-2020/AOC-4/main.c @@ -0,0 +1,140 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#if 0 +#define PART_1 +#else +#define PART_2 +#endif + +#if 0 +#define FILE_PATH "example-valid.txt" +#else +#define FILE_PATH "input.txt" +#endif + +char fields[8][4] = {"byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid", "cid"}; + +size_t valid = 0; + +void parse() +{ + FILE *fp = fopen(FILE_PATH, "r"); + if(!fp) { + fprintf(stderr, "ERROR: Could not open file: %s", FILE_PATH); + exit(EXIT_FAILURE); + } + + char line[2048] = {0}; + int field_valid[8] = {0}; + while(fgets(line, sizeof(line), fp) != NULL) + { + if(line[0] == '\n' || strncmp(line, "EOF", 3) == 0) + { + int result = 1; + for(int i = 0; i < 7; i++) + result *= field_valid[i]; + + valid += result; + memset(field_valid, 0 , sizeof(field_valid)); + continue; + } + + char *tok = strtok(line, " "); + while(tok != NULL) + { + for(int i = 0; i < 8; i++) + { + if(strncmp(tok, fields[i], 3) == 0) + { + #ifdef PART_1 + field_valid[i] = 1; + #endif + + #ifdef PART_2 + + char *saveptr; + (void)strtok_r(tok, ":", &saveptr); + char *val = strtok_r(NULL, ":", &saveptr); + assert(val != NULL); + assert(strtok_r(NULL, ":", &saveptr) == NULL); + + if(val[strlen(val)-1] == '\n') val[strlen(val)-1] = '\0'; + + int ival; + switch(i) + { + case 0: ival = atoi(val); + if(ival >= 1920 && ival <= 2002) field_valid[i] = 1; + break; + case 1: ival = atoi(val); + if(ival >= 2010 && ival <= 2020) field_valid[i] = 1; + break; + case 2: ival = atoi(val); + if(ival >= 2020 && ival <= 2030) field_valid[i] = 1; + break; + case 3: + if(strlen(val) == 5) + { + if(!(val[3] == 'c' && val[4] == 'm')) break; + char _val[4] = {0}; _val[0] = val[0]; + _val[1] = val[1]; _val[2] = val[2]; + ival = atoi(_val); + if(ival >= 150 && ival <= 193) field_valid[i] = 1; + } + if(strlen(val) == 4) + { + if(!(val[2] == 'i' && val[3] == 'n')) break; + char _val[3] = {0}; _val[0] = val[0]; _val[1] = val[1]; + ival = atoi(_val); + + if(ival >= 59 && ival <= 76) field_valid[i] = 1; + } + + break; + case 4: + int num = 0; + char valid_vals[16] = "0123456789abcdef"; + for(int k = 1; k <= strlen(val); k++) + for(int j = 0; j < 16; j++) + if(val[k] == valid_vals[j]) num++; + + if(val[0] == '#' && num == 6) field_valid[i] = 1; + break; + case 5: + int valid_ecl = 0; + char valid_cols[7][4] = {"amb", "blu", "brn", "gry", "grn", "hzl", "oth"}; + for(int k = 0; k < 7; k++) + if(strncmp(val, valid_cols[k], 3) == 0) valid_ecl++; + + if(valid_ecl == 1) field_valid[i] = 1; + break; + case 6: + int valid_pid = 0; + if(strlen(val) != 9) break; + char valid_nums[10] = "0123456789"; + for(int k = 0; k < strlen(val); k++) + for(int j = 0; j < 10; j++) + if(val[k] == valid_nums[j]) valid_pid++; + + if(valid_pid == 9) field_valid[i] = 1; + break; + } + #endif + } + } + tok = strtok(NULL, " "); + } + } + + fclose(fp); +} + +int main(void) +{ + parse(); + printf("%ld passports are valid\n", valid); + return 0; +} |