From 2994837ebc933c6deafe0f9bc6f70b9dd5e8b74d Mon Sep 17 00:00:00 2001 From: Lucia Ceionia Date: Mon, 8 Dec 2025 16:02:36 -0600 Subject: [PATCH] day 7 --- day0.h | 23 +++++--- day7.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib.h | 39 ++++++++++--- 3 files changed, 225 insertions(+), 15 deletions(-) create mode 100644 day7.c diff --git a/day0.h b/day0.h index 4cc5300..1724327 100644 --- a/day0.h +++ b/day0.h @@ -12,27 +12,36 @@ ch test[] = { #embed "day0_test.txt" }; +alignas(0x40) static +struct { + line padstart[4]; + struct { ch *s; num _extra[7]; }; + union { line l; struct { ch s[16]; num n; }; } result; + line padend; +} m; +static_assert(offsetof(typeof(m),result) % 64 == 0); +static_assert(offsetof(typeof(m),padend) % 64 == 0); static num do_part1(size_t file_len, ch file[file_len]) { - ch *s = file; - num result = 0; + m = (typeof(m)){ }; + m.s = file; + m.result.n = 0; #if DBG print("\n"); #endif do { - s++; -} while (s != &file[file_len]); + m.s++; +} while (m.s != &file[file_len]); - return result; + return m.result.n; } static num do_part2(size_t file_len, ch file[file_len]) { - num result = 0; - return result; + return 0; } #define RUN_TEST1 1 diff --git a/day7.c b/day7.c new file mode 100644 index 0000000..b1fd2ef --- /dev/null +++ b/day7.c @@ -0,0 +1,178 @@ +#include "lib.h" + +#define DBG 0 + +static +ch input[32768] = { +#embed "day7_input.txt" +}; + +static +ch test[512] = { +#embed "day7_test.txt" +}; + +typedef struct { ch l[64]; } line; +static_assert(sizeof(line) == 0x40); + +alignas(0x40) static +struct { + line padstart[4]; + num file_stride; + num stride; + num _extra[6]; + union { line l; struct { ch s[16]; num n; }; } result; + line padend; +} m; +static_assert(offsetof(typeof(m),result) % 64 == 0); +static_assert(offsetof(typeof(m),padend) % 64 == 0); + +alignas(4096) ch buf1[256]; +alignas(4096) num buf[256]; + +static +num do_part1(size_t file_len, ch file[file_len]) { + m = (typeof(m)){ }; + m.result.n = 0; +#if DBG + pnl(); +#endif + + memset(buf1, 0, sizeof(buf1)); + + m.file_stride = findc(file, '\n', file_len) - file; + num linecnt = (findc(file, 0, file_len) - file) / m.file_stride; +#if DBG + print("stride "); printd(m.file_stride); pnl(); + print("lines "); printd(linecnt); pnl(); +#endif + + num s_pos = findc(file, 'S', - 1) - 1 - file; + buf1[s_pos] = '|'; + num line = 2; + do { + ch *l = file + line * m.file_stride; + for (num col = 0; col < m.file_stride - 1; col++) { + ch c = l[col]; + if (c == '^') { + m.result.n += buf1[col] > 0; + buf1[col-1] |= buf1[col]; + buf1[col+1] |= buf1[col]; + buf1[col] = 0; + } + } +#if DBG + for (num col = 0; col < m.file_stride; col++) { + if (buf1[col] == '|') print("|"); + else if (l[col] == '^') print("^"); + else print(" "); + } + pnl(); +#endif + line+=2; + } while (line < linecnt); + + return m.result.n; +} + +static +num do_part2(size_t file_len, ch file[file_len]) { + m = (typeof(m)){ }; +#if DBG + pnl(); +#endif + + memset(buf, 0, sizeof(buf)); + + m.file_stride = findc(file, '\n', file_len) - file; + num linecnt = (findc(file, 0, file_len) - file) / m.file_stride; +#if DBG + print("stride "); printd(m.file_stride); pnl(); + print("lines "); printd(linecnt); pnl(); +#endif + + num s_pos = findc(file, 'S', - 1) - 1 - file; + buf[s_pos] = 1; + num line = 2; + do { + ch *l = file + line * m.file_stride; + for (num col = 0; col < m.file_stride - 1; col++) { + ch c = l[col]; + if (c == '^') { + buf[col-1] += buf[col]; + buf[col+1] += buf[col]; + buf[col] = 0; + } + } + for (num col = 0; col < m.file_stride; col++) { + num v = buf[col]; +#if DBG + if (l[col] == '^') print(" "); + else if (v >> 32) print("█"); + else if (v >> 16) print("▓"); + else if (v >> 8) print("▒"); + else if (v >> 4) print("░"); + else if (v >> 2) print("-"); + else if (v >> 0) print("."); + else print(" "); +#endif + } +#if DBG + pnl(); +#endif + line+=2; + } while (line < linecnt); + + m.result.n = 0; + for (num col = 0; col < m.file_stride; col++) { + m.result.n += buf[col]; + } + + return m.result.n; +} + +#define RUN_TEST1 1 +#define RUN_PART1 1 +#define RUN_TEST2 1 +#define RUN_PART2 1 + +#define TEST1_EXPECT 21 +#define TEST2_EXPECT 40 + +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 62bf9f2..2002703 100644 --- a/lib.h +++ b/lib.h @@ -9,14 +9,6 @@ #define STDOUT_FILENO 1 -__attribute__((always_inline)) -void *memchr(const void *s, int c, size_t n) { - uint64_t dispose; - void *d; - asm("repnz scasb":"=D"(d),"=c"(dispose):"D"(s),"c"(n),"a"(c):"memory","cc"); - return d; -} - static void write(uint64_t fileno, void *buffer, size_t len) { uint64_t a,d; @@ -45,6 +37,36 @@ typedef uint64_t bcdint; typedef uint64_t num; typedef unsigned char ch; +__attribute__((always_inline)) inline +ch *findc(const ch *s, ch c, size_t n) { + uint64_t dispose; + void *d; + asm("repnz scasb":"=D"(d),"=c"(dispose):"D"(s),"c"(n),"a"(c):"memory","cc"); + return d; +} + +__attribute__((always_inline)) inline +num *findnum(const num *s, num c, size_t n) { + uint64_t dispose; + void *d; + asm("repnz scasq":"=D"(d),"=c"(dispose):"D"(s),"c"(n),"a"(c):"memory","cc"); + return d; +} + +__attribute__((always_inline)) inline +num *findnotnum(const num *s, num c, size_t n) { + uint64_t dispose; + void *d; + asm("repz scasq":"=D"(d),"=c"(dispose):"D"(s),"c"(n),"a"(c):"memory","cc"); + return d; +} + +static inline num alignnum(num v, num align) { + num extra = v % align; + num adjust = (align - extra) % align; + return v + adjust; +} + static void printns(size_t len, unsigned char chars[len]) { write(STDOUT_FILENO, chars, len); @@ -72,6 +94,7 @@ void print_many_char(size_t len, char chars[len]) { } #define print(string) print_many_char(sizeof(string)-1, string) +#define pnl() print("\n") static void printd(unsigned long v) {