diff --git a/CMakeLists.txt b/CMakeLists.txt index e0eb1b6..9bfece6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ set(TARGETS day-01 day-02) # Add the other days as you please. list(LENGTH TARGETS NUM_TARGETS) -set(LIBGUF_IMPLS ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_alloc_libc_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_str_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_init_impl.c ) +set(LIBGUF_IMPLS ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_alloc_libc_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_str_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/guf_init_impl.c ${CMAKE_CURRENT_SOURCE_DIR}/libguf_impls/dict_impl.c) foreach(current_target IN LISTS TARGETS) add_executable(${current_target} ${current_target}/${current_target}.c ${LIBGUF_IMPLS}) diff --git a/day-02/day-02.c b/day-02/day-02.c index b6d1581..791c37b 100644 --- a/day-02/day-02.c +++ b/day-02/day-02.c @@ -3,10 +3,12 @@ #include "guf_str.h" #include "guf_math.h" +#include "libguf_impls/dict_impl.h" + /* - Part 1: 54234399924 (Example: 1227775554) - - Part 2: (Example: ) + - Part 2: 70187097315 (Example: 4174379265) */ guf_allocator g_allocator; @@ -56,6 +58,10 @@ uint64_t solution(guf_str_view input, bool part_two) guf_str_init_empty(&start_str, &g_allocator); guf_str_init_empty(&end_str, &g_allocator); + dict_u64_bool seen_invalid_ids; + dict_u64_bool_init(&seen_invalid_ids, &g_allocator); + + while (read_id_range(&input, &range)) { guf_str_append_u64(&start_str, range.start); guf_str_append_u64(&end_str, range.end); @@ -63,30 +69,44 @@ uint64_t solution(guf_str_view input, bool part_two) 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) { + for (int half_n_digits = 1; half_n_digits <= 20; ++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); + 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; + if (!part_two) { // Part 1: + 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; + } + } else { // Part 2: + uint64_t id = cur_half; + for (int reps = 0; reps < 20; ++reps) { + id = id * pow_10(half_n_digits) + cur_half; + if (id > range.end) { + break; + } else if (id >= range.start) { + if (!dict_u64_bool_contains_val_arg(&seen_invalid_ids, id)) { + invalid_id_sum += id; + dict_u64_bool_insert_val_arg(&seen_invalid_ids, id, true, GUF_CPY_VALUE, GUF_CPY_VALUE); + } + } + } } } } - guf_str_substr(&start_str, 0, 0); guf_str_substr(&end_str, 0, 0); } + dict_u64_bool_free(&seen_invalid_ids, NULL); + return invalid_id_sum; } @@ -108,8 +128,8 @@ int main(int argc, const char **argv) 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); + 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); diff --git a/libguf_impls/dict_impl.c b/libguf_impls/dict_impl.c new file mode 100644 index 0000000..79e6ee8 --- /dev/null +++ b/libguf_impls/dict_impl.c @@ -0,0 +1,10 @@ +#include "dict_impl.h" + +#define GUF_DICT_KEY_T uint64_t +#define GUF_DICT_KEY_HASH uint64_hash +#define GUF_DICT_KEY_T_EQ uint64_eq +#define GUF_DICT_VAL_T bool +#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE +#define GUF_DICT_NAME dict_u64_bool +#define GUF_DICT_IMPL +#include "guf_dict.h" diff --git a/libguf_impls/dict_impl.h b/libguf_impls/dict_impl.h new file mode 100644 index 0000000..8e24fbc --- /dev/null +++ b/libguf_impls/dict_impl.h @@ -0,0 +1,22 @@ +#ifndef GUF_DICT_IMPL_H +#define GUF_DICT_IMPL_H +#include "guf_hash.h" + +static inline guf_hash_size_t uint64_hash(const uint64_t *a) +{ + return guf_hash(a, sizeof(uint64_t), GUF_HASH_INIT); // TODO: byte order... +} +static inline bool uint64_eq(const uint64_t *a, const uint64_t *b) +{ + return *a == *b; +} +#define GUF_DICT_KEY_T uint64_t +#define GUF_DICT_KEY_HASH uint64_hash +#define GUF_DICT_KEY_T_EQ uint64_eq +#define GUF_DICT_VAL_T bool +#define GUF_DICT_VAL_T_IS_INTEGRAL_TYPE +#define GUF_DICT_NAME dict_u64_bool +#include "guf_dict.h" + + +#endif \ No newline at end of file