Solve Day 02 Part 1
This commit is contained in:
parent
76ea6e5d18
commit
e878231d52
@ -36,7 +36,7 @@ if (ipo_available AND (NOT CMAKE_BUILD_TYPE MATCHES Debug) AND (NOT CMAKE_BUILD_
|
||||
message("-- IPO enabled")
|
||||
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)
|
||||
|
||||
@ -72,11 +72,13 @@ endforeach(current_target)
|
||||
add_custom_target("run-all"
|
||||
DEPENDS ${TARGETS}
|
||||
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}
|
||||
)
|
||||
|
||||
add_custom_target("run-all-examples"
|
||||
DEPENDS ${TARGETS}
|
||||
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}
|
||||
)
|
||||
|
||||
117
day-02/day-02.c
Normal file
117
day-02/day-02.c
Normal 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
3
input/day-02-example.txt
Normal 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
|
||||
@ -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 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:
|
||||
@ -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_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++)
|
||||
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.
|
||||
@ -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_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;
|
||||
}
|
||||
|
||||
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_STATIC
|
||||
#endif /* end impl */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user