#include "guf_common.h" #include "guf_alloc_libc.h" #include "guf_str.h" #include "guf_math.h" /* - Part 1: 54234399924 (Example: 1227775554) - Part 2: (Example: ) */ guf_allocator g_allocator; guf_libc_alloc_ctx g_allocator_ctx; typedef struct id_range { uint64_t start, end; } id_range; bool read_id_range(guf_str_view *str, id_range *result) { guf_str_view start_str = guf_str_view_pop_split(str, GUF_CSTR_LIT_TO_VIEW("-")); guf_str_view end_str = guf_str_view_pop_split(str, GUF_CSTR_LIT_TO_VIEW(",")); start_str = guf_str_view_trim_left_ascii(start_str); end_str = guf_str_view_trim_left_ascii(end_str); if (start_str.len <= 0 || end_str.len <= 0) { return false; } uint64_t start = guf_str_view_read_u64(&start_str); uint64_t end = guf_str_view_read_u64(&end_str); result->start = start; result->end = end; return true; } uint64_t pow_10(int exp) { GUF_ASSERT(exp >= 0); uint64_t res = 1; while (exp--) { res *= 10u; } return res; } uint64_t solution(guf_str_view input, bool part_two) { uint64_t invalid_id_sum = 0; id_range range; guf_str start_str, end_str; guf_str_init_empty(&start_str, &g_allocator); guf_str_init_empty(&end_str, &g_allocator); while (read_id_range(&input, &range)) { guf_str_append_u64(&start_str, range.start); guf_str_append_u64(&end_str, range.end); const int n_digits_start = (int)guf_str_len(&start_str); const int n_digits_end = (int)guf_str_len(&end_str); // Generate all pairs of one, two, three, ... digits (without leading zeroes) for (int half_n_digits = 1; half_n_digits <= 10; ++half_n_digits) { if (half_n_digits * 2 > n_digits_end) { break; } else if (half_n_digits * 2 < n_digits_start) { continue; } const uint64_t min_half = pow_10(half_n_digits - 1); const uint64_t max_half = pow_10(half_n_digits) - 1; for (uint64_t cur_half = min_half; cur_half <= max_half; ++cur_half) { uint64_t id = cur_half * pow_10(half_n_digits) + cur_half; if (id > range.end) { break; } else if (id >= range.start) { invalid_id_sum += id; } } } guf_str_substr(&start_str, 0, 0); guf_str_substr(&end_str, 0, 0); } return invalid_id_sum; } int main(int argc, const char **argv) { g_allocator_ctx.zero_init = false; guf_alloc_tracker_init(&g_allocator_ctx.tracker, 1, "Day-2 heap allocator", NULL, stderr); guf_libc_allocator_init(&g_allocator, &g_allocator_ctx); if (argc < 2) { printf("No input file given.\n"); return EXIT_FAILURE; } guf_str input_str = GUF_STR_UNINITIALISED; guf_str_init_empty(&input_str, &g_allocator); guf_str_append_file(&input_str, argv[1]); const uint64_t p1_result = solution(guf_str_view_from_str(&input_str), false); printf("Part 1: %" PRIu64 "\n", p1_result); // const uint64_t p2_result = solution(guf_str_view_from_str(&input_str), true); // printf("Part 2: %" PRIu64 "\n", p2_result); guf_str_free(&input_str, NULL); return EXIT_SUCCESS; }