Solve Day 02 Part 1

This commit is contained in:
zeichensystem 2025-12-03 16:19:54 +01:00
parent 76ea6e5d18
commit e878231d52
4 changed files with 161 additions and 1 deletions

View File

@ -36,7 +36,7 @@ if (ipo_available AND (NOT CMAKE_BUILD_TYPE MATCHES Debug) AND (NOT CMAKE_BUILD_
message("-- IPO enabled") message("-- IPO enabled")
endif() endif()
set(TARGETS day-01) # Add the other days as you please. set(TARGETS day-01 day-02) # Add the other days as you please.
list(LENGTH TARGETS NUM_TARGETS) list(LENGTH TARGETS NUM_TARGETS)
@ -72,11 +72,13 @@ endforeach(current_target)
add_custom_target("run-all" add_custom_target("run-all"
DEPENDS ${TARGETS} DEPENDS ${TARGETS}
COMMAND day-01 ${CMAKE_CURRENT_SOURCE_DIR}/input/day-01.txt COMMAND day-01 ${CMAKE_CURRENT_SOURCE_DIR}/input/day-01.txt
COMMAND day-01 ${CMAKE_CURRENT_SOURCE_DIR}/input/day-02.txt
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
) )
add_custom_target("run-all-examples" add_custom_target("run-all-examples"
DEPENDS ${TARGETS} DEPENDS ${TARGETS}
COMMAND day-01 ${CMAKE_CURRENT_SOURCE_DIR}/input/day-01-example.txt COMMAND day-01 ${CMAKE_CURRENT_SOURCE_DIR}/input/day-01-example.txt
COMMAND day-02 ${CMAKE_CURRENT_SOURCE_DIR}/input/day-02-example.txt
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
) )

117
day-02/day-02.c Normal file
View File

@ -0,0 +1,117 @@
#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;
}

3
input/day-02-example.txt Normal file
View File

@ -0,0 +1,3 @@
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,
1698522-1698528,446443-446449,38593856-38593862,565653-565659,
824824821-824824827,2121212118-2121212124

View File

@ -129,6 +129,8 @@ GUF_STR_KWRDS guf_str_tok_state guf_str_tok_state_new(guf_str_view str, guf_str_
GUF_STR_KWRDS bool guf_str_tok_next(guf_str_tok_state *state, bool preserve_delims); GUF_STR_KWRDS bool guf_str_tok_next(guf_str_tok_state *state, bool preserve_delims);
GUF_STR_KWRDS unsigned guf_str_view_read_uint(guf_str_view *sv); // TODO: Handle overflow, signs etc. GUF_STR_KWRDS unsigned guf_str_view_read_uint(guf_str_view *sv); // TODO: Handle overflow, signs etc.
GUF_STR_KWRDS uint_least64_t guf_str_view_read_u64(guf_str_view *sv);
// 2.) guf_str: // 2.) guf_str:
@ -215,6 +217,9 @@ GUF_STR_KWRDS guf_str *guf_str_append(guf_str *str, guf_str_view sv);
GUF_STR_KWRDS ptrdiff_t guf_str_try_append_file(guf_str *to_append, const char *fname, guf_err *err); GUF_STR_KWRDS ptrdiff_t guf_str_try_append_file(guf_str *to_append, const char *fname, guf_err *err);
GUF_STR_KWRDS ptrdiff_t guf_str_append_file(guf_str *to_append, const char *fname); GUF_STR_KWRDS ptrdiff_t guf_str_append_file(guf_str *to_append, const char *fname);
// Append ints:
GUF_STR_KWRDS guf_str *guf_str_append_u64(guf_str *str, uint_least64_t n);
// Return a pointer to the null-terminated char array representing the string (works like std::string::c_str in C++) // Return a pointer to the null-terminated char array representing the string (works like std::string::c_str in C++)
GUF_STR_KWRDS const char *guf_str_const_cstr(const guf_str *str); GUF_STR_KWRDS const char *guf_str_const_cstr(const guf_str *str);
GUF_STR_KWRDS char *guf_str_try_get_cstr(guf_str *str, guf_err *err); // Error if str is readonly. GUF_STR_KWRDS char *guf_str_try_get_cstr(guf_str *str, guf_err *err); // Error if str is readonly.
@ -1188,6 +1193,27 @@ GUF_STR_KWRDS ptrdiff_t guf_str_append_file(guf_str *to_append, const char *fna
} }
GUF_STR_KWRDS guf_str *guf_str_append_u64(guf_str *str, uint_least64_t n) {
char buf[20] = {'\0'};
int start_idx = GUF_ARR_SIZE(buf);
int num_digits = 0;
do {
GUF_ASSERT(start_idx > 0);
char c = (n % 10) + '0';
buf[--start_idx] = c;
++num_digits;
} while ((n = n / 10));
GUF_ASSERT(num_digits == (int)GUF_ARR_SIZE(buf) - start_idx);
const guf_str_view num_sv = (guf_str_view) {.str = buf + start_idx, .len = num_digits};
return guf_str_append(str, num_sv);
}
GUF_STR_KWRDS guf_str *guf_str_try_substr(guf_str *str, ptrdiff_t pos, ptrdiff_t count, guf_err *err) GUF_STR_KWRDS guf_str *guf_str_try_substr(guf_str *str, ptrdiff_t pos, ptrdiff_t count, guf_err *err)
{ {
GUF_ASSERT(guf_str_is_valid(str)); GUF_ASSERT(guf_str_is_valid(str));
@ -1584,6 +1610,18 @@ GUF_STR_KWRDS unsigned guf_str_view_read_uint(guf_str_view *sv)
return res; return res;
} }
GUF_STR_KWRDS uint_least64_t guf_str_view_read_u64(guf_str_view *sv)
{ // TODO: Handle overflow etc.
uint_least64_t res = 0;
while (sv->len && sv->str[0] >= '0' && sv->str[0] <= '9') {
res *= 10;
res += (sv->str[0] - '0');
sv->len -= 1;
sv->str = sv->len > 0 ? sv->str + 1 : NULL;
}
return res;
}
#undef GUF_STR_IMPL #undef GUF_STR_IMPL
#undef GUF_STR_IMPL_STATIC #undef GUF_STR_IMPL_STATIC
#endif /* end impl */ #endif /* end impl */