#include #include #include #include #define SYS_write 1 #define SYS_exit_group 231 #define STDOUT_FILENO 1 static void write(uint64_t fileno, void *buffer, size_t len) { uint64_t a,d; asm volatile("syscall" :"=a"(a),"=d"(d):"a"(SYS_write),"D"(fileno),"S"(buffer),"d"(len):"memory"); } [[noreturn]] static void exit_group() { asm volatile( "syscall\n" "ud2" ::"a"(SYS_exit_group),"D"(0)); for (;;); } #define xstr(s) str(s) #define str(s) #s static void print_many_char(size_t len, char chars[len]) { write(STDOUT_FILENO, chars, len); } #define print(string) print_many_char(sizeof(string)-1, string) static void printd(unsigned long v) { if (!v) { print("0"); return; } char buf[32]; char *p = buf+32; unsigned count = 0; while (v) { p--; *p = '0' + (v % 10); v /= 10; count++; } write(STDOUT_FILENO, p, count); } static unsigned grabnum(const char *s, const char **end) { unsigned r = 0; for (; *s >= '0' && *s <= '9'; s++) r = r * 10 + (*s - '0'); *end = s; return r; } #define DBG 1 #define RUN_PART1 1 #define RUN_PART2 1 #define RUN_TEST1 1 #define RUN_TEST2 1 #define TEST1_EXPECT 3 #define TEST2_EXPECT 6 static char input[] = { #embed "day1_input.txt" }; static char test[] = { #embed "day1_test.txt" }; static unsigned long do_part1(size_t src_len, const char src[src_len]) { const char *s = src; unsigned long count = 0; unsigned long pos = 1'000'000'000'050; while (s < &src[src_len]) { const char *ns = s + 1; unsigned r = grabnum(ns, &ns); if (*s == 'L') { pos -= r; } else { pos += r; } count += pos % 100 == 0; s = ns + 1; } return count; } static unsigned do_part2(size_t src_len, const char src[src_len]) { const char *s = src, *ns = s + 1; unsigned count = 0; unsigned pos = 50; for (;s < &src[src_len]; s = ns + 1, ns = s + 1) { unsigned r = grabnum(ns, &ns); if (*s == 'L') { if (pos == 0) pos = 100; unsigned to_zero = pos; if (r < to_zero) { pos -= r; } else { unsigned over = r - to_zero; unsigned rots = over / 100; unsigned adjust = over % 100; count += 1 + rots; pos = (100 - adjust) % 100; } } else { unsigned to_zero = 100 - pos; if (r < to_zero) { pos += r; } else { unsigned over = r - to_zero; unsigned rots = over / 100; unsigned adjust = over % 100; count += 1 + rots; pos = adjust; } } } return count; } void run() { #if RUN_TEST1 print("PART 1 TEST: "); if (unsigned long 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 (unsigned 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(); }