diff --git a/2024/day14/input.txt b/2024/day14/input.txt new file mode 100644 index 0000000..8505c3c --- /dev/null +++ b/2024/day14/input.txt @@ -0,0 +1,500 @@ +p=64,86 v=9,40 +p=82,101 v=51,65 +p=98,58 v=-52,74 +p=63,66 v=-79,-35 +p=21,89 v=-51,83 +p=23,63 v=90,9 +p=93,9 v=14,-12 +p=97,25 v=40,-34 +p=88,81 v=67,41 +p=41,100 v=34,-63 +p=67,88 v=-22,93 +p=63,98 v=29,-20 +p=95,87 v=53,74 +p=81,102 v=-72,40 +p=20,47 v=-72,90 +p=5,44 v=-46,-8 +p=27,41 v=-42,-75 +p=38,96 v=-18,-44 +p=37,82 v=88,-53 +p=80,7 v=92,38 +p=46,20 v=-13,89 +p=87,66 v=87,-74 +p=44,45 v=12,44 +p=60,48 v=-76,-67 +p=83,34 v=29,-85 +p=51,8 v=29,-67 +p=65,37 v=41,-49 +p=89,101 v=-56,40 +p=35,52 v=62,-16 +p=12,80 v=31,79 +p=18,30 v=46,80 +p=47,29 v=67,41 +p=98,43 v=-62,-84 +p=19,77 v=-55,67 +p=92,84 v=55,-71 +p=94,89 v=71,-30 +p=18,95 v=-33,91 +p=64,25 v=9,89 +p=59,12 v=-89,-4 +p=42,18 v=-10,96 +p=74,27 v=-28,29 +p=76,46 v=54,95 +p=63,80 v=-19,41 +p=96,27 v=93,72 +p=3,71 v=9,51 +p=98,17 v=-72,-5 +p=23,5 v=43,39 +p=50,32 v=-51,37 +p=48,39 v=6,-58 +p=100,30 v=96,3 +p=41,16 v=-76,90 +p=82,99 v=10,-99 +p=33,34 v=43,-23 +p=66,26 v=19,-91 +p=24,64 v=-67,-90 +p=59,26 v=25,-23 +p=9,89 v=-8,40 +p=83,21 v=1,-4 +p=22,47 v=14,61 +p=42,88 v=-16,-36 +p=71,73 v=-63,-12 +p=92,43 v=64,95 +p=96,15 v=42,4 +p=17,34 v=52,-83 +p=56,38 v=47,96 +p=73,51 v=-85,69 +p=34,41 v=-63,30 +p=72,92 v=-6,-54 +p=28,99 v=53,15 +p=89,96 v=-44,7 +p=13,63 v=-25,-12 +p=21,30 v=-36,-15 +p=71,9 v=-63,-56 +p=3,4 v=52,91 +p=88,35 v=-84,-91 +p=55,43 v=-48,-23 +p=26,60 v=43,8 +p=71,8 v=-41,39 +p=39,30 v=-26,97 +p=54,36 v=-86,-41 +p=3,40 v=58,-67 +p=26,7 v=-20,-55 +p=62,22 v=-8,-37 +p=53,84 v=-50,-61 +p=67,82 v=97,95 +p=83,8 v=48,-39 +p=0,56 v=1,36 +p=0,76 v=-81,-18 +p=40,58 v=-77,-19 +p=21,12 v=-82,-87 +p=92,74 v=-94,59 +p=71,47 v=-47,-93 +p=21,97 v=-17,-13 +p=43,91 v=37,76 +p=27,70 v=-74,-95 +p=6,76 v=-43,-76 +p=42,64 v=-13,1 +p=36,68 v=-8,81 +p=72,67 v=95,-27 +p=85,77 v=-34,16 +p=9,67 v=71,-25 +p=48,48 v=-91,-6 +p=4,64 v=29,-24 +p=55,62 v=52,-30 +p=8,62 v=-70,-68 +p=26,40 v=-89,4 +p=87,30 v=86,11 +p=56,102 v=85,23 +p=16,44 v=-90,-33 +p=85,31 v=86,-92 +p=70,4 v=-19,-31 +p=83,14 v=20,46 +p=29,66 v=-60,-94 +p=69,19 v=83,81 +p=97,67 v=-59,34 +p=91,10 v=7,13 +p=54,51 v=-95,-51 +p=51,45 v=50,-84 +p=90,22 v=-85,4 +p=54,37 v=91,-32 +p=27,84 v=81,-19 +p=34,27 v=54,40 +p=71,85 v=63,52 +p=54,16 v=-63,71 +p=5,78 v=-93,96 +p=61,31 v=46,57 +p=16,52 v=27,44 +p=11,17 v=-58,-81 +p=67,71 v=-57,9 +p=46,63 v=15,-43 +p=1,48 v=-6,-32 +p=27,75 v=11,77 +p=23,73 v=-45,-43 +p=45,16 v=-92,21 +p=12,75 v=33,-36 +p=6,57 v=52,-68 +p=7,25 v=-78,79 +p=43,18 v=97,-81 +p=77,69 v=13,17 +p=83,102 v=20,91 +p=41,18 v=-76,-75 +p=88,69 v=35,84 +p=60,84 v=-39,30 +p=16,46 v=-93,18 +p=72,91 v=54,-63 +p=39,43 v=-89,-67 +p=100,10 v=80,-13 +p=60,92 v=-29,39 +p=57,26 v=28,-31 +p=43,26 v=-15,15 +p=32,34 v=-87,-63 +p=17,49 v=-73,48 +p=65,69 v=-29,-56 +p=89,81 v=89,-2 +p=58,16 v=-66,20 +p=7,82 v=14,-52 +p=64,19 v=-16,-94 +p=92,33 v=26,-41 +p=63,31 v=79,45 +p=49,92 v=91,-2 +p=59,76 v=-58,-83 +p=90,43 v=-18,18 +p=1,88 v=27,9 +p=91,3 v=-4,-84 +p=34,97 v=-1,-89 +p=14,4 v=-73,-12 +p=59,49 v=-35,87 +p=3,24 v=74,60 +p=93,45 v=61,-16 +p=41,70 v=-76,-70 +p=92,90 v=-14,-46 +p=0,10 v=96,20 +p=90,72 v=-28,-34 +p=21,54 v=-64,-51 +p=62,76 v=96,31 +p=91,96 v=-5,-73 +p=60,23 v=-4,68 +p=30,0 v=-45,-28 +p=95,30 v=-25,-87 +p=75,102 v=-82,51 +p=11,79 v=12,-55 +p=40,82 v=75,-97 +p=26,5 v=8,91 +p=96,63 v=-37,-52 +p=39,50 v=-45,-42 +p=41,6 v=25,21 +p=91,68 v=-44,-43 +p=18,78 v=69,-9 +p=26,51 v=-49,-60 +p=2,1 v=-87,39 +p=95,41 v=-49,-83 +p=99,102 v=58,-90 +p=3,94 v=72,-68 +p=82,89 v=76,24 +p=22,70 v=-38,-96 +p=91,12 v=23,21 +p=72,17 v=-85,46 +p=89,48 v=-2,-32 +p=7,7 v=-65,-4 +p=65,35 v=79,96 +p=98,75 v=-18,-70 +p=88,3 v=52,-6 +p=89,3 v=-24,-5 +p=53,83 v=51,-37 +p=73,40 v=-85,3 +p=64,93 v=-75,-44 +p=68,21 v=-40,-26 +p=69,33 v=-25,-75 +p=54,20 v=-86,-92 +p=70,78 v=-5,32 +p=17,55 v=48,20 +p=25,72 v=75,-62 +p=20,41 v=-25,44 +p=19,18 v=-35,-98 +p=17,90 v=-1,-97 +p=21,11 v=30,-21 +p=90,55 v=4,35 +p=85,4 v=57,74 +p=36,19 v=97,-14 +p=24,0 v=87,-46 +p=23,32 v=84,96 +p=32,1 v=8,64 +p=53,37 v=6,20 +p=26,57 v=-58,-9 +p=25,76 v=-36,-37 +p=83,72 v=-69,34 +p=16,40 v=-97,-56 +p=49,57 v=59,13 +p=13,81 v=49,16 +p=16,6 v=68,5 +p=100,37 v=61,-6 +p=100,79 v=55,93 +p=18,65 v=71,34 +p=25,29 v=-77,-39 +p=43,43 v=81,43 +p=54,39 v=-70,28 +p=97,69 v=-64,-45 +p=94,84 v=-97,24 +p=63,18 v=-98,72 +p=21,26 v=37,-75 +p=8,59 v=-24,-43 +p=29,53 v=-58,-68 +p=48,28 v=50,63 +p=0,22 v=-59,72 +p=5,58 v=-72,-52 +p=41,30 v=53,-6 +p=55,96 v=-22,-7 +p=78,50 v=-69,-67 +p=88,65 v=-94,34 +p=89,45 v=-37,-31 +p=72,68 v=-78,-76 +p=78,93 v=26,58 +p=13,84 v=8,-28 +p=76,24 v=51,-57 +p=2,101 v=-80,52 +p=35,78 v=78,92 +p=33,11 v=21,-90 +p=16,98 v=-43,92 +p=0,35 v=1,54 +p=6,45 v=-90,10 +p=31,58 v=-72,-99 +p=18,25 v=46,-5 +p=89,76 v=25,8 +p=45,40 v=-29,96 +p=91,77 v=-69,4 +p=7,54 v=-55,-28 +p=18,95 v=43,32 +p=28,79 v=-99,75 +p=29,92 v=-18,81 +p=70,8 v=-98,3 +p=72,28 v=9,54 +p=28,6 v=59,99 +p=63,102 v=-79,31 +p=76,32 v=-76,-32 +p=59,1 v=63,-46 +p=96,48 v=39,-50 +p=9,77 v=36,85 +p=86,47 v=-34,-92 +p=2,97 v=-43,-89 +p=92,51 v=-78,-16 +p=63,31 v=19,81 +p=3,72 v=68,16 +p=45,68 v=-28,-91 +p=59,90 v=89,-83 +p=75,7 v=-66,-22 +p=72,18 v=-55,47 +p=27,64 v=24,1 +p=64,55 v=57,-68 +p=72,66 v=19,84 +p=55,4 v=-60,-31 +p=1,39 v=67,-94 +p=84,22 v=4,-84 +p=65,7 v=-44,-98 +p=42,15 v=-99,-56 +p=19,3 v=-55,48 +p=9,18 v=-8,73 +p=54,71 v=47,-43 +p=93,77 v=64,76 +p=53,43 v=82,45 +p=22,0 v=10,47 +p=12,40 v=-99,95 +p=38,8 v=-67,47 +p=47,59 v=-3,31 +p=21,25 v=-58,63 +p=84,87 v=-72,84 +p=62,63 v=-57,7 +p=94,27 v=-62,72 +p=30,6 v=87,23 +p=69,58 v=97,9 +p=76,43 v=-85,-7 +p=76,22 v=62,11 +p=96,20 v=-53,39 +p=97,66 v=68,-63 +p=28,23 v=-32,57 +p=74,24 v=-46,-25 +p=34,82 v=78,-36 +p=48,96 v=-80,26 +p=76,71 v=70,-18 +p=94,23 v=45,-48 +p=47,39 v=-1,-75 +p=89,59 v=15,-63 +p=35,40 v=94,88 +p=14,51 v=86,-37 +p=71,57 v=-42,-86 +p=45,41 v=-20,2 +p=21,65 v=-46,-18 +p=28,77 v=78,-1 +p=78,101 v=13,-3 +p=33,81 v=65,57 +p=20,2 v=49,30 +p=80,73 v=54,-44 +p=25,73 v=-8,26 +p=42,54 v=-10,-16 +p=77,98 v=32,-56 +p=26,83 v=21,32 +p=30,53 v=72,-25 +p=16,53 v=-55,9 +p=68,75 v=34,60 +p=83,77 v=-28,-87 +p=17,55 v=61,-77 +p=91,86 v=-15,66 +p=31,47 v=97,11 +p=60,14 v=51,98 +p=21,40 v=-1,69 +p=26,54 v=-9,58 +p=71,81 v=-94,-95 +p=40,26 v=91,-57 +p=51,19 v=91,98 +p=10,72 v=8,-69 +p=34,40 v=-99,-35 +p=4,94 v=27,57 +p=20,76 v=-23,-95 +p=37,89 v=-7,58 +p=53,100 v=-92,23 +p=92,56 v=-56,-85 +p=38,72 v=-42,-52 +p=100,16 v=-81,-31 +p=57,23 v=-54,-14 +p=32,75 v=81,84 +p=71,61 v=57,-52 +p=46,89 v=97,71 +p=70,85 v=-26,14 +p=80,40 v=4,-73 +p=18,91 v=37,-69 +p=10,61 v=15,65 +p=71,34 v=-50,55 +p=88,2 v=-48,-60 +p=75,51 v=-15,-58 +p=46,98 v=-47,-97 +p=49,20 v=66,81 +p=82,2 v=-54,37 +p=11,83 v=-23,-22 +p=100,9 v=61,30 +p=88,64 v=-78,17 +p=88,13 v=4,81 +p=48,11 v=-62,-29 +p=91,100 v=77,64 +p=62,71 v=16,-69 +p=29,22 v=12,98 +p=7,3 v=55,57 +p=53,14 v=12,56 +p=30,95 v=-11,-79 +p=53,32 v=31,1 +p=84,47 v=-99,-99 +p=99,15 v=49,20 +p=83,89 v=-75,-62 +p=44,77 v=95,-8 +p=38,95 v=94,49 +p=35,4 v=-20,-31 +p=34,12 v=-26,-66 +p=73,102 v=-88,26 +p=58,82 v=28,7 +p=89,44 v=4,70 +p=82,36 v=48,71 +p=44,34 v=21,36 +p=88,82 v=86,-37 +p=70,17 v=-76,-26 +p=79,62 v=-69,-17 +p=71,36 v=-25,2 +p=75,14 v=-25,-73 +p=6,11 v=-27,-89 +p=5,25 v=96,-49 +p=38,33 v=-18,-31 +p=27,86 v=43,-36 +p=93,34 v=57,-39 +p=82,97 v=41,-50 +p=50,37 v=-32,62 +p=10,101 v=93,-29 +p=53,45 v=-45,1 +p=23,6 v=84,89 +p=5,62 v=-5,-51 +p=73,73 v=-44,-78 +p=66,55 v=-26,17 +p=41,26 v=84,-30 +p=23,40 v=-98,39 +p=81,63 v=29,-18 +p=63,100 v=-84,28 +p=76,81 v=79,-46 +p=41,20 v=39,98 +p=75,3 v=95,64 +p=42,74 v=-48,24 +p=93,48 v=-56,-94 +p=32,25 v=15,-73 +p=69,71 v=89,41 +p=8,39 v=13,20 +p=52,43 v=-10,-24 +p=20,26 v=96,64 +p=26,69 v=50,86 +p=98,32 v=-37,-15 +p=27,59 v=-55,-51 +p=8,33 v=36,-5 +p=13,85 v=-43,-12 +p=24,23 v=-55,-92 +p=52,29 v=47,-15 +p=51,77 v=-98,-87 +p=21,48 v=-71,51 +p=34,70 v=59,-87 +p=13,28 v=-36,-45 +p=66,86 v=28,-45 +p=37,83 v=-86,76 +p=61,81 v=-79,-36 +p=42,42 v=-7,87 +p=62,28 v=3,-33 +p=62,61 v=-60,-77 +p=50,45 v=-92,-41 +p=78,6 v=-59,63 +p=37,15 v=75,11 +p=39,76 v=-38,-26 +p=82,82 v=64,-89 +p=84,27 v=-75,97 +p=58,56 v=-82,1 +p=24,57 v=-99,-69 +p=27,43 v=67,43 +p=53,80 v=71,40 +p=30,1 v=90,-11 +p=99,73 v=-24,26 +p=72,56 v=-55,-10 +p=27,69 v=58,-39 +p=60,36 v=31,35 +p=8,99 v=-3,-5 +p=13,75 v=-71,-95 +p=51,86 v=-77,11 +p=40,51 v=-73,-58 +p=63,41 v=-69,19 +p=43,74 v=-80,86 +p=66,2 v=35,14 +p=27,89 v=27,-44 +p=46,77 v=-34,-38 +p=6,80 v=68,-3 +p=70,57 v=-9,59 +p=39,90 v=6,40 +p=79,35 v=35,-66 +p=34,65 v=-58,86 +p=98,54 v=80,-34 +p=14,98 v=8,-29 +p=94,75 v=-59,41 +p=37,59 v=-67,-68 +p=96,100 v=23,-38 +p=38,96 v=99,58 +p=70,47 v=-85,1 +p=46,64 v=-79,52 +p=7,10 v=14,65 +p=29,43 v=-39,71 +p=37,53 v=-90,92 +p=64,6 v=38,-21 +p=1,7 v=45,52 +p=39,85 v=24,92 +p=62,49 v=82,10 +p=17,72 v=-84,-19 +p=6,94 v=-37,66 +p=54,52 v=96,-66 +p=85,90 v=91,-20 +p=13,84 v=-66,-26 +p=7,29 v=82,69 +p=82,78 v=67,48 +p=90,85 v=-47,-27 +p=9,37 v=-59,-33 +p=83,0 v=29,-29 +p=21,16 v=-74,-40 +p=70,53 v=66,53 diff --git a/2024/day14/input.txt.h b/2024/day14/input.txt.h new file mode 100644 index 0000000..2e1713f --- /dev/null +++ b/2024/day14/input.txt.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_2024_day14_input_txt_start __asm("_binary_2024_day14_input_txt_start"); +extern uint32_t _binary_2024_day14_input_txt_end __asm("_binary_2024_day14_input_txt_end"); +extern uint32_t _binary_2024_day14_input_txt_size __asm("_binary_2024_day14_input_txt_size"); + +#ifdef __cplusplus +} +#endif diff --git a/2024/day14/render.cpp b/2024/day14/render.cpp new file mode 100644 index 0000000..a7e80ff --- /dev/null +++ b/2024/day14/render.cpp @@ -0,0 +1,199 @@ +#include "holly/isp_tsp.hpp" +#include "holly/ta_parameter.hpp" +#include "holly/ta_global_parameter.hpp" +#include "holly/ta_vertex_parameter.hpp" + +#include "sh7091/store_queue.hpp" +#include "sh7091/serial.hpp" + +#include "math/vec2.hpp" +#include "font/font.h" +#include "maple/maple_bus_ft0.hpp" + +#include "unparse.h" +#include "solution.h" + +extern void glyph_start(const uint32_t texture_width, uint32_t texture_height); +extern int32_t transform_char(const uint32_t texture_width, + const uint32_t texture_height, + const uint32_t first_char_code, + const glyph * glyphs, + const char c, + int32_t horizontal_advance, + int32_t vertical_advance, + uint32_t base_color = 0xffffffff); + +using vec2 = vec<2, float>; + +constexpr vec2 square_vertices[] = { + {0.0, 4.0}, + {0.0, 0.0}, + {4.0, 4.0}, + {4.0, 0.0}, +}; + +static void polygon_start() +{ + const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume + | para_control::list_type::translucent + | obj_control::col_type::packed_color; + + const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::always + | isp_tsp_instruction_word::culling_mode::no_culling; + + const uint32_t tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one + | tsp_instruction_word::dst_alpha_instr::zero + | tsp_instruction_word::fog_control::no_fog; + + *reinterpret_cast(store_queue) = + ta_global_parameter::polygon_type_0(parameter_control_word, + isp_tsp_instruction_word, + tsp_instruction_word, + 0, // texture_control_word + 0, // data_size_for_sort_dma + 0 // next_address_for_sort_dma + ); + sq_transfer_32byte(ta_fifo_polygon_converter); +} + +static void draw_robot(int cx, int cy, uint32_t base_color) +{ + float z = 1.0 / 10.0; + + for (int i = 0; i < 4; i++) { + bool end_of_strip = i == 3; + vec2 v = square_vertices[i]; + + v.x += 118 + 4 * cx; + v.y += 34 + 4 * cy; + + *reinterpret_cast(store_queue) = + ta_vertex_parameter::polygon_type_0(polygon_vertex_parameter_control_word(end_of_strip), + v.x, v.y, z, + base_color); + sq_transfer_32byte(ta_fifo_polygon_converter); + } +} + +static void draw_time(const struct font * font, + const struct glyph * glyphs) +{ + int32_t horizontal_advance = 250 << 6; + int32_t vertical_advance = font->face_metrics.height; + + { + char time[64] = "time: "; + int ix = 6; + ix += unparse_base10(&time[ix], _2024_day14_state.time, 0, 0); + + for (int i = 0; i < ix; i++) { + char c = time[i]; + horizontal_advance += transform_char(font->texture_width, + font->texture_height, + font->first_char_code, + glyphs, + c, + horizontal_advance, + vertical_advance); + } + } + + { + horizontal_advance = (450 << 6); + char max_size[64] = "max_size: "; + int ix = 10; + ix += unparse_base10(&max_size[ix], _2024_day14_state.max_size, 0, 0); + + for (int i = 0; i < ix; i++) { + char c = max_size[i]; + horizontal_advance += transform_char(font->texture_width, + font->texture_height, + font->first_char_code, + glyphs, + c, + horizontal_advance, + vertical_advance); + } + } +} + +static void draw_christmas(const struct font * font, + const struct glyph * glyphs, + uint32_t base_color, + int x) +{ + int32_t horizontal_advance = (x << 6) + font->face_metrics.max_advance / 2; + int32_t vertical_advance = (480 << 6) - (font->face_metrics.height / 2); + + char max_size[64] = "christmas detected"; + + for (int i = 0; i < 18; i++) { + char c = max_size[i]; + horizontal_advance += transform_char(font->texture_width, + font->texture_height, + font->first_char_code, + glyphs, + c, + horizontal_advance, + vertical_advance, + base_color); + } +} + +extern "C" +void _2024_day14_render(const struct font * font, + const struct glyph * glyphs, + ft0::data_transfer::data_format * maple_ft0_data) +{ + static int frame = 0; + + frame += 1; + + static bool last_a = true; + static bool last_b = true; + + if (maple_ft0_data[0].digital_button != 0) { + bool a = ft0::data_transfer::digital_button::a(maple_ft0_data[0].digital_button) == 0; + bool b = ft0::data_transfer::digital_button::b(maple_ft0_data[0].digital_button) == 0; + if (a && !last_a) { + _2024_day14_state.step = 1; + } + if (b && !last_b) { + _2024_day14_state.step = -1; + } + last_a = a; + last_b = b; + } + + polygon_start(); + + uint32_t red_and_green[2] = { + 0xffff0000, + 0xff00ff00, + }; + + uint32_t base_color = 0xff00ffff; + uint32_t font_color = 0xffffffff; + if (_2024_day14_state.step == 0 && _2024_day14_state.max_size > 200) { + int robot_ix = (frame / 60) % 2; + base_color = red_and_green[robot_ix]; + font_color = red_and_green[(robot_ix + 1) % 2]; + } + + for (int i = 0; i < _2024_day14_state.robot_length; i++) { + struct robot * robot = &_2024_day14_state.robot[i]; + draw_robot(robot->x, robot->y, base_color); + } + + glyph_start(font->texture_width, font->texture_height); + + draw_time(font, + glyphs); + + if (font_color != 0xffffffff) { + draw_christmas(font, glyphs, + font_color, 50); + draw_christmas(font, glyphs, + font_color, 350); + } +} diff --git a/2024/day14/sample1.txt b/2024/day14/sample1.txt new file mode 100644 index 0000000..2455da4 --- /dev/null +++ b/2024/day14/sample1.txt @@ -0,0 +1,12 @@ +p=0,4 v=3,-3 +p=6,3 v=-1,-3 +p=10,3 v=-1,2 +p=2,0 v=2,-1 +p=0,0 v=1,3 +p=3,0 v=-2,-2 +p=7,6 v=-1,-3 +p=3,0 v=-1,-2 +p=9,3 v=2,3 +p=7,3 v=-1,2 +p=2,4 v=2,-3 +p=9,5 v=-3,-3 diff --git a/2024/day14/sample1.txt.h b/2024/day14/sample1.txt.h new file mode 100644 index 0000000..d68dd83 --- /dev/null +++ b/2024/day14/sample1.txt.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_2024_day14_sample1_txt_start __asm("_binary_2024_day14_sample1_txt_start"); +extern uint32_t _binary_2024_day14_sample1_txt_end __asm("_binary_2024_day14_sample1_txt_end"); +extern uint32_t _binary_2024_day14_sample1_txt_size __asm("_binary_2024_day14_sample1_txt_size"); + +#ifdef __cplusplus +} +#endif diff --git a/2024/day14/solution.c b/2024/day14/solution.c new file mode 100644 index 0000000..be0910c --- /dev/null +++ b/2024/day14/solution.c @@ -0,0 +1,169 @@ +#include + +#include "parse.h" +#include "printf.h" +#include "memory.h" + +#include "solution.h" +#include "cartesian.h" + +struct solution_state _2024_day14_state = {0}; + +const char * parse_robot(const char * input, struct robot * robot) +{ + input = parse_match(input, "p="); + input = parse_base10(input, &robot->x); + input = parse_skip(input, ','); + input = parse_base10(input, &robot->y); + input = parse_match(input, " v="); + input = parse_base10(input, &robot->dx); + input = parse_skip(input, ','); + input = parse_base10(input, &robot->dy); + input = parse_skip(input, '\n'); + return input; +} + +static inline int positive_modulus(int n, int d) { + return (n % d + d) % d; +} + +void simulate_robot(struct robot * robot, + int width, int height, + int steps) +{ + int x = robot->x + robot->dx * steps; + robot->x = positive_modulus(x, width); + + int y = robot->y + robot->dy * steps; + robot->y = positive_modulus(y, height); +} + +static int xy_to_quadrant(int x, int y, int width, int height) +{ + int midx = width / 2; + int midy = height / 2; + + if (x == midx || y == midy) + return -1; + + return + (0b01 * (x > midx)) | + (0b10 * (y > midy)); +} + + +static int flood_fill(char * visited, + int width, int height, + int x, int y) +{ + int size = 1; + + visited[y * width + x] = 0; + + for (int i = 0; i < cartesian_neighbor_count; i++) { + int nx = x + cartesian_neighbor[i].x; + int ny = y + cartesian_neighbor[i].y; + + char nc = visited[ny * width + nx]; + + if (cartesian_inside(width, height, nx, ny) && nc != 0) { + size += flood_fill(visited, + width, height, + nx, ny); + } + } + + return size; +} + +int64_t _2024_day14_part1(const char * input, int length) +{ + const char * end = input + length; + + //int width = 11; + //int height = 7; + int width = 101; + int height = 103; + int steps = 100; + + int quadrant[4]; + memory_set_int(quadrant, 0, 4); + + while (input < end) { + struct robot robot; + + input = parse_robot(input, &robot); + simulate_robot(&robot, width, height, steps); + + int ix = xy_to_quadrant(robot.x, robot.y, width, height); + if (ix >= 0) + quadrant[ix] += 1; + } + + int sum = quadrant[0]; + for (int i = 1; i < 4; i++) + sum *= quadrant[i]; + + return sum; +} + +int64_t _2024_day14_part2(const char * input, int length) +{ + const char * end = input + length; + + //int width = 11; + //int height = 7; + int width = 101; + int height = 103; + + int robot_length = parse_height(input, length); + struct robot robot[robot_length]; + + _2024_day14_state.time = 0; + _2024_day14_state.robot = &robot[0]; + _2024_day14_state.robot_length = robot_length; + + int i = 0; + while (input < end) { + input = parse_robot(input, &robot[i++]); + } + + _2024_day14_state.time = 0; + + char visited[width * height]; + + int max_size = 0; + _2024_day14_state.max_size = max_size; + + while (max_size < 200) { + int step = _2024_day14_state.step; + if (step == 0) + continue; + + _2024_day14_state.time += step; + + memory_set_char(visited, 0, width * height); + + for (int i = 0; i < robot_length; i++) { + simulate_robot(&robot[i], width, height, step); + visited[robot[i].y * width + robot[i].x] = 1; + } + + for (int i = 0; i < robot_length; i++) { + if (visited[robot[i].y * width + robot[i].x]) { + int size = flood_fill(visited, + width, height, + robot[i].x, robot[i].y); + _2024_day14_state.size = size; + if (size > max_size) { + max_size = size; + _2024_day14_state.max_size = max_size; + } + if (size > 200) + _2024_day14_state.step = 0; + } + } + } + + return _2024_day14_state.time; +} diff --git a/2024/day14/solution.h b/2024/day14/solution.h new file mode 100644 index 0000000..ac75457 --- /dev/null +++ b/2024/day14/solution.h @@ -0,0 +1,27 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +struct robot { + int x; + int y; + int dx; + int dy; +}; + +struct solution_state { + int step; + int time; + int max_size; + int size; + struct robot * robot; + int robot_length; +}; + +extern struct solution_state _2024_day14_state; + +#ifdef __cplusplus +} +#endif diff --git a/2024/day6/render.cpp b/2024/day6/render.cpp index 7726114..1b2d202 100644 --- a/2024/day6/render.cpp +++ b/2024/day6/render.cpp @@ -19,7 +19,8 @@ extern int32_t transform_char(const uint32_t texture_width, const glyph * glyphs, const char c, int32_t horizontal_advance, - int32_t vertical_advance); + int32_t vertical_advance, + uint32_t base_color = 0xffffffff); using vec2 = vec<2, float>; @@ -36,7 +37,7 @@ constexpr vec2 square_vertices[] = { {0.525, 0.475}, }; -vec2 rotate(vec2 v, int n) { +static vec2 rotate(vec2 v, int n) { switch (n) { case 0: return {v.x, v.y}; case 1: return {-v.y, v.x}; @@ -46,7 +47,7 @@ vec2 rotate(vec2 v, int n) { __builtin_unreachable(); } -void polygon_start() +static void polygon_start() { const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume | para_control::list_type::translucent @@ -72,7 +73,7 @@ void polygon_start() constexpr int scale = 45; -void arrow(int cx, int cy, int rotation, uint32_t base_color) +static void arrow(int cx, int cy, int rotation, uint32_t base_color) { float z = 1.0 / 10.0; @@ -95,7 +96,7 @@ void arrow(int cx, int cy, int rotation, uint32_t base_color) } } -void border(int cx, int cy, int rotation) +static void border(int cx, int cy, int rotation) { uint32_t base_color = 0xff'ff00ff; float z = 1.0 / 10.0; @@ -119,10 +120,10 @@ void border(int cx, int cy, int rotation) } } -void glyph(const struct font * font, - const struct glyph * glyphs, - int cx, int cy, - char c) +static void glyph(const struct font * font, + const struct glyph * glyphs, + int cx, int cy, + char c) { int32_t horizontal_advance = font->face_metrics.max_advance * 2 / 5; // 26.6 fixed point int32_t vertical_advance = font->face_metrics.height * 5 / 4; // 26.6 fixed point @@ -144,7 +145,7 @@ void glyph(const struct font * font, extern "C" struct solution_state day6_state; -void a_press() +static void a_press() { serial::string("press\n"); serial::integer(day6_state.part); diff --git a/input_dreamcast.inc b/input_dreamcast.inc index c5652e9..5cd7ca6 100644 --- a/input_dreamcast.inc +++ b/input_dreamcast.inc @@ -35,6 +35,8 @@ #include "2024/day12/input.txt.h" #include "2024/day13/sample1.txt.h" #include "2024/day13/input.txt.h" +#include "2024/day14/sample1.txt.h" +#include "2024/day14/input.txt.h" static struct start_size sample[][2] = { { @@ -139,6 +141,12 @@ static struct start_size sample[][2] = { { ( char *)&_binary_2024_day13_sample1_txt_start, (uint32_t)&_binary_2024_day13_sample1_txt_size }, }, + { + { ( char *)&_binary_2024_day14_sample1_txt_start, + (uint32_t)&_binary_2024_day14_sample1_txt_size }, + { ( char *)&_binary_2024_day14_sample1_txt_start, + (uint32_t)&_binary_2024_day14_sample1_txt_size }, + }, }; static struct start_size input[] = { @@ -176,4 +184,6 @@ static struct start_size input[] = { (uint32_t)&_binary_2024_day12_input_txt_size }, { ( char *)&_binary_2024_day13_input_txt_start, (uint32_t)&_binary_2024_day13_input_txt_size }, + { ( char *)&_binary_2024_day14_input_txt_start, + (uint32_t)&_binary_2024_day14_input_txt_size }, }; diff --git a/runner.c b/runner.c index aafa3ad..9db869b 100644 --- a/runner.c +++ b/runner.c @@ -38,11 +38,12 @@ bool runner_tick(struct runner_state * runner_state) int year = solution[ix].year; int day = solution[ix].day; - if (year != 2024 || day != 13) { + if (year != 2024 || day != 14) { return false; } runner_state->want_render = solution[ix].render != NULL; + //printf("want_render %d\n", runner_state->want_render); char * buf; int length; @@ -60,12 +61,14 @@ void runner_render(struct runner_state * runner_state, const struct glyph * glyphs, const void * maple_ft0_data) { - int day = runner_state->tick / 2; + int tick = (solution_ticks - 1) - runner_state->tick; + int ix = tick / 2; - if (day >= solution_days) { + if (tick < 0) { return; } - if (solution[day].render != NULL) { - solution[day].render(font, glyphs, maple_ft0_data); + + if (solution[ix].render != NULL) { + solution[ix].render(font, glyphs, maple_ft0_data); } } diff --git a/runner.inc b/runner.inc index a6ac2dd..6e8b4dc 100644 --- a/runner.inc +++ b/runner.inc @@ -35,6 +35,11 @@ int64_t _2024_day12_part1(const char * input, int length); int64_t _2024_day12_part2(const char * input, int length); int64_t _2024_day13_part1(const char * input, int length); int64_t _2024_day13_part2(const char * input, int length); +int64_t _2024_day14_part1(const char * input, int length); +int64_t _2024_day14_part2(const char * input, int length); +void _2024_day14_render(const struct font * font, + const struct glyph * glyphs, + const void * maple_ft0_data); struct day_funcs solution[] = { { @@ -122,4 +127,9 @@ struct day_funcs solution[] = { {_2024_day13_part1, _2024_day13_part2}, NULL, }, + { + 2024, 14, + {_2024_day14_part1, _2024_day14_part2}, + _2024_day14_render, + }, }; diff --git a/runner_dreamcast.cpp b/runner_dreamcast.cpp index 1fe2b6d..a2aed01 100644 --- a/runner_dreamcast.cpp +++ b/runner_dreamcast.cpp @@ -105,7 +105,7 @@ const struct vertex strip_vertices[4] = { constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex)); -void glyph_start(const uint32_t texture_width, uint32_t texture_height) +void glyph_start(const uint32_t texture_width, const uint32_t texture_height) { const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume | para_control::list_type::translucent @@ -119,6 +119,7 @@ void glyph_start(const uint32_t texture_width, uint32_t texture_height) | tsp_instruction_word::dst_alpha_instr::one | tsp_instruction_word::fog_control::no_fog | tsp_instruction_word::use_alpha + | tsp_instruction_word::texture_shading_instruction::modulate | tsp_instruction_word::texture_u_size::from_int(texture_width) | tsp_instruction_word::texture_v_size::from_int(texture_height); @@ -144,7 +145,8 @@ int32_t transform_char(const uint32_t texture_width, const glyph * glyphs, const char c, int32_t horizontal_advance, - int32_t vertical_advance) + int32_t vertical_advance, + uint32_t base_color = 0xffffffff) { auto& glyph = glyphs[c - first_char_code]; @@ -173,7 +175,7 @@ int32_t transform_char(const uint32_t texture_width, ta_vertex_parameter::polygon_type_3(polygon_vertex_parameter_control_word(end_of_strip), x, y, z, u, v, - 0, // base_color + base_color, // base_color 0 // offset_color ); sq_transfer_32byte(ta_fifo_polygon_converter); diff --git a/solutions.mk b/solutions.mk index 487ecb8..ebf0c7a 100644 --- a/solutions.mk +++ b/solutions.mk @@ -53,4 +53,8 @@ DAY_OBJ = \ 2024/day12/solution.o \ 2024/day13/sample1.txt.o \ 2024/day13/input.txt.o \ - 2024/day13/solution.o + 2024/day13/solution.o \ + 2024/day14/sample1.txt.o \ + 2024/day14/input.txt.o \ + 2024/day14/render.o \ + 2024/day14/solution.o