#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); }