aoc-2025/day-01/day-01.c
2025-12-02 22:46:16 +01:00

83 lines
2.9 KiB
C

#include "guf_common.h"
#include "guf_alloc_libc.h"
#include "guf_str.h"
/*
- Part 1: 1191 (Example: 3)
- modular arithmetic
- Part 2: 6858 (Example: 6)
- modular arithmetic and integer division
- note the special case for handling left turns when the dial is at zero.
- took me two tries to figure out %)
*/
guf_allocator g_allocator;
guf_libc_alloc_ctx g_allocator_ctx;
int solution(guf_str_view input, bool part_two)
{
guf_str_view linebreak_delim = GUF_CSTR_LIT_TO_VIEW("\n");
guf_str_tok_state tokenizer = guf_str_tok_state_new(input, &linebreak_delim, 1, GUF_STR_TOK_DELIM_OPT_MATCH_LONGEST);
const int DIAL_SIZE = 100; // 0 to 99
int cur_dial_pos = 50;
int num_zeroes_encountered = 0;
while (guf_str_tok_next(&tokenizer, false)) { // For each line.
guf_str_view line = guf_str_view_trim_left_ascii(tokenizer.cur_tok);
if (line.len < 2) {
continue;
}
const int dir = line.str[0] == 'L' ? -1 : 1;
line = guf_str_view_substr(line, 1, line.len - 1);
const int num_clicks = guf_str_view_read_uint(&line);
if (!part_two) { // Part 1:
cur_dial_pos = ( DIAL_SIZE + ((cur_dial_pos + dir * num_clicks) % DIAL_SIZE) ) % DIAL_SIZE;
if (cur_dial_pos == 0) {
++num_zeroes_encountered;
}
} else { // Part 2:
int passed_zeroes = 0;
if (dir == -1) { // Left (counter-clockwise) turn
passed_zeroes = (DIAL_SIZE - cur_dial_pos + num_clicks) / DIAL_SIZE;
if (cur_dial_pos == 0 && passed_zeroes > 0 && num_clicks > 0) { // Special case for left turns: Don't count twice if the current position is zero.
passed_zeroes -= 1;
}
} else { // Right (clockwise) turn
passed_zeroes = (cur_dial_pos + num_clicks) / DIAL_SIZE;
}
num_zeroes_encountered += passed_zeroes;
cur_dial_pos = ( DIAL_SIZE + ((cur_dial_pos + dir * num_clicks) % DIAL_SIZE) ) % DIAL_SIZE; // Same as in part one
}
}
return num_zeroes_encountered;
}
int main(int argc, const char **argv)
{
g_allocator_ctx.zero_init = false;
guf_alloc_tracker_init(&g_allocator_ctx.tracker, 1, "Day-1 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 int p1_result = solution(guf_str_view_from_str(&input_str), false);
printf("Part one: %d\n", p1_result);
const int p2_result = solution(guf_str_view_from_str(&input_str), true);
printf("Part two: %d\n", p2_result);
guf_str_free(&input_str, NULL);
return EXIT_SUCCESS;
}