diff --git a/aoc.mk b/aoc.mk index 0524a3c..c9ed242 100644 --- a/aoc.mk +++ b/aoc.mk @@ -11,6 +11,7 @@ OBJ = \ DREAMCAST_OBJ = \ runner_dreamcast.o \ input_dreamcast.o \ + sh7091_scif.o \ $(LIB)/holly/core.o \ $(LIB)/holly/region_array.o \ $(LIB)/holly/background.o \ diff --git a/day10/input.txt b/day10/input.txt new file mode 100644 index 0000000..483f666 --- /dev/null +++ b/day10/input.txt @@ -0,0 +1,54 @@ +034565433432321821235456556798712438943432345432101010 +125674344341210930012367349897601123876501656543238923 +545981265210523841112398232098532014101665437654147014 +436780378019654756501454101123442125012878328956056985 +521091489328765661498760130210356916763969012347841076 +342698456410644570187321221202197809854054521078932987 +434784387569653089298435430143087612870123654169410673 +525601295678762120387589347834561543965434783254321034 +510567856789854871456678956921670123457650199165890321 +654356943889903962345665067830589894398743278056785410 +701245012958712653434784167845678765210634565410156789 +898434321867012344321093254976104543231023876321943089 +686321780154102101287765323987267650122012989423872176 +567980691233283237898894015416398532143606788714565765 +408974500543098946907623234505458545014545698601159854 +312363217632127655416510107612369876105894332589018345 +221457898565634562323421458733478983276701201478121230 +100656967874567641032102369021098744589856782363210121 +789345450923498634543001078112321654678345891054308701 +654212321012654521694210981205430903543232654143489610 +503403430156787610784300870376567812654121743267876523 +012567567343898525695421889487854925780010893210965432 +123498788210123436786438976598943056891234984921014101 +019567699101898345877567887678762147878765675870123012 +108754543210567212968900194589054038969454566767636323 +205610121056750303453213293032123229454323879098545438 +014981232347841219874984782143210110301012978121654569 +123672654338932306705675676154560121212307665430743478 +298543789221069455012310145069430430925408578989832387 +567010176109178764563498232178521567876519454567601296 +432123485458769853074567310123678106898323343218970345 +012034394367458102189601489433439256765401252102181234 +123465210210343012078732676512508349850106769843098321 +054896990101212043896543216109612556743219856784587410 +969887889654302158987894107898743445654340145697656531 +878791078745983467856765545677654354567854234548545621 +745622363215676500345653231987980123498960129639343210 +034215454301876211256570120345678154323870038721658343 +122100189321945308967981011234569067212721801290569012 +543893276430932457898876323233432178008934980387378143 +456764345567801966501895400145567889127645673456269654 +369632105478765873432689312176876901234560012562158765 +278543254309894569546576543089985432321071239873043210 +103450569212723278637434010034394321810980548954560127 +894321078112010198728922121165223010901289687643073438 +765697151003434587017213033278112987874398796542189569 +056788769876524326501304544569001056965834321233675678 +145679458985015415432987693432102345216945610344569547 +230989347034376102341056780540989104307898700123678632 +321078234123289211652346791691071234487465410878766781 +989165106000105690789905882782360943296578321969215690 +076234245612234782349814943485456850123489100154304385 +145210238763145671456723876596306765012101256701235276 +234300149854078980365432101487217898721032349810120123 diff --git a/day10/input.txt.h b/day10/input.txt.h new file mode 100644 index 0000000..4b2963f --- /dev/null +++ b/day10/input.txt.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_day10_input_txt_start __asm("_binary_day10_input_txt_start"); +extern uint32_t _binary_day10_input_txt_end __asm("_binary_day10_input_txt_end"); +extern uint32_t _binary_day10_input_txt_size __asm("_binary_day10_input_txt_size"); + +#ifdef __cplusplus +} +#endif diff --git a/day10/sample1.txt b/day10/sample1.txt new file mode 100644 index 0000000..cada9b3 --- /dev/null +++ b/day10/sample1.txt @@ -0,0 +1,8 @@ +89010123 +78121874 +87430965 +96549874 +45678903 +32019012 +01329801 +10456732 diff --git a/day10/sample1.txt.h b/day10/sample1.txt.h new file mode 100644 index 0000000..6e8e1bc --- /dev/null +++ b/day10/sample1.txt.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_day10_sample1_txt_start __asm("_binary_day10_sample1_txt_start"); +extern uint32_t _binary_day10_sample1_txt_end __asm("_binary_day10_sample1_txt_end"); +extern uint32_t _binary_day10_sample1_txt_size __asm("_binary_day10_sample1_txt_size"); + +#ifdef __cplusplus +} +#endif diff --git a/day10/solution.c b/day10/solution.c new file mode 100644 index 0000000..ce13c55 --- /dev/null +++ b/day10/solution.c @@ -0,0 +1,110 @@ +#include + +#include "parse.h" +#include "cartesian.h" +#include "printf.h" +#include "memory.h" +#include "array.h" + +struct offset { + int x; + int y; +}; + +int walk_trailhead(const char * input, + int depth, + int stride, + int width, int height, + int x, int y, + char * reachable) +{ + if (depth == 9) { + reachable[y * width + x] = 1; + return 1; + } + + const static struct offset offset[] = { + { 1, 0}, + {-1, 0}, + { 0, 1}, + { 0, -1}, + }; + + int rating = 0; + for (int i = 0; i < (sizeof (offset)) / (sizeof (offset[0])); i++) { + int new_x = x + offset[i].x; + int new_y = y + offset[i].y; + if (cartesian_inside(width, height, new_x, new_y)) { + char c = input[new_y * stride + new_x]; + int new_depth = parse_base10_digit(c); + if (new_depth == depth + 1) { + rating += walk_trailhead(input, + new_depth, + stride, + width, height, + new_x, new_y, + reachable); + } + } + } + + return rating; +} + +struct rating_score { + int rating; + int score; +}; + +struct rating_score find_trailheads(const char * input, int length, + int stride, + int width, int height + ) +{ + int x = 0; + int y = 0; + + char reachable[width * height]; + int total_score = 0; + int total_rating = 0; + + for (int i = 0; i < length; i++) { + if (input[i] == '0') { + memory_set_char(reachable, 0, width * height); + int rating = walk_trailhead(input, 0, stride, width, height, x, y, reachable); + total_rating += rating; + int score = array_sum_char(reachable, width * height); + total_score += score; + } + if (input[i] == '\n') { + x = 0; + y += 1; + } else { + x += 1; + } + } + + return (struct rating_score){total_rating, total_score}; +} + +int64_t day10_part1(const char * input, int length) +{ + int stride = parse_stride(input, length); + int height = parse_height(input, length); + int width = stride - 1; + + struct rating_score rs = find_trailheads(input, length, stride, width, height); + + return rs.score; +} + +int64_t day10_part2(const char * input, int length) +{ + int stride = parse_stride(input, length); + int height = parse_height(input, length); + int width = stride - 1; + + struct rating_score rs = find_trailheads(input, length, stride, width, height); + + return rs.rating; +} diff --git a/gen.sh b/gen.sh index ae4f9c9..19bd70e 100755 --- a/gen.sh +++ b/gen.sh @@ -42,7 +42,7 @@ function gen_start_size () } -for i in day* ; do +for i in day? day?? ; do make ${i}/sample1.txt.h ${i}/input.txt.h if [ -f ${i}/sample2.txt ]; then make ${i}/sample2.txt.h @@ -52,7 +52,7 @@ done truncate -s0 input_dreamcast.inc -for i in day* ; do +for i in day? day?? ; do echo "#include \"${i}/sample1.txt.h\"" >> input_dreamcast.inc if [ -f ${i}/sample2.txt ]; then echo "#include \"${i}/sample2.txt.h\"" >> input_dreamcast.inc @@ -61,7 +61,7 @@ for i in day* ; do done echo >> input_dreamcast.inc echo "static struct start_size sample[][2] = {" >> input_dreamcast.inc -for i in day* ; do +for i in day? day?? ; do echo " {" >> input_dreamcast.inc gen_start_size " " "${i}" "sample1" if [ ! -f ${i}/sample2.txt ]; then @@ -74,7 +74,7 @@ done echo "};" >> input_dreamcast.inc echo >> input_dreamcast.inc echo "static struct start_size input[] = {" >> input_dreamcast.inc -for i in day* ; do +for i in day? day?? ; do gen_start_size "" "${i}" "input" done echo "};" >> input_dreamcast.inc @@ -82,7 +82,7 @@ echo "};" >> input_dreamcast.inc truncate -s0 solutions.mk echo -n "DAY_OBJ =" >> solutions.mk -for i in day* ; do +for i in day? day?? ; do echo " \\" >> solutions.mk echo " ${i}/sample1.txt.o \\" >> solutions.mk if [ -f ${i}/sample2.txt ]; then @@ -97,7 +97,7 @@ done echo >> solutions.mk truncate -s0 runner.inc -for i in day* ; do +for i in day? day?? ; do echo "int64_t ${i}_part1(const char * input, int length);" >> runner.inc echo "int64_t ${i}_part2(const char * input, int length);" >> runner.inc if [ -f ${i}/render.cpp ]; then @@ -108,7 +108,7 @@ for i in day* ; do done echo >> runner.inc echo "struct day_funcs solution[] = {" >> runner.inc -for i in day* ; do +for i in day? day?? ; do echo " {" >> runner.inc echo " {${i}_part1, ${i}_part2}," >> runner.inc if [ -f ${i}/render.cpp ]; then diff --git a/input_dreamcast.inc b/input_dreamcast.inc index 6891ed5..60d3f72 100644 --- a/input_dreamcast.inc +++ b/input_dreamcast.inc @@ -17,6 +17,8 @@ #include "day8/input.txt.h" #include "day9/sample1.txt.h" #include "day9/input.txt.h" +#include "day10/sample1.txt.h" +#include "day10/input.txt.h" static struct start_size sample[][2] = { { @@ -73,6 +75,12 @@ static struct start_size sample[][2] = { { ( char *)&_binary_day9_sample1_txt_start, (uint32_t)&_binary_day9_sample1_txt_size }, }, + { + { ( char *)&_binary_day10_sample1_txt_start, + (uint32_t)&_binary_day10_sample1_txt_size }, + { ( char *)&_binary_day10_sample1_txt_start, + (uint32_t)&_binary_day10_sample1_txt_size }, + }, }; static struct start_size input[] = { @@ -94,4 +102,6 @@ static struct start_size input[] = { (uint32_t)&_binary_day8_input_txt_size }, { ( char *)&_binary_day9_input_txt_start, (uint32_t)&_binary_day9_input_txt_size }, + { ( char *)&_binary_day10_input_txt_start, + (uint32_t)&_binary_day10_input_txt_size }, }; diff --git a/printf.c b/printf.c index f5d589b..3f14cca 100644 --- a/printf.c +++ b/printf.c @@ -5,6 +5,7 @@ #include "parse.h" #include "unparse.h" #include "printf.h" +#include "sh7091_scif.h" enum format_type { FORMAT_BASE10, @@ -62,6 +63,19 @@ static const char * parse_escape(const char * format, struct format * ft) struct output_buffer global_output_buffer = {0}; +void print_char(char c) +{ + global_output_buffer.buf[global_output_buffer.buf_ix++] = c; + scif_character(c); +} + +static void __print_s(const char * s, int length) +{ + for (int i = 0; i < length; i++) { + scif_character(s[i]); + } +} + void _printf(const char * format, ...) { va_list args; @@ -82,6 +96,7 @@ void _printf(const char * format, ...) int32_t num = va_arg(args, int32_t); char * s = &global_output_buffer.buf[global_output_buffer.buf_ix]; int offset = unparse_base10(s, num, ft.pad_length, ft.fill_char); + __print_s(s, offset); global_output_buffer.buf_ix += offset; } break; @@ -90,6 +105,7 @@ void _printf(const char * format, ...) int64_t num = va_arg(args, int64_t); char * s = &global_output_buffer.buf[global_output_buffer.buf_ix]; int offset = unparse_base10_64(s, num, ft.pad_length, ft.fill_char); + __print_s(s, offset); global_output_buffer.buf_ix += offset; } break; @@ -98,6 +114,7 @@ void _printf(const char * format, ...) uint32_t num = va_arg(args, uint32_t); char * s = &global_output_buffer.buf[global_output_buffer.buf_ix]; int offset = unparse_base16(s, num, ft.pad_length, ft.fill_char); + __print_s(s, offset); global_output_buffer.buf_ix += offset; } break; @@ -105,24 +122,32 @@ void _printf(const char * format, ...) { const char * s = va_arg(args, const char *); while (*s != 0) { - global_output_buffer.buf[global_output_buffer.buf_ix++] = *s++; + char c = *s++; + scif_character(c); + global_output_buffer.buf[global_output_buffer.buf_ix++] = c; } } break; case FORMAT_CHAR: { const int c = va_arg(args, const int); + scif_character((char)c); global_output_buffer.buf[global_output_buffer.buf_ix++] = (char)c; } break; case FORMAT_PERCENT: + scif_character('%'); global_output_buffer.buf[global_output_buffer.buf_ix++] = '%'; break; } } break; default: - global_output_buffer.buf[global_output_buffer.buf_ix++] = *format++; + { + char c = *format++; + scif_character(c); + global_output_buffer.buf[global_output_buffer.buf_ix++] = c; + } break; } } diff --git a/runner.c b/runner.c index 423539f..70529e5 100644 --- a/runner.c +++ b/runner.c @@ -32,7 +32,7 @@ bool runner_tick(struct runner_state * runner_state) int part = tick % 2; int day = tick / 2; - if (day < 8) + if (day < 9) return true; runner_state->want_render = solution[day].render != NULL; diff --git a/runner.inc b/runner.inc index bd1eb88..7af3b94 100644 --- a/runner.inc +++ b/runner.inc @@ -19,6 +19,8 @@ int64_t day8_part1(const char * input, int length); int64_t day8_part2(const char * input, int length); int64_t day9_part1(const char * input, int length); int64_t day9_part2(const char * input, int length); +int64_t day10_part1(const char * input, int length); +int64_t day10_part2(const char * input, int length); struct day_funcs solution[] = { { @@ -57,4 +59,8 @@ struct day_funcs solution[] = { {day9_part1, day9_part2}, NULL, }, + { + {day10_part1, day10_part2}, + NULL, + }, }; diff --git a/runner_dreamcast.cpp b/runner_dreamcast.cpp index 5278e9a..845fcf4 100644 --- a/runner_dreamcast.cpp +++ b/runner_dreamcast.cpp @@ -454,11 +454,3 @@ int main() serial::string("return\n"); serial::string("return\n"); } - - -extern "C" -void print_char(char c) -{ - global_output_buffer.buf[global_output_buffer.buf_ix++] = c; - serial::character(c); -} diff --git a/sh7091_scif.cpp b/sh7091_scif.cpp new file mode 100644 index 0000000..c5cf598 --- /dev/null +++ b/sh7091_scif.cpp @@ -0,0 +1,15 @@ +#include "sh7091/sh7091.hpp" +#include "sh7091/sh7091_bits.hpp" + +#include "sh7091_scif.h" + +void scif_character(const char c) +{ + using namespace scif; + // wait for transmit fifo to become partially empty + while ((sh7091.SCIF.SCFSR2 & scfsr2::tdfe::bit_mask) == 0); + + sh7091.SCIF.SCFSR2 &= ~scfsr2::tdfe::bit_mask; + + sh7091.SCIF.SCFTDR2 = static_cast(c); +} diff --git a/sh7091_scif.h b/sh7091_scif.h new file mode 100644 index 0000000..419a1f5 --- /dev/null +++ b/sh7091_scif.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void scif_character(const char c); + +#ifdef __cplusplus +} +#endif diff --git a/solutions.mk b/solutions.mk index cb61e8f..f388687 100644 --- a/solutions.mk +++ b/solutions.mk @@ -27,4 +27,7 @@ DAY_OBJ = \ day8/solution.o \ day9/sample1.txt.o \ day9/input.txt.o \ - day9/solution.o + day9/solution.o \ + day10/sample1.txt.o \ + day10/input.txt.o \ + day10/solution.o