diff --git a/Makefile b/Makefile index dc6043e..195aed7 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,6 @@ CFLAGS += -Wno-error=unused-variable CFLAGS += -I$(MAKEFILE_PATH)/include CFLAGS += -I$(MAKEFILE_PATH) CXXFLAGS += -fno-exceptions -#CFLAGS += -DDEBUG_BUTTONS -#CFLAGS += -DDEBUG_AXES LDFLAGS += -nostdlib++ -lm -static-libgcc ifeq ($(OS),Windows_NT) LDFLAGS += -Wl,--subsystem,windows -mwindows @@ -136,8 +134,11 @@ shaders: $(SHADER_HEADERS) INPUTS = $(shell find puzzle/ -type f -name input) INPUT_OBJS = $(patsubst %,%.o,$(INPUTS)) +INPUT_HEADERS = $(patsubst %,%.h,$(INPUTS)) -SOLUTIONS = $(shell find src/solution/2025/ -type f -name '*.c') +inputs: $(INPUT_HEADERS) + +SOLUTIONS = $(shell find src/solution/ -type f -name '*.c') SOLUTION_OBJS = $(patsubst %.c,%.o,$(SOLUTIONS)) MAIN_OBJS = \ @@ -150,7 +151,7 @@ MAIN_OBJS = \ $(SOLUTION_OBJS) \ $(GLFW) -main: $(MAIN_OBJS) | shaders +main: $(MAIN_OBJS) | shaders inputs $(CXX) $^ $(CXXFLAGS) $(ARCH) -o $@ $(LDFLAGS) #-include $(shell find -type f -name 'src/*.d') diff --git a/include/solution/2025/03/solution.fs.glsl.h b/include/solution/2025/03/solution.fs.glsl.h new file mode 100644 index 0000000..722b1f9 --- /dev/null +++ b/include/solution/2025/03/solution.fs.glsl.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_src_solution_2025_03_solution_fs_glsl_start __asm("_binary_src_solution_2025_03_solution_fs_glsl_start"); +extern uint32_t _binary_src_solution_2025_03_solution_fs_glsl_end __asm("_binary_src_solution_2025_03_solution_fs_glsl_end"); +extern uint32_t _binary_src_solution_2025_03_solution_fs_glsl_size __asm("_binary_src_solution_2025_03_solution_fs_glsl_size"); + +#define src_solution_2025_03_solution_fs_glsl_start ((const char *)&_binary_src_solution_2025_03_solution_fs_glsl_start) +#define src_solution_2025_03_solution_fs_glsl_end ((const char *)&_binary_src_solution_2025_03_solution_fs_glsl_end) +#define src_solution_2025_03_solution_fs_glsl_size (src_solution_2025_03_solution_fs_glsl_end - src_solution_2025_03_solution_fs_glsl_start) + +#ifdef __cplusplus +} +#endif diff --git a/include/solution/generic.vs.glsl.h b/include/solution/generic.vs.glsl.h new file mode 100644 index 0000000..6f1461e --- /dev/null +++ b/include/solution/generic.vs.glsl.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_src_solution_generic_vs_glsl_start __asm("_binary_src_solution_generic_vs_glsl_start"); +extern uint32_t _binary_src_solution_generic_vs_glsl_end __asm("_binary_src_solution_generic_vs_glsl_end"); +extern uint32_t _binary_src_solution_generic_vs_glsl_size __asm("_binary_src_solution_generic_vs_glsl_size"); + +#define src_solution_generic_vs_glsl_start ((const char *)&_binary_src_solution_generic_vs_glsl_start) +#define src_solution_generic_vs_glsl_end ((const char *)&_binary_src_solution_generic_vs_glsl_end) +#define src_solution_generic_vs_glsl_size (src_solution_generic_vs_glsl_end - src_solution_generic_vs_glsl_start) + +#ifdef __cplusplus +} +#endif diff --git a/puzzle/2025/02/input.h b/puzzle/2025/02/input.h new file mode 100644 index 0000000..ccca0f7 --- /dev/null +++ b/puzzle/2025/02/input.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_puzzle_2025_02_input_start __asm("_binary_puzzle_2025_02_input_start"); +extern uint32_t _binary_puzzle_2025_02_input_end __asm("_binary_puzzle_2025_02_input_end"); +extern uint32_t _binary_puzzle_2025_02_input_size __asm("_binary_puzzle_2025_02_input_size"); + +#define puzzle_2025_02_input_start ((const char *)&_binary_puzzle_2025_02_input_start) +#define puzzle_2025_02_input_end ((const char *)&_binary_puzzle_2025_02_input_end) +#define puzzle_2025_02_input_size (puzzle_2025_02_input_end - puzzle_2025_02_input_start) + +#ifdef __cplusplus +} +#endif diff --git a/puzzle/2025/03/input.h b/puzzle/2025/03/input.h new file mode 100644 index 0000000..abcdf1d --- /dev/null +++ b/puzzle/2025/03/input.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_puzzle_2025_03_input_start __asm("_binary_puzzle_2025_03_input_start"); +extern uint32_t _binary_puzzle_2025_03_input_end __asm("_binary_puzzle_2025_03_input_end"); +extern uint32_t _binary_puzzle_2025_03_input_size __asm("_binary_puzzle_2025_03_input_size"); + +#define puzzle_2025_03_input_start ((const char *)&_binary_puzzle_2025_03_input_start) +#define puzzle_2025_03_input_end ((const char *)&_binary_puzzle_2025_03_input_end) +#define puzzle_2025_03_input_size (puzzle_2025_03_input_end - puzzle_2025_03_input_start) + +#ifdef __cplusplus +} +#endif diff --git a/puzzle/2025/04/input.h b/puzzle/2025/04/input.h new file mode 100644 index 0000000..ea6dfc9 --- /dev/null +++ b/puzzle/2025/04/input.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_puzzle_2025_04_input_start __asm("_binary_puzzle_2025_04_input_start"); +extern uint32_t _binary_puzzle_2025_04_input_end __asm("_binary_puzzle_2025_04_input_end"); +extern uint32_t _binary_puzzle_2025_04_input_size __asm("_binary_puzzle_2025_04_input_size"); + +#define puzzle_2025_04_input_start ((const char *)&_binary_puzzle_2025_04_input_start) +#define puzzle_2025_04_input_end ((const char *)&_binary_puzzle_2025_04_input_end) +#define puzzle_2025_04_input_size (puzzle_2025_04_input_end - puzzle_2025_04_input_start) + +#ifdef __cplusplus +} +#endif diff --git a/puzzle/2025/05/input.h b/puzzle/2025/05/input.h new file mode 100644 index 0000000..4bcbfc4 --- /dev/null +++ b/puzzle/2025/05/input.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_puzzle_2025_05_input_start __asm("_binary_puzzle_2025_05_input_start"); +extern uint32_t _binary_puzzle_2025_05_input_end __asm("_binary_puzzle_2025_05_input_end"); +extern uint32_t _binary_puzzle_2025_05_input_size __asm("_binary_puzzle_2025_05_input_size"); + +#define puzzle_2025_05_input_start ((const char *)&_binary_puzzle_2025_05_input_start) +#define puzzle_2025_05_input_end ((const char *)&_binary_puzzle_2025_05_input_end) +#define puzzle_2025_05_input_size (puzzle_2025_05_input_end - puzzle_2025_05_input_start) + +#ifdef __cplusplus +} +#endif diff --git a/puzzle/2025/06/input.h b/puzzle/2025/06/input.h new file mode 100644 index 0000000..d419a18 --- /dev/null +++ b/puzzle/2025/06/input.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_puzzle_2025_06_input_start __asm("_binary_puzzle_2025_06_input_start"); +extern uint32_t _binary_puzzle_2025_06_input_end __asm("_binary_puzzle_2025_06_input_end"); +extern uint32_t _binary_puzzle_2025_06_input_size __asm("_binary_puzzle_2025_06_input_size"); + +#define puzzle_2025_06_input_start ((const char *)&_binary_puzzle_2025_06_input_start) +#define puzzle_2025_06_input_end ((const char *)&_binary_puzzle_2025_06_input_end) +#define puzzle_2025_06_input_size (puzzle_2025_06_input_end - puzzle_2025_06_input_start) + +#ifdef __cplusplus +} +#endif diff --git a/puzzle/2025/07/input.h b/puzzle/2025/07/input.h new file mode 100644 index 0000000..6d17278 --- /dev/null +++ b/puzzle/2025/07/input.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t _binary_puzzle_2025_07_input_start __asm("_binary_puzzle_2025_07_input_start"); +extern uint32_t _binary_puzzle_2025_07_input_end __asm("_binary_puzzle_2025_07_input_end"); +extern uint32_t _binary_puzzle_2025_07_input_size __asm("_binary_puzzle_2025_07_input_size"); + +#define puzzle_2025_07_input_start ((const char *)&_binary_puzzle_2025_07_input_start) +#define puzzle_2025_07_input_end ((const char *)&_binary_puzzle_2025_07_input_end) +#define puzzle_2025_07_input_size (puzzle_2025_07_input_end - puzzle_2025_07_input_start) + +#ifdef __cplusplus +} +#endif diff --git a/src/main.c b/src/main.c index 9e243ad..1ff091d 100644 --- a/src/main.c +++ b/src/main.c @@ -28,6 +28,7 @@ const float triangle_array[] = { }; extern void solution_2025_01(unsigned int vertex_array); +extern void solution_2025_03(unsigned int vertex_array); int main() { @@ -86,7 +87,8 @@ int main() if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); - solution_2025_01(vertex_array); + //solution_2025_01(vertex_array); + solution_2025_03(vertex_array); break; diff --git a/src/solution/2025/01/solution.c b/src/solution/2025/01/solution.c index f44e155..8d1feaf 100644 --- a/src/solution/2025/01/solution.c +++ b/src/solution/2025/01/solution.c @@ -5,11 +5,11 @@ #include "opengl.h" #include "puzzle/2025/01/input.h" -#include "solution/2025/01/solution.vs.glsl.h" +#include "solution/generic.vs.glsl.h" #include "solution/2025/01/solution.fs.glsl.h" -const int output_width = 1; -const int output_height = 1; +static const int output_width = 1; +static const int output_height = 1; void solution_2025_01(unsigned int vertex_array) { @@ -38,8 +38,8 @@ void solution_2025_01(unsigned int vertex_array) // shaders ////////////////////////////////////////////////////////////////////// - uint program = compile_shader(src_solution_2025_01_solution_vs_glsl_start, - src_solution_2025_01_solution_vs_glsl_size, + uint program = compile_shader(src_solution_generic_vs_glsl_start, + src_solution_generic_vs_glsl_size, src_solution_2025_01_solution_fs_glsl_start, src_solution_2025_01_solution_fs_glsl_size); uint program__input_sampler = glGetUniformLocation(program, "input_sampler"); diff --git a/src/solution/2025/03/parse_input.fs.glsl b/src/solution/2025/03/parse_input.fs.glsl index 7fd4633..fec9d31 100644 --- a/src/solution/2025/03/parse_input.fs.glsl +++ b/src/solution/2025/03/parse_input.fs.glsl @@ -1,34 +1,68 @@ #version 330 core -uniform vec4 in_size; // w h halfpx_w halfpx_h -uniform vec4 out_size; // w h halfpx_w halfpx_h +uniform sampler2D input_sampler; +uniform vec4 input_dim; // w h halfpx_w halfpx_h +uniform float input_length; + +uniform vec4 output_dim; // w h halfpx_w halfpx_h out vec4 fragment_result; in vec2 f_position; -vec2 halfpixel(float x, float y, vec4 size) +vec2 halfpixel(float x, float y, vec4 dim) { - return vec2((x * 2.0 + 1) * size.z, - (y * 2.0 + 1) * size.w); + return vec2((x * 2.0 + 1.0) * dim.z, + (y * 2.0 + 1.0) * dim.w); } -vec2 rectangularize(float ix, vec4 size) +vec2 rectangularize(float ix, vec4 dim) { - float y = floor(ix * size.z * 2.0); - float x = ix - size.x * y; + float y = floor(ix * dim.z * 2.0); + float x = ix - dim.x * y; - return halfpixel(x, y, size); + return halfpixel(x, y, dim); } float get_input(float ix) { - return texture(tex_sampler, rectangularize(ix, in_size)).x * 255.0; + return texture(input_sampler, rectangularize(ix, input_dim)).x * 255.0; } -void main() +vec2 integer_coord(vec2 v, vec4 dim) +{ + return ((v * 0.5 + 0.5) - dim.zw) * dim.xy; +} + +const float ascii_newline = 10.0; +const float ascii_zero = 48.0; + +float find_character(vec2 v) { float x = 0.0; float y = 0.0; float ix = 0.0; + + while (ix < input_length) { + float c = get_input(ix); + if (x == v.x && y == v.y) + return c - ascii_zero; + if (c == ascii_newline) { + x = 0.0; + y += 1.0; + } else { + x += 1.0; + } + ix += 1.0; + } + + return -1.0; +} + +void main() +{ + vec2 v = integer_coord(f_position, output_dim); + + //fragment_result = vec4(v, 0, 0); + fragment_result = vec4(find_character(v)); } diff --git a/src/solution/2025/03/solution.c b/src/solution/2025/03/solution.c new file mode 100644 index 0000000..c46df61 --- /dev/null +++ b/src/solution/2025/03/solution.c @@ -0,0 +1,164 @@ +#include + +#include "glad.h" +#include "input.h" +#include "opengl.h" + +#include "puzzle/2025/03/input.h" +#include "solution/generic.vs.glsl.h" +#include "solution/2025/03/parse_input.fs.glsl.h" +#include "solution/2025/03/solution.fs.glsl.h" + +static const int output_width = 1; +static const int output_height = 1; + +static const int parsed_input_width = 128; +static const int parsed_input_height = 256; + +void solution_2025_03(unsigned int vertex_array) +{ + ////////////////////////////////////////////////////////////////////// + // textures + ////////////////////////////////////////////////////////////////////// + + const char * input_start = puzzle_2025_03_input_start; + const int input_length = puzzle_2025_03_input_size; + int input_width; + uint texture_input = rectangularize_input(input_start, + input_length, + &input_width); + int input_height = input_width; + + uint texture_parsed_input = make_texture(NULL, + GL_R32F, + parsed_input_width, + parsed_input_height, + GL_RED, + GL_UNSIGNED_BYTE); + uint framebuffer_parsed_input = make_framebuffer(&texture_parsed_input, 1); + + + uint texture_output = make_texture(NULL, + GL_RGB32F, + output_width, + output_height, + GL_RGB, + GL_UNSIGNED_BYTE); + uint framebuffer_output = make_framebuffer(&texture_output, 1); + + ////////////////////////////////////////////////////////////////////// + // shaders + ////////////////////////////////////////////////////////////////////// + + uint p__parse_input = compile_shader(src_solution_generic_vs_glsl_start, + src_solution_generic_vs_glsl_size, + src_solution_2025_03_parse_input_fs_glsl_start, + src_solution_2025_03_parse_input_fs_glsl_size); + uint p__parse_input__input_sampler = glGetUniformLocation(p__parse_input, "input_sampler"); + uint p__parse_input__input_dim = glGetUniformLocation(p__parse_input, "input_dim"); + uint p__parse_input__input_length = glGetUniformLocation(p__parse_input, "input_length"); + uint p__parse_input__output_dim = glGetUniformLocation(p__parse_input, "output_dim"); + + uint p__solution = compile_shader(src_solution_generic_vs_glsl_start, + src_solution_generic_vs_glsl_size, + src_solution_2025_03_solution_fs_glsl_start, + src_solution_2025_03_solution_fs_glsl_size); + uint p__solution__input_sampler = glGetUniformLocation(p__solution, "input_sampler"); + uint p__solution__input_dim = glGetUniformLocation(p__solution, "input_dim"); + uint p__solution__input_length = glGetUniformLocation(p__solution, "input_length"); + + ////////////////////////////////////////////////////////////////////// + // runner step 1: parse input + ////////////////////////////////////////////////////////////////////// + + // shader uniforms + + glUseProgram(p__parse_input); + glUniform1i(p__parse_input__input_sampler, 0); + glUniform4f(p__parse_input__input_dim, + input_width, + input_height, + 0.5f / input_width, + 0.5f / input_height); + glUniform1f(p__parse_input__input_length, input_length); + + glUniform4f(p__parse_input__output_dim, + parsed_input_width, + parsed_input_height, + 0.5f / parsed_input_width, + 0.5f / parsed_input_height); + + // draw + + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_parsed_input); + glViewport(0, 0, parsed_input_width, parsed_input_height); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_input); + const uint draw_buffers0[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, draw_buffers0); + + glBindVertexArray(vertex_array); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + // debug + + if (1) { + float out[1 * parsed_input_width * parsed_input_height] = {}; + glReadPixels(0, 0, + parsed_input_width, parsed_input_height, + GL_RED, + GL_FLOAT, + out); + + for (int y = 0; y < parsed_input_height; y++) { + for (int x = 0; x < parsed_input_width; x++) { + printf("%d", (int)out[(y * parsed_input_width + x) * 1 + 0]); + } + printf("\n"); + break; + } + } + + ////////////////////////////////////////////////////////////////////// + // runner step 2: solve + ////////////////////////////////////////////////////////////////////// + + // shader uniforms + + glUseProgram(p__solution); + glUniform1i(p__solution__input_sampler, 0); + glUniform4f(p__solution__input_dim, + parsed_input_width, + parsed_input_height, + 0.5f / parsed_input_width, + 0.5f / parsed_input_height); + glUniform2f(p__solution__input_length, + 100, + 200); // is this cheating? + + // draw + + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_output); + glViewport(0, 0, output_width, output_height); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_parsed_input); + const uint draw_buffers1[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, draw_buffers1); + + glBindVertexArray(vertex_array); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + ////////////////////////////////////////////////////////////////////// + // output + ////////////////////////////////////////////////////////////////////// + + float out[3 * output_width * output_height] = {}; + glReadPixels(0, 0, + output_width, output_height, + GL_RGB, + GL_FLOAT, + out); + printf("2025/03: %2.3f %2.3f\n", out[0], (double)out[1] * 16777216.0 + (double)out[2]); +} diff --git a/src/solution/2025/03/solution.fs.glsl b/src/solution/2025/03/solution.fs.glsl new file mode 100644 index 0000000..2bce4f9 --- /dev/null +++ b/src/solution/2025/03/solution.fs.glsl @@ -0,0 +1,78 @@ +#version 330 core + +uniform sampler2D input_sampler; +uniform vec4 input_dim; // w h halfpx_w halfpx_h + +uniform vec2 input_length; + +out vec4 fragment_result; + +vec2 halfpixel(float x, float y, vec4 dim) +{ + return vec2((x * 2.0 + 1.0) * dim.z, + (y * 2.0 + 1.0) * dim.w); +} + +float get_input(float x, float y) +{ + return texture(input_sampler, halfpixel(x, y, input_dim)).x; +} + +vec2 max_single(float y, float start, float end) +{ + float max_v = get_input(start, y); + float max_ix = start; + float x = max_ix + 1.0; + while (x < end) { + float value = get_input(x, y); + if (value > max_v) { + max_v = value; + max_ix = x; + } + x += 1.0; + } + return vec2(max_v, max_ix); +} + +double powd(float n) +{ + double res = double(1.0); + for (float i = 0.0; i < n; i++) { + res *= double(10.0); + } + return res; +} + +double max_joltage_n(float y, float reserve) +{ + float start = 0.0; + double acc = double(0.0); + while (reserve > 0.0) { + reserve -= 1.0; + vec2 res = max_single(y, start, input_length.x - reserve); + float d = res.x; + float ix = res.y; + start = ix + 1.0; + acc += powd(reserve) * double(d); + } + return acc; +} + +void main() +{ + double acc_part1 = double(0.0); + for (float i = 0.0; i < input_length.y; i += 1.0) { + acc_part1 += max_joltage_n(i, 2); + } + + double acc_part2 = double(0.0); + for (float i = 0.0; i < input_length.y; i += 1.0) { + acc_part2 += max_joltage_n(i, 12); + } + + double radix = double(16777216.0); + double h = double(floor(float(acc_part2 / radix))); + double l = acc_part2 - h * radix; + + fragment_result = vec4(float(acc_part1), h, l, 0); +} diff --git a/src/solution/2025/01/solution.vs.glsl b/src/solution/generic.vs.glsl similarity index 70% rename from src/solution/2025/01/solution.vs.glsl rename to src/solution/generic.vs.glsl index cdcb557..e1b1518 100644 --- a/src/solution/2025/01/solution.vs.glsl +++ b/src/solution/generic.vs.glsl @@ -2,7 +2,11 @@ layout (location = 0) in vec2 position; +out vec2 f_position; + void main() { + f_position = position; + gl_Position = vec4(position, 0, 1); }