#include #include #include #include #include #include #include #include "aoc.h" #include "day1.c" #include "day2.c" #include "day3.c" #include "day4.c" #include "day5.c" #include "day6.c" Solution *find_solution(int day) { for (int i = 0; i < SOLUTIONS_COUNT; i++) { Solution *s = &SOLUTIONS[i]; if (s->day == day) { return s; } } return NULL; } char **read_lines(int *line_count, FILE *f) { *line_count = 0; rewind(f); while(!feof(f)){ char ch = fgetc(f); if(ch == '\n') { (*line_count)++; } } char **lines = malloc(*line_count * sizeof(char*)); char *line; size_t len = 0; int i = 0; size_t read; rewind(f); while ((read = getline(&line, &len, f)) != -1) { line[read-1] = '\0'; lines[i++] = strdup(line); } return lines; } int download_input(int day, char *filename, char *session) { int rc = 0; curl_global_init(CURL_GLOBAL_ALL); FILE *f = fopen(filename, "w"); CURL *curl = curl_easy_init(); CURLcode curl_code; if (curl) { char *cookie_header = calloc(42 + strlen(session), sizeof(char)); sprintf(cookie_header, "Cookie: session=%s", session); char url[81] = { 0 }; sprintf(url, "https://adventofcode.com/2022/day/%d/input", day); struct curl_slist *chunk = NULL; chunk = curl_slist_append(chunk, cookie_header); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk); curl_easy_setopt(curl, CURLOPT_WRITEDATA, f); curl_easy_setopt(curl, CURLOPT_URL, &url); curl_code = curl_easy_perform(curl); if (curl_code == CURLE_OK) { long http_code = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); if (http_code != 200) { fprintf(stderr, "Request failed: HTTP code %ld\n", http_code); rc = -1; } } else { fprintf(stderr, "Request failed: %s\n", curl_easy_strerror(curl_code)); rc = -1; } curl_easy_cleanup(curl); curl_slist_free_all(chunk); } end: curl_global_cleanup(); fclose(f); if (rc) { remove(filename); } return rc; } void print_solutions() { fprintf(stderr, "Available solutions: "); for (int i = 0; i < SOLUTIONS_COUNT; i++) { Solution *s = &SOLUTIONS[i]; fprintf(stderr, "%d ", s->day); } fprintf(stderr, "\n"); } int main(int argc, char** argv) { if (argc < 2) { fprintf(stderr, "Usage: %s [input.txt]\n", argv[0]); exit(1); } int day = atoi(argv[1]); if (day == 0) { fprintf(stderr, "Day number is invalid\n"); print_solutions(); exit(1); } Solution *solution = find_solution(day); if (solution == NULL) { fprintf(stderr, "Failed to find solution to %d\n", day); print_solutions(); exit(1); } char *input_file = NULL; if (argc >= 3) { input_file = argv[2]; } else if ( access( "input.txt", F_OK ) != -1 ) { input_file = "input.txt"; } else { char* session = getenv("AOC_SESSION"); if (session && !download_input(day, "input.txt", session)) { input_file = "input.txt"; } else { fprintf(stderr, "Missing input file"); exit(1); } } FILE *f = fopen(input_file, "r"); if (f == NULL) { fprintf(stderr, "Failed to open file solution to day '%s': %s\n", input_file, strerror(errno)); return 1; } int line_count; char **lines = read_lines(&line_count, f); fclose(f); void* parsed = solution->parse(lines, line_count); printf("part1:\n"); solution->part1(parsed); printf("part2:\n"); solution->part2(parsed); return 0; }