day02_02.c (2935B)
1 #if 0 2 # Self-building c file. Invoke like: `./file.c` 3 outdir=out 4 input=$(basename "$0") 5 output="$outdir"/$(basename "$0" .c) 6 if [ "$input" -nt "$output" ]; 7 then 8 mkdir --parents "$outdir" || exit 9 echo "Building ${output}." || exit 10 clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit 11 fi 12 if [ "$1" = "-r" ]; 13 then 14 ./"$output" "$@" 15 fi 16 exit 17 #endif 18 19 #include <errno.h> 20 #include <inttypes.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 24 _Noreturn void assert_fail(const char *expr, const char *file, int line, const char *func) { 25 fprintf(stderr, "%s:%d: %s: Assertion failed: '%s'\n", file, line, func, expr); 26 abort(); 27 } 28 29 #define AM_ENABLE_ASSERT 1 30 #define AM_ASSERT_FAIL(expr, file, line, func) assert_fail(expr, file, line, func) 31 #include "am_base.h" 32 #include "am_memory.h" 33 #include "am_list.h" 34 #include "am_string.h" 35 36 Str open_file(MemArena *arena, char *path) { 37 FILE *f = fopen(path, "r"); 38 assert(f); 39 40 s32 error = fseek(f, 0L, SEEK_END); 41 assert(!error); 42 43 s64 size = ftell(f); 44 assert(size >= 0); 45 rewind(f); 46 47 u8 *buf = am_mem_arena_push(arena, size); 48 assert(buf); 49 50 size_t items_read = fread(buf, 1, size, f); 51 assert(items_read == (size_t)size); 52 53 error = fclose(f); 54 assert(!error); 55 56 return am_str(buf, size); 57 } 58 59 int main(void) { 60 MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc()); 61 Str input = open_file(&a, "day02_input.txt"); 62 StrList tokens = am_str_split(&a, input, (u8 *)"\n ", 2); 63 64 struct { 65 s64 horizontal; 66 s64 depth; 67 s64 aim; 68 } position = {0}; 69 70 s64 *dimension = NULL; 71 s64 sign = 0; 72 bool expect_command = true; 73 74 for (StrListNode *token = tokens.first; token; token = token->next) { 75 if (expect_command) { 76 if (am_str_eq(token->s, AM_STR_LIT("forward"))) { 77 dimension = &position.horizontal; 78 sign = 1; 79 } else if (am_str_eq(token->s, AM_STR_LIT("up"))) { 80 dimension = &position.aim; 81 sign = -1; 82 } else if (am_str_eq(token->s, AM_STR_LIT("down"))) { 83 dimension = &position.aim; 84 sign = 1; 85 } else { 86 assert(false); 87 } 88 expect_command = false; 89 } else { 90 assert(dimension); 91 assert(sign == -1 || sign == 1); 92 assert(token->s.size == 1); 93 assert(token->s.str[0] >= '0' && token->s.str[0] <= '9'); 94 s64 amount = token->s.str[0] - '0'; 95 *dimension += sign * amount; 96 if (dimension == &position.horizontal) { 97 position.depth += position.aim * amount; 98 } 99 expect_command = true; 100 } 101 } 102 103 printf("Multiplied position dimensions: %" PRId64 "\n", position.horizontal * position.depth); 104 105 am_mem_arena_release(&a); 106 return 0; 107 }