advent-of-code

Solutions for Advent of Code.
git clone git://git.amin.space/advent-of-code.git
Log | Files | Refs | LICENSE

commit a11c5cfa69db7d5291269e66a4aa64bf67cb6212
parent 4bfbfaea1f4d44c57060250805c4071b58bbbdac
Author: amin <dev@aminmesbah.com>
Date:   Fri,  3 Dec 2021 22:33:42 +0000

Solve 2021 day 1 part 1

FossilOrigin-Name: 44901fcf7d9d6bcd32e0089cd6f3228c5236f0a779a80a2df8e5d89d06881bf3
Diffstat:
M.gitignore | 1+
A2021/am_base.h | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2021/am_list.h | 233+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2021/am_memory.h | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2021/am_string.h | 252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2021/day01_01.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A2021/day01_input.txt | 2000+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 2858 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1 +1,2 @@ zig-cache/ +**/out/ diff --git a/2021/am_base.h b/2021/am_base.h @@ -0,0 +1,118 @@ +#ifndef AM_BASE_H +#define AM_BASE_H + +#if __STDC_VERSION__ < 201112L +# error "C11 or greater required." +#endif + +// context +// https://sourceforge.net/p/predef/wiki/Home/ +#if defined(__clang__) +# define COMPILER_CLANG 1 +#elif defined (__GNUC__) +# define COMPILER_GCC 1 +#else +# error "Unsupported compiler." +#endif + +#if !defined(COMPILER_CLANG) +# define COMPILER_CLANG 0 +#endif +#if !defined(COMPILER_GCC) +# define COMPILER_GCC 0 +#endif + +#if defined (__linux__) +# define OPERATING_SYSTEM_LINUX 1 +#elif defined(_WIN32) +# define OPERATING_SYSTEM_WINDOWS 1 +#else +# error "Unsupported OS." +#endif + +#if !defined(OPERATING_SYSTEM_LINUX) +# define OPERATING_SYSTEM_LINUX 0 +#endif +#if !defined(OPERATING_SYSTEM_WINDOWS) +# define OPERATING_SYSTEM_WINDOWS 0 +#endif + +// compiler builtins +#if COMPILER_CLANG || COMPILER_GCC +# ifndef __has_builtin +# define __has_builtin(x) 0 +# endif +#endif + +#define IMPLEMENTATION_UNSIGNED_CHAR (CHAR_MIN == 0) + +// freestanding headers +#include <float.h> +#include <limits.h> +#include <stdalign.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdnoreturn.h> + +// preprocessor improvement +#define AM__STRINGIFY(S) #S +#define AM__GLUE(A, B) A##B +#define AM_STRINGIFY(S) AM__STRINGIFY(S) +#define AM_GLUE(A, B) AM__GLUE((A), (B)) + +// assert +#define static_assert(expr) _Static_assert((expr), "") + +#if !defined(AM_ENABLE_ASSERT) +# define AM_ENABLE_ASSERT 0 +#endif + +#if AM_ENABLE_ASSERT +# if !defined(AM_ASSERT_FAIL) +# if __has_builtin(__builtin_trap) +# define AM_ASSERT_FAIL(expr, file, line, func) __builtin_trap() +# else +# error "Must define implementation of AM_ASSERT_FAIL(expr, file, line, func)." +# endif +# endif +# define assert(x) ((void)((x) || (AM_ASSERT_FAIL(AM_STRINGIFY(x), __FILE__, __LINE__, __func__),0))) +#else +# define assert(c) ((void)0) +#endif + +#define AM_UNREACHABLE assert(false && "Unreachable code reached") + +// utility macros +#define ALIGN_UP_POW_2(x, p) (((x) + (p) - 1) & ~((p) - (1))) +#define ALIGN_DOWN_POW_2(x, p) ((x) & ~((p) - 1)) +#define ARRAY_COUNT(a) (sizeof(a)/sizeof(*(a))) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define CLAMP(a, x, b) (((x) < (a)) ? (a) : (((b) < (x)) ? (b) : (x))) +#define CLAMP_TOP(a, b) MIN((a), (b)) +#define CLAMP_BOT(a, b) MAX((a), (b)) +#define UNUSED(p) (void)(p) + +// basic types +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef size_t usz; +typedef float f32; +typedef double f64; + +#define global static +#define local_persist static +#define internal static + +// sanity checks +static_assert(CHAR_BIT == 8); + +#endif // AM_BASE_H diff --git a/2021/am_list.h b/2021/am_list.h @@ -0,0 +1,233 @@ +#ifndef AM_LIST_H +#define AM_LIST_H + +#define DLL_APPEND_NP(f, l, n, next, prev) \ + ((f) == NULL \ + ? ((f) = (l) = (n) \ + , (f)->prev = (n)->next = NULL) \ + : ((n)->prev = (l) \ + , (l)->next = (n) \ + , (l) = (n) \ + , (n)->next = NULL)) + +#define DLL_REMOVE_NP(f, l, n, next, prev) \ + ((f) == (l) && (f) == (n) \ + ? ((f) = (l) = NULL) \ + : ((f) == (n) \ + ? ((f) = (f)->next \ + , (f)->prev = NULL) \ + : ((l) == (n) \ + ? ((l) = (l)->prev \ + , (l)->next = NULL) \ + : ((n)->prev->next = (n)->next \ + , (n)->next->prev = (n)->prev)))) + +#define SLL_QUEUE_PUSH_N(f, l, n, next) \ + ((f) == NULL \ + ? ((f) = (l) = (n)) \ + : ((l)->next = (n) \ + , (l) = (n) \ + , (n)->next = NULL)) + +#define SLL_QUEUE_PUSH_FRONT_N(f, l, n, next) \ + ((f) == NULL \ + ? ((f) = (l) = (n) \ + , (n)->next = NULL) \ + : ((n)->next = (f) \ + , (f) = (n))) + +// TODO: It's maybe somewhat surprising to the user that these pop functions +// don't return the popped node. +#define SLL_QUEUE_POP_N(f, l, next) \ + ((f) == (l) \ + ? ((f) = (l) = NULL) \ + : ((f) = (f)->next)) + + +#define SLL_STACK_PUSH_N(f, n, next) ((n)->next = (f), (f) = (n)) + +#define SLL_STACK_POP_N(f, next) \ + ((f) == NULL \ + ? 0 \ + : ((f) = (f)->next)) + +#define DLL_APPEND(f, l, n) DLL_APPEND_NP((f), (l), (n), next, prev) +#define DLL_PREPEND(f, l, n) DLL_APPEND_NP((l), (f), (n), prev, next) +#define DLL_REMOVE(f, l, n) DLL_REMOVE_NP((f), (l), (n), next, prev) + +#define SLL_QUEUE_PUSH(f, l, n) SLL_QUEUE_PUSH_N((f), (l), (n), next) +#define SLL_QUEUE_PUSH_FRONT(f, l, n) SLL_QUEUE_PUSH_FRONT_N((f), (l), (n), next) +#define SLL_QUEUE_POP(f, l) SLL_QUEUE_POP_N((f), (l), next) + +#define SLL_STACK_PUSH(f, n) SLL_STACK_PUSH_N((f), (n), next) +#define SLL_STACK_POP(f) SLL_STACK_POP_N((f), next) + +#if defined(AM_INCLUDE_TESTS) +typedef struct TestNode TestNode; +struct TestNode { + TestNode *next; + TestNode *prev; + s32 val; +}; + +internal void am_list_test(void) { + TestNode nodes[10] = {0}; + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + nodes[i].val = i; + } + + { + TestNode *first = NULL; + TestNode *last = NULL; + + printf("dll append and remove from front\n"); + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + DLL_APPEND(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf(" <|> "); + for (TestNode *n = last; n; n = n->prev) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + DLL_REMOVE(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf(" <|> "); + for (TestNode *n = last; n; n = n->prev) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + printf("dll prepend and remove from back\n"); + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + DLL_PREPEND(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf(" <|> "); + for (TestNode *n = last; n; n = n->prev) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + DLL_REMOVE(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf(" <|> "); + for (TestNode *n = last; n; n = n->prev) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + printf("dll append and remove from middle\n"); + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + DLL_APPEND(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf(" <|> "); + for (TestNode *n = last; n; n = n->prev) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + DLL_REMOVE(first, last, &nodes[(i + (ARRAY_COUNT(nodes) / 2)) % ARRAY_COUNT(nodes)]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf(" <|> "); + for (TestNode *n = last; n; n = n->prev) { + printf(" %i ", n->val); + } + printf("]\n"); + } + } + + { + TestNode *first = NULL; + TestNode *last = NULL; + + printf("sll queue push and pop\n"); + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + SLL_QUEUE_PUSH(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + while (first) { + SLL_QUEUE_POP(first, last); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + printf("sll queue push front and pop\n"); + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + SLL_QUEUE_PUSH_FRONT(first, last, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + while (first) { + SLL_QUEUE_POP(first, last); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf("]\n"); + } + } + + { + TestNode *first = NULL; + + printf("sll stack push and pop\n"); + for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) { + SLL_STACK_PUSH(first, &nodes[i]); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf("]\n"); + } + + while (first) { + SLL_STACK_POP(first); + printf("["); + for (TestNode *n = first; n; n = n->next) { + printf(" %i ", n->val); + } + printf("]\n"); + } + } +} +#endif // defined(AM_INCLUDE_TESTS) + +#endif // AM_LIST_H diff --git a/2021/am_memory.h b/2021/am_memory.h @@ -0,0 +1,178 @@ +#ifndef AM_MEMORY_H +#define AM_MEMORY_H + +#define MEM_KIB(b) ((u64)(b) << 10) +#define MEM_MIB(b) ((u64)(b) << 20) +#define MEM_GIB(b) ((u64)(b) << 30) + +#define AM_MEM_RESERVE_FN(name) void *(name)(void *ctx, u64 size) +typedef AM_MEM_RESERVE_FN(am_mem_reserve_fn); + +#define AM_MEM_CHANGE_FN(name) void (name)(void *ctx, void *ptr, u64 size) +typedef AM_MEM_CHANGE_FN(am_mem_change_fn); + +typedef struct { + am_mem_reserve_fn* reserve; + am_mem_change_fn* commit; + am_mem_change_fn* decommit; + am_mem_change_fn* release; + void *ctx; +} BaseAllocator; + +#define AM_MEM_ARENA_COMMIT_BLOCK_SIZE MEM_MIB(64) +#define AM_MEM_ARENA_DEFAULT_RESERVE_SIZE MEM_GIB(1) + +typedef struct { + BaseAllocator *base; + u8 *mem; + u64 cap; + u64 pos; + u64 commit_pos; +} MemArena; + +internal AM_MEM_CHANGE_FN(am_mem_change_noop) { + UNUSED(ctx); + UNUSED(ptr); + UNUSED(size); +} + +internal AM_MEM_RESERVE_FN(am_mem_reserve_malloc) { + UNUSED(ctx); + return malloc(size); +} + +internal AM_MEM_CHANGE_FN(am_mem_release_malloc) { + UNUSED(ctx); + UNUSED(size); + free(ptr); +} + +internal BaseAllocator *am_mem_base_allocator_malloc(void) { + local_persist BaseAllocator b; + if (!b.reserve) { + b = (BaseAllocator) { + .reserve = am_mem_reserve_malloc, + .commit = am_mem_change_noop, + .decommit = am_mem_change_noop, + .release = am_mem_release_malloc, + }; + } + return &b; +} + +internal MemArena am_mem_arena_create_reserve(BaseAllocator *base, u64 reserve_size) { + MemArena a = { + .base = base, + }; + a.mem = a.base->reserve(a.base->ctx, reserve_size); + a.cap = reserve_size; + return a; +} + +internal MemArena am_mem_arena_create(BaseAllocator *base) { + return am_mem_arena_create_reserve(base, AM_MEM_ARENA_DEFAULT_RESERVE_SIZE); +} + +internal void *am_mem_arena_push(MemArena *a, u64 size) { + void *result = NULL; + if (a->mem + size <= a->mem + a->cap) { + result = a->mem + a->pos; + a->pos += size; + + if (a->pos > a->commit_pos) { + u64 aligned = ALIGN_UP_POW_2(a->pos, AM_MEM_ARENA_COMMIT_BLOCK_SIZE); + u64 next_commit_pos = CLAMP_TOP(aligned, a->cap); + u64 commit_size = next_commit_pos - a->commit_pos; + a->base->commit(a->base->ctx, a->mem + a->commit_pos, commit_size); + a->commit_pos = next_commit_pos; + } + } + return result; +} + +#define AM_MEM_ARENA_PUSH_ARRAY(arena, T, count) (am_mem_arena_push((arena), sizeof(T) * (count))) + +internal void am_mem_arena_pop_to(MemArena *a, u64 pos) { + if (pos < a->pos) { + a->pos = pos; + + u64 aligned = ALIGN_UP_POW_2(a->pos, AM_MEM_ARENA_COMMIT_BLOCK_SIZE); + u64 next_commit_pos = CLAMP_TOP(aligned, a->cap); + if (next_commit_pos < a->commit_pos) { + u64 decommit_size = a->commit_pos - next_commit_pos; + a->base->decommit(a->base->ctx, a->mem + a->commit_pos, decommit_size); + a->commit_pos = next_commit_pos; + } + } +} + +internal void am_mem_arena_release(MemArena *a) { + a->base->release(a->base->ctx, a->mem, a->cap); + *a = (MemArena){0}; +} + +// TODO: SIMD +internal void am_mem_copy(void *dst, void *src, u64 size) { + for (u64 i = 0; i < size; i++) { + ((u8 *)dst)[i] = ((u8 *)src)[i]; + } +} + +internal bool am_mem_equal(void *dst, void *src, u64 size) { + for (u64 i = 0; i < size; i++) { + if (((u8 *)dst)[i] != ((u8 *)src)[i]) { + return false; + } + } + return true; +} + +#if defined(AM_INCLUDE_TESTS) +internal void am_memory_test(void) { + assert(MEM_KIB(10) == 10240); + assert(MEM_MIB(10) == 10485760); + assert(MEM_GIB(10) == 10737418240); + + { + BaseAllocator *a = am_mem_base_allocator_malloc(); + u64 num_test_ints = 10; + s32 *int_buf = a->reserve(NULL, num_test_ints * sizeof(s32)); + assert(int_buf); + a->release(NULL, int_buf, 0); + } + + { + MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc()); + am_mem_arena_push(&a, 1020); + assert(a.pos == 1020); + u64 p = a.pos; + u64 cp = a.commit_pos; + + AM_MEM_ARENA_PUSH_ARRAY(&a, u8, a.cap - a.pos); + assert(a.pos == a.cap); + assert(a.commit_pos == a.cap); + + am_mem_arena_pop_to(&a, p); + assert(a.pos == p); + assert(a.commit_pos == cp); + + am_mem_arena_release(&a); + assert(a.pos == 0); + assert(a.commit_pos == 0); + assert(a.mem == NULL); + } + + { + u8 src[10] = {0}; + u8 dst[10] = {0}; + for (u64 i = 0; i < ARRAY_COUNT(src); i++) { + src[i] = i; + } + + am_mem_copy(dst, src, ARRAY_COUNT(dst)); + assert(am_mem_equal(dst, src, ARRAY_COUNT(dst))); + } +} +#endif // defined(AM_INCLUDE_TESTS) + +#endif // AM_MEMORY_H diff --git a/2021/am_string.h b/2021/am_string.h @@ -0,0 +1,252 @@ +#ifndef AM_STRING_H +#define AM_STRING_H + +#ifndef AM_MEMORY_H + #error "am_memory.h is required" +#endif +#ifndef AM_LIST_H + #error "am_list.h is required" +#endif + +typedef struct { + usz size; + u8 *str; +} Str; + +typedef struct StrListNode StrListNode; +struct StrListNode { + StrListNode *next; + Str s; +}; + +typedef struct { + StrListNode *first; + StrListNode *last; + u64 node_count; + u64 total_size; +} StrList; + +#define AM_STR_LIT(s) (Str) { .str = (u8 *)(s), .size = sizeof(s) - 1, } +#define AM_STR_EXPAND(s) (s32)((s).size), ((s).str) + +internal usz am_cstr_len(char *cstr) { + usz len = 0; + while (cstr && *cstr != '\0') { + len++; + cstr++; + } + return len; +} + +internal Str am_str(u8 *str, usz size) { + return (Str) { .size = size, .str = str, }; +} + +internal Str am_str_from_range(u8 *start, u8 *opl) { + assert(start < opl); + return am_str(start, opl - start); +} + +internal Str am_str_from_cstr(char *cstr, usz len) { + return am_str((u8 *)cstr, len); +} + +// TODO: Use string interning +internal bool am_str_eq(Str s1, Str s2) { + if (s1.size != s2.size) { + return false; + } + + for (usz i = 0; i < s1.size; i++) { + if (s1.str[i] != s2.str[i]) { + return false; + } + } + + return true; +} + +internal bool am_cstr_eq(char *cstr1, char *cstr2) { + usz len1 = am_cstr_len(cstr1); + usz len2 = am_cstr_len(cstr2); + return am_str_eq(am_str_from_cstr(cstr1, len1), am_str_from_cstr(cstr2, len2)); +} + +internal Str am_str_line(Str s, u8 *cursor) { + u8 *opl = s.str + s.size; + + assert(cursor >= s.str && cursor < opl); + + u8 *end = cursor; + while (end < opl) { + if (*end == '\n') { + break; + } + end++; + } + + u8 *beginning = cursor - (*cursor == '\n'); + while (beginning >= s.str) { + if (*beginning == '\n') { + beginning++; + break; + } + beginning--; + } + + return am_str_from_range(beginning, end); +} + +internal bool am_str_contains(Str s, char c) { + for (usz i = 0; i < s.size; i++) { + if (s.str[i] == c) { + return true; + } + } + return false; +} + +internal bool am_cstr_contains(char *s, usz len, char c) { + return am_str_contains(am_str_from_cstr(s, len), c); +} + +internal bool am_str_cstr_eq(Str s, char *cstr) { + return am_str_eq(s, am_str_from_cstr(cstr, am_cstr_len(cstr))); +} + +internal void am_str_list_append(MemArena *arena, StrList *list, Str s) { + StrListNode *node = am_mem_arena_push(arena, sizeof(StrListNode)); + *node = (StrListNode) { + .s = s, + }; + SLL_QUEUE_PUSH(list->first, list->last, node); + list->node_count += 1; + list->total_size += s.size; +} + +typedef struct { + Str pre; + Str mid; + Str post; +} StringJoinOptions; + +internal Str am_str_join(MemArena *arena, StrList *list, StringJoinOptions *options) { + StringJoinOptions join; + if (options) { + join = *options; + } else { + join = (StringJoinOptions){0}; + } + + u64 total_size = list->total_size + + join.pre.size + + (join.mid.size * (list->node_count - 1)) + + join.post.size; + + Str s= { + .str = AM_MEM_ARENA_PUSH_ARRAY(arena, u8, total_size), + .size = total_size, + }; + + u8 *p = s.str; + am_mem_copy(p, join.pre.str, join.pre.size); + p += join.pre.size; + + bool is_mid = false; + for (StrListNode *n = list->first; n; n = n->next) { + if (is_mid) { + am_mem_copy(p, join.mid.str, join.mid.size); + p += join.mid.size; + } + + am_mem_copy(p, n->s.str, n->s.size); + p += n->s.size; + + is_mid = true; + } + + am_mem_copy(p, join.post.str, join.post.size); + p += join.post.size; + + return s; +} + +internal StrList am_str_split(MemArena *arena, Str s, u8 *split_chars, u64 split_char_count) { + StrList list = {0}; + + u8 *cursor = s.str; + u8 *split_beginning = cursor; + u8 *opl = s.str + s.size; + while (cursor < opl) { + bool split_byte = false; + for (u64 i = 0; i < split_char_count; i++) { + if (split_chars[i] == *cursor) { + split_byte = true; + } + } + + if (split_byte) { + if (split_beginning < cursor) { + am_str_list_append(arena, &list, am_str_from_range(split_beginning, cursor)); + } + split_beginning = cursor + 1; + } + cursor++; + } + + return list; +} + +#if defined(AM_INCLUDE_TESTS) +internal void am_string_test(void) { + assert(am_cstr_len("abcdefg") == 7); + assert(am_cstr_len("") == 0); + assert(am_cstr_len("\0") == 0); + assert(am_cstr_eq("", "")); + assert(am_cstr_eq("\0", "\0")); + assert(am_cstr_eq("abc", "abc")); + assert(!am_cstr_eq("ABC", "abc")); + assert(!am_cstr_eq("", " ")); + assert(!am_cstr_eq("abc", "abcde")); + assert(!am_str_cstr_eq(AM_STR_LIT("abcd"), "abc")); + assert(am_str_cstr_eq(AM_STR_LIT("abc"), "abc")); + assert(am_cstr_contains("abc", 3, 'c')); + assert(am_cstr_contains("a c", 3, ' ')); + assert(am_cstr_contains("", 1, '\0')); + assert(!am_cstr_contains("abc", 3, 'z')); + assert(!am_cstr_contains("", 0, 'z')); + assert(!am_cstr_contains("", 0, '\0')); + assert(am_cstr_contains("https://www.example.com", 23, '/')); + + { + StrList l = {0}; + MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc()); + Str strings[] = { + AM_STR_LIT("one"), + AM_STR_LIT("two"), + AM_STR_LIT("three"), + }; + + for (u64 i = 0; i < ARRAY_COUNT(strings); i++) { + am_str_list_append(&a, &l, strings[i]); + } + + Str joined = am_str_join(&a, &l, &(StringJoinOptions){ + .pre = AM_STR_LIT("Joined: '"), + .mid = AM_STR_LIT(", "), + .post = AM_STR_LIT("'."), + }); + + printf("%.*s\n", AM_STR_EXPAND(joined)); + + StrList split = am_str_split(&a, AM_STR_LIT(", one, two, three, "), (u8 *)", ", 2); + + for (StrListNode *n = split.first; n; n = n->next) { + printf("split: '%.*s'\n", AM_STR_EXPAND(n->s)); + } + am_mem_arena_release(&a); + } +} +#endif // defined(AM_INCLUDE_TESTS) + +#endif // AM_STRING_H diff --git a/2021/day01_01.c b/2021/day01_01.c @@ -0,0 +1,76 @@ +#if 0 +# Self-building c file. Invoke like: `./file.c` +outdir=out +input=$(basename "$0") +output="$outdir"/$(basename "$0" .c) +if [ "$input" -nt "$output" ]; +then + mkdir --parents "$outdir" || exit + echo "Building ${output}." || exit + clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit +fi +if [ "$1" = "-r" ]; +then + ./"$output" "$@" +fi +exit +#endif + +#include <inttypes.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +_Noreturn void assert_fail(const char *expr, const char *file, int line, const char *func) { + fprintf(stderr, "%s:%d: %s: Assertion failed: '%s'\n", file, line, func, expr); + abort(); +} + +#define AM_ENABLE_ASSERT 1 +#define AM_ASSERT_FAIL(expr, file, line, func) assert_fail(expr, file, line, func) +#include "am_base.h" +#include "am_memory.h" +#include "am_list.h" +#include "am_string.h" + +Str open_file(MemArena *arena, char *path) { + FILE *f = fopen(path, "r"); + assert(f); + + s32 error = fseek(f, 0L, SEEK_END); + assert(!error); + + s64 size = ftell(f); + assert(size >= 0); + rewind(f); + + u8 *buf = am_mem_arena_push(arena, size); + assert(buf); + + size_t items_read = fread(buf, 1, size, f); + assert(items_read == (size_t)size); + + error = fclose(f); + assert(!error); + + return am_str(buf, size); +} + +int main(void) { + MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc()); + Str input = open_file(&a, "day01_input.txt"); + StrList lines = am_str_split(&a, input, (u8 *)"\n", 1); + u64 increase_count = 0; + u64 previous_number = UINT64_MAX; + for (StrListNode *line = lines.first; line; line = line->next) { + u64 number = 0; + for (usz i = 0; i < line->s.size; i++) { + u64 digit = line->s.str[i] - '0'; + number = (number * 10) + digit; + } + increase_count += (number > previous_number); + previous_number = number; + } + printf("Increase Count: %" PRIu64 "\n", increase_count); + am_mem_arena_release(&a); + return 0; +} diff --git a/2021/day01_input.txt b/2021/day01_input.txt @@ -0,0 +1,2000 @@ +149 +163 +165 +160 +179 +184 +186 +199 +207 +210 +211 +212 +228 +241 +242 +265 +269 +271 +287 +286 +295 +296 +293 +300 +301 +302 +304 +308 +320 +322 +321 +333 +350 +345 +348 +347 +351 +348 +349 +345 +353 +366 +376 +384 +387 +390 +391 +378 +382 +394 +409 +411 +415 +419 +424 +425 +427 +428 +436 +445 +446 +459 +464 +478 +479 +493 +492 +493 +482 +484 +491 +492 +497 +501 +506 +509 +521 +526 +527 +539 +546 +547 +551 +562 +567 +568 +573 +590 +591 +596 +612 +613 +618 +620 +593 +594 +596 +597 +596 +612 +616 +618 +620 +621 +622 +611 +612 +613 +610 +615 +616 +634 +647 +654 +655 +656 +657 +659 +676 +678 +675 +703 +715 +722 +738 +747 +760 +765 +771 +784 +789 +792 +769 +770 +773 +762 +772 +817 +823 +825 +864 +863 +849 +852 +862 +868 +893 +895 +896 +925 +946 +945 +946 +945 +964 +954 +962 +969 +976 +1004 +1007 +1015 +1029 +1037 +1043 +1048 +1070 +1080 +1100 +1097 +1094 +1102 +1099 +1098 +1099 +1096 +1097 +1117 +1123 +1124 +1125 +1127 +1119 +1121 +1137 +1173 +1174 +1179 +1181 +1200 +1204 +1175 +1179 +1180 +1189 +1194 +1195 +1197 +1199 +1206 +1200 +1208 +1211 +1213 +1214 +1229 +1230 +1271 +1278 +1279 +1282 +1288 +1285 +1291 +1290 +1294 +1297 +1299 +1300 +1320 +1324 +1323 +1328 +1329 +1330 +1331 +1334 +1337 +1311 +1313 +1314 +1320 +1323 +1318 +1323 +1331 +1339 +1340 +1328 +1334 +1336 +1342 +1343 +1350 +1357 +1359 +1377 +1378 +1384 +1368 +1369 +1371 +1380 +1360 +1349 +1374 +1373 +1376 +1372 +1382 +1384 +1391 +1393 +1399 +1403 +1404 +1419 +1427 +1425 +1454 +1455 +1458 +1459 +1479 +1484 +1485 +1487 +1492 +1497 +1499 +1496 +1503 +1528 +1543 +1535 +1546 +1547 +1549 +1546 +1547 +1549 +1550 +1553 +1581 +1583 +1598 +1616 +1618 +1640 +1638 +1655 +1686 +1685 +1671 +1674 +1680 +1673 +1675 +1676 +1673 +1674 +1679 +1681 +1689 +1701 +1702 +1708 +1722 +1723 +1727 +1739 +1742 +1743 +1756 +1759 +1763 +1767 +1768 +1772 +1771 +1775 +1783 +1784 +1794 +1796 +1815 +1811 +1812 +1822 +1820 +1836 +1825 +1828 +1826 +1827 +1832 +1844 +1847 +1854 +1855 +1857 +1864 +1854 +1869 +1868 +1867 +1868 +1872 +1875 +1876 +1880 +1874 +1875 +1876 +1877 +1881 +1882 +1897 +1898 +1903 +1904 +1906 +1904 +1911 +1908 +1909 +1930 +1929 +1928 +1948 +1958 +1963 +1964 +1967 +1971 +1960 +1958 +1968 +1969 +1972 +1973 +1974 +1980 +1981 +1992 +1993 +1999 +1998 +1997 +1996 +1997 +2008 +2007 +1987 +1991 +1992 +1998 +2006 +2007 +2014 +2017 +2022 +2027 +2017 +2020 +2048 +2049 +2050 +2054 +2055 +2067 +2072 +2089 +2075 +2076 +2077 +2078 +2085 +2086 +2088 +2091 +2086 +2094 +2102 +2103 +2105 +2107 +2109 +2111 +2124 +2125 +2127 +2130 +2131 +2133 +2136 +2147 +2148 +2153 +2152 +2158 +2157 +2164 +2165 +2167 +2166 +2200 +2201 +2200 +2206 +2207 +2197 +2208 +2209 +2211 +2217 +2235 +2236 +2243 +2233 +2226 +2238 +2244 +2237 +2232 +2229 +2233 +2242 +2239 +2240 +2241 +2242 +2247 +2248 +2260 +2276 +2273 +2275 +2301 +2317 +2340 +2341 +2328 +2332 +2326 +2322 +2323 +2330 +2334 +2351 +2352 +2360 +2370 +2371 +2370 +2377 +2378 +2381 +2392 +2406 +2385 +2392 +2397 +2395 +2393 +2397 +2395 +2414 +2418 +2424 +2429 +2431 +2455 +2456 +2468 +2478 +2483 +2485 +2484 +2485 +2486 +2475 +2484 +2493 +2494 +2513 +2519 +2529 +2530 +2535 +2537 +2555 +2540 +2541 +2539 +2533 +2534 +2543 +2548 +2551 +2557 +2561 +2563 +2565 +2600 +2601 +2595 +2594 +2609 +2613 +2587 +2591 +2598 +2604 +2564 +2568 +2570 +2576 +2575 +2577 +2595 +2602 +2605 +2613 +2615 +2606 +2601 +2600 +2598 +2599 +2601 +2603 +2617 +2623 +2625 +2626 +2638 +2641 +2642 +2636 +2637 +2630 +2617 +2619 +2616 +2615 +2624 +2633 +2635 +2663 +2666 +2668 +2671 +2672 +2675 +2685 +2686 +2697 +2702 +2704 +2723 +2724 +2729 +2716 +2718 +2727 +2731 +2770 +2761 +2778 +2800 +2801 +2798 +2799 +2800 +2801 +2798 +2794 +2795 +2835 +2836 +2845 +2848 +2858 +2873 +2874 +2892 +2906 +2898 +2927 +2933 +2936 +2940 +2948 +2950 +2945 +2947 +2957 +2949 +2950 +2951 +2957 +2959 +2960 +2962 +2978 +2982 +2983 +2986 +3000 +3002 +3004 +3005 +3002 +3009 +3022 +3009 +3002 +3003 +3022 +3037 +3040 +3041 +3042 +3044 +3045 +3049 +3053 +3057 +3060 +3061 +3059 +3060 +3070 +3071 +3072 +3075 +3076 +3081 +3084 +3081 +3080 +3086 +3098 +3099 +3100 +3105 +3107 +3113 +3121 +3126 +3131 +3136 +3145 +3150 +3153 +3154 +3156 +3157 +3165 +3154 +3155 +3156 +3169 +3176 +3191 +3188 +3190 +3197 +3199 +3221 +3254 +3262 +3263 +3259 +3258 +3259 +3267 +3266 +3268 +3263 +3268 +3269 +3291 +3295 +3294 +3326 +3327 +3335 +3327 +3343 +3346 +3369 +3368 +3372 +3375 +3379 +3386 +3395 +3396 +3397 +3409 +3412 +3416 +3418 +3419 +3418 +3417 +3414 +3424 +3425 +3430 +3431 +3433 +3434 +3435 +3421 +3422 +3424 +3425 +3416 +3429 +3423 +3432 +3444 +3451 +3468 +3469 +3468 +3470 +3471 +3472 +3473 +3471 +3483 +3486 +3495 +3496 +3501 +3505 +3496 +3497 +3507 +3512 +3515 +3519 +3523 +3524 +3525 +3524 +3549 +3551 +3525 +3526 +3534 +3536 +3542 +3545 +3548 +3527 +3529 +3528 +3553 +3555 +3560 +3561 +3580 +3582 +3579 +3582 +3586 +3584 +3588 +3564 +3572 +3568 +3567 +3565 +3583 +3575 +3579 +3581 +3589 +3605 +3613 +3615 +3617 +3643 +3645 +3652 +3654 +3653 +3654 +3659 +3656 +3659 +3653 +3651 +3654 +3657 +3675 +3677 +3679 +3707 +3710 +3717 +3755 +3758 +3759 +3761 +3766 +3768 +3759 +3761 +3762 +3790 +3791 +3793 +3797 +3784 +3785 +3786 +3787 +3790 +3792 +3784 +3789 +3792 +3795 +3789 +3790 +3797 +3783 +3795 +3792 +3801 +3804 +3806 +3810 +3808 +3813 +3793 +3797 +3802 +3810 +3822 +3825 +3830 +3839 +3838 +3837 +3838 +3839 +3840 +3841 +3842 +3862 +3870 +3871 +3886 +3887 +3890 +3882 +3890 +3884 +3885 +3907 +3914 +3926 +3934 +3935 +3944 +3954 +3946 +3951 +3954 +3957 +3958 +3970 +3981 +3988 +3985 +3988 +3989 +3982 +3978 +3979 +3980 +3981 +4001 +4002 +4011 +4016 +4021 +4026 +4024 +4027 +4043 +4044 +4062 +4066 +4069 +4067 +4087 +4099 +4097 +4091 +4093 +4090 +4088 +4094 +4100 +4108 +4109 +4105 +4121 +4138 +4141 +4144 +4145 +4154 +4153 +4156 +4157 +4153 +4151 +4157 +4161 +4162 +4163 +4165 +4162 +4171 +4170 +4177 +4192 +4202 +4203 +4204 +4213 +4217 +4218 +4220 +4221 +4222 +4228 +4258 +4259 +4261 +4262 +4263 +4267 +4269 +4277 +4279 +4278 +4256 +4258 +4277 +4301 +4297 +4336 +4315 +4301 +4302 +4299 +4291 +4294 +4295 +4297 +4291 +4292 +4297 +4303 +4313 +4319 +4327 +4312 +4311 +4316 +4321 +4323 +4335 +4337 +4338 +4348 +4343 +4344 +4345 +4327 +4329 +4331 +4334 +4355 +4356 +4352 +4360 +4366 +4376 +4383 +4391 +4373 +4388 +4376 +4372 +4369 +4366 +4376 +4392 +4397 +4398 +4406 +4405 +4420 +4427 +4426 +4423 +4419 +4420 +4418 +4420 +4418 +4423 +4427 +4428 +4430 +4419 +4420 +4421 +4417 +4418 +4435 +4434 +4448 +4449 +4450 +4451 +4456 +4453 +4456 +4480 +4481 +4504 +4512 +4519 +4527 +4530 +4529 +4530 +4549 +4569 +4572 +4579 +4578 +4583 +4587 +4599 +4604 +4619 +4618 +4619 +4627 +4628 +4626 +4627 +4629 +4628 +4632 +4635 +4636 +4669 +4681 +4684 +4681 +4683 +4682 +4686 +4690 +4689 +4690 +4692 +4695 +4696 +4692 +4691 +4722 +4721 +4720 +4721 +4732 +4735 +4734 +4737 +4736 +4739 +4744 +4775 +4790 +4796 +4769 +4770 +4763 +4765 +4787 +4804 +4792 +4794 +4795 +4793 +4794 +4799 +4817 +4828 +4842 +4844 +4849 +4852 +4876 +4877 +4892 +4896 +4906 +4907 +4910 +4922 +4927 +4930 +4933 +4934 +4935 +4940 +4938 +4951 +4966 +4975 +4987 +4988 +4991 +4992 +4996 +5001 +5002 +5014 +5026 +5031 +5035 +5038 +5037 +5038 +5048 +5049 +5072 +5074 +5100 +5101 +5107 +5116 +5115 +5127 +5125 +5134 +5136 +5140 +5143 +5150 +5148 +5178 +5179 +5181 +5186 +5187 +5191 +5202 +5204 +5202 +5206 +5217 +5214 +5224 +5221 +5236 +5231 +5232 +5235 +5226 +5230 +5231 +5210 +5219 +5223 +5224 +5225 +5229 +5230 +5239 +5254 +5261 +5262 +5265 +5261 +5262 +5263 +5270 +5275 +5274 +5270 +5267 +5263 +5265 +5289 +5290 +5298 +5300 +5303 +5301 +5302 +5305 +5319 +5324 +5348 +5351 +5355 +5356 +5354 +5365 +5359 +5356 +5357 +5380 +5378 +5395 +5403 +5413 +5422 +5421 +5431 +5430 +5446 +5458 +5462 +5466 +5467 +5471 +5472 +5471 +5486 +5494 +5495 +5497 +5500 +5520 +5522 +5525 +5529 +5562 +5563 +5566 +5569 +5572 +5586 +5592 +5594 +5595 +5598 +5603 +5587 +5588 +5592 +5595 +5596 +5605 +5626 +5628 +5629 +5632 +5637 +5639 +5643 +5647 +5629 +5634 +5642 +5643 +5651 +5646 +5662 +5663 +5675 +5677 +5684 +5688 +5700 +5703 +5681 +5720 +5731 +5738 +5741 +5743 +5744 +5754 +5756 +5764 +5770 +5769 +5777 +5780 +5788 +5791 +5812 +5813 +5817 +5830 +5839 +5840 +5866 +5870 +5871 +5864 +5867 +5870 +5873 +5874 +5912 +5914 +5917 +5922 +5931 +5932 +5936 +5937 +5936 +5938 +5959 +5961 +5955 +5960 +5985 +5998 +5997 +5999 +6000 +6003 +6013 +6027 +6028 +6048 +6047 +6049 +6043 +6050 +6073 +6074 +6097 +6098 +6099 +6100 +6102 +6104 +6117 +6116 +6118 +6138 +6139 +6151 +6152 +6150 +6152 +6153 +6163 +6187 +6191 +6187 +6191 +6190 +6202 +6205 +6214 +6213 +6216 +6217 +6219 +6225 +6200 +6201 +6211 +6212 +6222 +6231 +6230 +6249 +6250 +6282 +6309 +6312 +6315 +6310 +6314 +6328 +6335 +6336 +6341 +6348 +6351 +6353 +6358 +6357 +6384 +6385 +6372 +6377 +6382 +6384 +6380 +6382 +6384 +6385 +6388 +6391 +6406 +6405 +6414 +6415 +6417 +6418 +6423 +6424 +6436 +6453 +6460 +6459 +6461 +6475 +6479 +6476 +6477 +6479 +6482 +6481 +6479 +6478 +6491 +6500 +6504 +6505 +6506 +6483 +6473 +6474 +6476 +6477 +6487 +6498 +6500 +6501 +6499 +6497 +6501 +6503 +6512 +6510 +6509 +6496 +6497 +6498 +6513 +6520 +6521 +6523 +6546 +6545 +6548 +6558 +6578 +6579 +6584 +6582 +6588 +6593 +6610 +6616 +6605 +6607 +6629 +6626 +6628 +6648 +6647 +6675 +6674 +6682 +6684 +6691 +6716 +6725 +6726 +6731 +6747 +6764 +6771 +6774 +6780 +6784 +6785 +6789 +6802 +6823 +6838 +6853 +6860 +6847 +6848 +6863 +6862 +6868 +6872 +6873 +6865 +6869 +6870 +6872 +6874 +6898 +6902 +6908 +6907 +6914 +6912 +6913 +6918 +6940 +6942 +6943 +6944 +6945 +6948 +6949 +6950 +6956 +6961 +6978 +6984 +7007 +7011 +7019 +7031 +7038 +7052 +7053 +7059 +7064 +7058 +7064 +7067 +7069 +7063 +7062 +7084 +7086 +7093 +7096 +7088 +7091 +7102 +7099 +7103 +7131 +7132 +7127 +7130 +7131 +7132 +7133 +7134 +7133 +7144 +7145 +7152 +7156 +7157 +7158 +7155 +7169 +7172 +7182 +7184 +7209 +7212 +7180 +7185 +7184 +7185 +7190 +7176 +7178 +7181 +7178 +7186 +7179 +7180 +7183 +7182 +7183 +7179 +7181 +7185 +7187 +7200 +7201 +7202 +7204 +7205 +7213 +7216 +7217 +7219 +7220 +7217 +7234 +7235 +7238 +7239 +7237 +7240 +7241 +7264 +7280 +7278 +7267 +7273 +7283 +7284 +7287 +7289 +7288 +7286 +7311 +7323 +7332 +7333 +7336 +7339 +7343 +7351 +7376 +7380 +7381 +7382 +7392 +7402 +7400 +7402 +7409 +7431 +7435 +7437 +7439 +7455 +7451 +7465 +7468 +7495 +7503 +7504 +7508 +7498 +7502 +7503 +7504 +7496 +7504 +7509 +7517 +7519 +7514 +7532 +7534 +7553 +7551 +7555 +7550 +7551 +7552 +7553 +7554 +7556 +7557 +7558 +7559 +7583 +7588 +7589 +7590 +7589 +7605 +7606 +7608 +7615 +7637 +7652 +7664 +7665 +7667 +7669 +7688 +7690 +7716 +7717 +7720 +7728 +7732 +7738 +7752 +7758 +7780 +7789 +7801 +7839 +7838 +7849 +7848 +7860 +7851 +7844 +7845 +7844 +7849 +7850 +7855 +7853 +7854 +7864 +7865 +7866 +7867 +7875 +7888 +7889 +7895 +7899 +7911 +7906 +7934 +7938 +7941 +7943 +7936 +7935 +7937 +7938 +7940 +7950 +7959 +7958 +7966 +7968 +7992 +7996 +7997 +7991 +7995 +7996 +8005 +8006 +8007 +8010 +8013 +8015 +8014 +8016 +8048 +8053 +8051 +8030 +8032 +8029 +8028 +8029 +8038 +8047 +8069 +8084 +8099 +8095 +8099 +8105 +8096 +8101 +8102 +8107 +8131 +8151 +8154 +8156 +8158 +8177 +8207 +8208 +8187 +8188 +8191 +8168 +8169 +8172 +8179 +8180 +8181 +8183 +8193 +8205 +8245 +8246 +8255 +8247 +8251 +8252 +8251 +8250 +8252 +8258 +8259 +8260 +8267 +8271 +8290 +8305 +8315 +8322 +8335 +8338 +8341 +8342 +8332 +8337 +8345 +8364 +8375 +8362 +8361 +8362 +8354 +8361 +8362 +8377 +8379 +8382 +8406 +8409 +8412 +8413 +8419 +8418 +8419 +8430 +8435 +8429 +8434 +8435 +8417 +8443 +8434 +8447 +8449 +8452 +8459 +8486 +8487 +8489 +8490 +8510 +8508 +8509 +8513 +8514 +8511 +8514 +8493 +8476 +8473 +8487 +8511 +8509 +8517 +8521 +8544 +8549 +8567 +8589 +8594 +8598 +8624 +8650 +8654 +8655 +8663 +8662 +8675 +8676 +8693 +8694 +8691 +8693 +8698 +8699 +8720 +8739 +8740 +8747 +8739 +8740 +8761 +8767 +8761 +8768 +8762 +8752 +8757 +8754 +8756 +8765 +8771 +8775 +8780 +8787 +8774 +8772 +8784 +8778 +8783 +8787 +8789 +8808 +8809 +8819 +8837 +8847 +8850 +8848 +8864 +8862 +8864 +8891 +8892 +8884 +8886 +8887 +8888 +8893 +8894 +8895