From e71c742863bffbdb3e9a1667421fbb4f51c5b294 Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Sat, 6 Dec 2025 14:29:30 -0600 Subject: [PATCH] day 6 --- Makefile | 4 +- day0.h | 28 ++----- day6.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib.h | 1 + 4 files changed, 257 insertions(+), 21 deletions(-) create mode 100644 day6.c diff --git a/Makefile b/Makefile index 73d1b41..8a94430 100644 --- a/Makefile +++ b/Makefile @@ -14,13 +14,13 @@ LFLAGS = -Ttext=C475000 -static -nostdlib -no-pie all: $(BINS) -%.elf: %.o start.o | %.c lib.h $(MUSLOBJS) +%.elf: %.o start.o | %.c $(MUSLOBJS) ld -o $@ $(LFLAGS) start.o $< $(MUSLOBJS) start.o: start.s nasm -f elf64 -o $@ $< -%.o: %.c +%.o: %.c | lib.h gcc-tree -o $@ $(CFLAGS) $< clean: diff --git a/day0.h b/day0.h index ad35655..4cc5300 100644 --- a/day0.h +++ b/day0.h @@ -3,20 +3,20 @@ #define DBG 0 static -unsigned char input[] = { +ch input[] = { #embed "day0_input.txt" }; static -unsigned char test[] = { +ch test[] = { #embed "day0_test.txt" }; static -unsigned long do_part1(size_t file_len, unsigned char file[file_len]) { - unsigned char *s = file; - unsigned long result = 0; +num do_part1(size_t file_len, ch file[file_len]) { + ch *s = file; + num result = 0; #if DBG print("\n"); @@ -30,18 +30,8 @@ do { } static -unsigned long do_part2(size_t file_len, unsigned char file[file_len]) { - unsigned char *s = file; - unsigned long result = 0; - -#if DBG - print("\n"); -#endif - -do { - s++; -} while (s != &file[file_len]); - +num do_part2(size_t file_len, ch file[file_len]) { + num result = 0; return result; } @@ -56,7 +46,7 @@ do { void run() { #if RUN_TEST1 print("PART 1 TEST: "); - if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) { + if (num v = do_part1(countof(test), test); v != TEST1_EXPECT) { print("FAILED (got "); printd(v); print(", expected " xstr(TEST1_EXPECT) ")\n"); @@ -73,7 +63,7 @@ void run() { #if RUN_TEST2 print("PART 2 TEST: "); - if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) { + if (num v = do_part2(countof(test), test); v != TEST2_EXPECT) { print("FAILED (got "); printd(v); print(", expected " xstr(TEST2_EXPECT) ")\n"); diff --git a/day6.c b/day6.c new file mode 100644 index 0000000..e11e41b --- /dev/null +++ b/day6.c @@ -0,0 +1,245 @@ +#include "lib.h" + +#define DBG 1 + +static +ch input[] = { +#embed "day6_input.txt" +}; + +static +ch test[] = { +#embed "day6_test.txt" +}; + + +static +num do_part1(size_t file_len, ch file[file_len]) { + ch *s = file; + num result = 0; + +#if DBG + print("\n"); +#endif + + while (*s != 10) s++; + num stride = s - file + 1; + + s = file; + while (*s != '+' && *s != '*') s += stride; + num heightb = (s - file); + num height = (s - file) / stride; + ch *op = s; + +#if DBG + print("STRIDE\t"); printd(stride); print("\n"); + print("HEIGHT\t"); printd(height); print("\n"); +#endif + + // constructing a pointer more than 1 past the end of an array + // is UB, sadly, so we'll use offsets + num op_off = op - file; + s = file; + do { + num ledge_off = op_off - heightb; + if (s[op_off] == '+') { + num a = 0; + num rem = height; + do { + ch *t = s + ledge_off; + while (*t < '0') t++; + num b = grabnum(t, NULL); +#if DBG + if (rem < height) { print("\t+\t"); } + printd(b); +#endif + a += b; + ledge_off += stride; + rem--; + } while (rem); + result += a; +#if DBG + print("\t= "); printd(a); print("\n"); +#endif + } else if (s[op_off] == '*') { + num a = 1; + num rem = height; + do { + ch *t = s + ledge_off; + while (*t < '0') t++; + num b = grabnum(t, NULL); +#if DBG + if (rem < height) { print("\t*\t"); } + printd(b); +#endif + a *= b; + ledge_off += stride; + rem--; + } while (rem); + result += a; +#if DBG + print("\t= "); printd(a); print("\n"); +#endif + } +#if DBG + else { + print("INVALID OP\n"); + exit_group(-1); + } +#endif + op_off++; + while (op_off < file_len) { + if (s[op_off] == '+' || s[op_off] == '*') + break; + op_off++; + } + } while (op_off < file_len); + + return result; +} + +static +num do_part2(size_t file_len, unsigned char file[file_len]) { + ch *s = file; + num result = 0; + +#if DBG + print("\n"); +#endif + + while (*s != 10) s++; + num stride = s - file + 1; + + s = file; + while (*s != '+' && *s != '*') s += stride; + num heightb = (s - file); + num height = (s - file) / stride; + ch *op = s; + +#if DBG + print("STRIDE\t"); printd(stride); print("\n"); + print("HEIGHT\t"); printd(height); print("\n"); +#endif + + // constructing a pointer more than 1 past the end of an array + // is UB, sadly, so we'll use offsets + num fop_off = op - file; + num prev_op_off = fop_off + stride - 1; + s = file; + do { + // we don't need to do these in the same order as the example + // because both these operations are commutative. + // but you know what? we can anyway. for fun. and pretty output + num op_off = prev_op_off - 1; + while (s[op_off] != '+' && s[op_off] != '*' && s[op_off] != '\n') + op_off--; + num ledge_off = op_off - heightb; + num redge_off = (s[prev_op_off] == '\n' ? -1 : -2) + prev_op_off - heightb; + if (s[op_off] == '+') { + num a = 0; + num rem = redge_off - ledge_off + 1; + num frem = rem; + do { + num b = 0; + ch *t = s + redge_off; + for (num i = height; i; i--,t+=stride) { + if (*t >= '0') { + b *= 10; + b += *t - '0'; + } + } +#if DBG + if (rem < frem) { print("\t+\t"); } + printd(b); +#endif + a += b; + redge_off--; + rem--; + } while (rem); + result += a; +#if DBG + print("\t=\t"); printd(a); print("\n"); +#endif + } else if (s[op_off] == '*') { + num a = 1; + num rem = redge_off - ledge_off + 1; + num frem = rem; + do { + num b = 0; + ch *t = s + redge_off; + for (num i = height; i; i--,t+=stride) { + if (*t >= '0') { + b *= 10; + b += *t - '0'; + } + } +#if DBG + if (rem < frem) { print("\t*\t"); } + printd(b); +#endif + a *= b; + redge_off--; + rem--; + } while (rem); + result += a; +#if DBG + print("\t=\t"); printd(a); print("\n"); +#endif + } +#if DBG + else { + print("INVALID OP\n"); + exit_group(-1); + } +#endif + prev_op_off = op_off; + } while (prev_op_off != fop_off); + + return result; +} + +#define RUN_TEST1 1 +#define RUN_PART1 1 +#define RUN_TEST2 1 +#define RUN_PART2 1 + +#define TEST1_EXPECT 4277556 +#define TEST2_EXPECT 3263827 + +void run() { +#if RUN_TEST1 + print("PART 1 TEST: "); + if (num v = do_part1(countof(test), test); v != TEST1_EXPECT) { + print("FAILED (got "); + printd(v); + print(", expected " xstr(TEST1_EXPECT) ")\n"); + } else { + print("PASSED\n"); + } +#endif + +#if RUN_PART1 + print("PART 1 RESULT: "); + printd(do_part1(countof(input), input)); + print("\n"); +#endif + +#if RUN_TEST2 + print("PART 2 TEST: "); + if (num v = do_part2(countof(test), test); v != TEST2_EXPECT) { + print("FAILED (got "); + printd(v); + print(", expected " xstr(TEST2_EXPECT) ")\n"); + } else { + print("PASSED\n"); + } +#endif + +#if RUN_PART2 + print("PART 2 RESULT: "); + printd(do_part2(countof(input), input)); + print("\n"); +#endif + + exit_group(0); +} diff --git a/lib.h b/lib.h index 77185a9..e329035 100644 --- a/lib.h +++ b/lib.h @@ -35,6 +35,7 @@ void exit_group(uint64_t code) { typedef uint64_t bcdint; typedef uint64_t num; +typedef unsigned char ch; static void printns(size_t len, unsigned char chars[len]) {