diff --git a/2023/day1/solution.c b/2023/day1/solution.c index 323ba25..d9f68b2 100644 --- a/2023/day1/solution.c +++ b/2023/day1/solution.c @@ -1,11 +1,90 @@ #include +#include "parse.h" + +typedef int (* digit_parser_t)(const char * start, const char * end); + +static int part1_digit_parser(const char * start, const char * end) +{ + return parse_base10_digit(*start); +} + +static int part2_digit_parser(const char * start, const char * end) +{ + int length = end - start; + if (length >= 1) { + int n = parse_base10_digit(*start); + if (n >= 0) return n; + } + if (length >= 3) { + if (parse_match(start, "one")) return 1; + if (parse_match(start, "two")) return 2; + if (parse_match(start, "six")) return 6; + } + if (length >= 4) { + if (parse_match(start, "four")) return 4; + if (parse_match(start, "five")) return 5; + if (parse_match(start, "nine")) return 9; + } + if (length >= 5) { + if (parse_match(start, "three")) return 3; + if (parse_match(start, "seven")) return 7; + if (parse_match(start, "eight")) return 8; + } + return -1; +} + +static int parse_digit_left(const char * start, const char * end, digit_parser_t parser) +{ + while (start < end) { + int digit = parser(start, end); + if (digit >= 0) { + return digit; + } + start++; + } + return -1; +} + +static int parse_digit_right(const char * start, const char * end, digit_parser_t parser) +{ + const char * s = end - 1; + while (s >= start) { + int digit = parser(s, end); + if (digit >= 0) { + return digit; + } + s--; + } + return -1; +} + +int solve(const char * input, int length, digit_parser_t parser) +{ + const char * end = input + length; + + int sum = 0; + + while (input < end) { + const char * newline = parse_find(input, '\n'); + int left = parse_digit_left(input, newline, parser); + int right = parse_digit_right(input, newline, parser); + + sum += left * 10 + right; + + input = newline + 1; + } + + + return sum; +} + int64_t _2023_day1_part1(const char * input, int length) { - return -1; + return solve(input, length, part1_digit_parser); } int64_t _2023_day1_part2(const char * input, int length) { - return -1; + return solve(input, length, part2_digit_parser); } diff --git a/Makefile b/Makefile index 7cfd750..70a2ae3 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ CFLAGS += -Wno-char-subscripts LIB ?= $(MAKEFILE_PATH)/dreamcast libgcc/%.o: $(LIBGCC) + @mkdir -p $(dir $@) ar x --output $(dir $@) $(LIBGCC) $(notdir $@) sh4-none-elf-objdump -t $@ \ | grep -E '[.]hidden' \ diff --git a/input_dreamcast.c b/input_dreamcast.c index b1eb4e6..fd5b6b6 100644 --- a/input_dreamcast.c +++ b/input_dreamcast.c @@ -25,7 +25,7 @@ void open_input(int ix, char ** buf, int * length) void open_sample(int ix, int part, char ** buf, int * length) { - if (ix < 1 || ix > input_size || part < 0 || part > 1) { + if (ix < 0 || ix > input_size || part < 0 || part > 1) { *buf = NULL; *length = 0; } else { diff --git a/parse.c b/parse.c index d63555b..ef45ef6 100644 --- a/parse.c +++ b/parse.c @@ -3,25 +3,6 @@ #include "parse.h" -const char * parse_skip(const char * s, char c) -{ - while (*s == c) { - s++; - } - return s; -} - -const char * parse_find_first_right(const char * s, int length, char c) -{ - const char * ss = &s[length - 1]; - while (ss >= s) { - if (*ss == c) - return ss; - ss--; - } - return s; -} - int parse_base10_digit(char c) { switch (c) { @@ -39,6 +20,33 @@ int parse_base10_digit(char c) } } +const char * parse_skip(const char * s, char c) +{ + while (*s == c) { + s++; + } + return s; +} + +const char * parse_find(const char * s, char c) +{ + while (*s != c) { + s++; + } + return s; +} + +const char * parse_find_first_right(const char * s, int length, char c) +{ + const char * ss = &s[length - 1]; + while (ss >= s) { + if (*ss == c) + return ss; + ss--; + } + return s; +} + const char * parse_base10(const char * s, int * n) { *n = 0; diff --git a/parse.h b/parse.h index 295d366..3e7f4e4 100644 --- a/parse.h +++ b/parse.h @@ -7,6 +7,7 @@ extern "C" { #endif const char * parse_skip(const char * s, char c); +const char * parse_find(const char * s, char c); const char * parse_find_first_right(const char * s, int length, char c); int parse_base10_digit(char c); const char * parse_base10(const char * s, int * n); diff --git a/runner.c b/runner.c index 6a22cc6..1e5115d 100644 --- a/runner.c +++ b/runner.c @@ -26,6 +26,7 @@ bool runner_tick(struct runner_state * runner_state) { int tick = (solution_ticks - 1) - runner_state->tick; //int tick = runner_state->tick; + runner_state->tick += 1; if (tick < 0) { runner_state->want_render = false; @@ -37,18 +38,20 @@ bool runner_tick(struct runner_state * runner_state) int year = solution[ix].year; int day = solution[ix].day; + if (year != 2023) { + return false; + } + runner_state->want_render = solution[ix].render != NULL; char * buf; int length; - open_sample(ix, part, &buf, &length); - //open_input(ix, &buf, &length); - int64_t answer = solution[day].part[part](buf, length); + //open_sample(ix, part, &buf, &length); + open_input(ix, &buf, &length); + int64_t answer = solution[ix].part[part](buf, length); printf("%d day %d part %d: %l\n", year, day, part + 1, answer); - runner_state->tick += 1; - return false; }