day01.c (2596B)
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 mkdir --parents "$outdir" || exit 7 echo "Building ${output}." || exit 8 clang -std=c11 -O0 -g -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit 9 if [ "$1" = "-r" ]; 10 then 11 ./"$output" "$@" 12 fi 13 exit 14 #endif 15 16 #include <inttypes.h> 17 #include <errno.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 _Noreturn void assert_fail(const char *expr, const char *file, int line, const char *func) { 21 fprintf(stderr, "%s:%d: %s: Assertion failed: '%s'\n", file, line, func, expr); 22 abort(); 23 } 24 25 #define AM_ENABLE_ASSERT 1 26 #define AM_ASSERT_FAIL(expr, file, line, func) assert_fail(expr, file, line, func) 27 #include "am_base.h" 28 #include "am_memory.h" 29 #include "am_list.h" 30 #include "am_string.h" 31 32 Str open_file(MemArena *arena, char *path) { 33 FILE *f = fopen(path, "r"); 34 assert(f); 35 36 int error = fseek(f, 0L, SEEK_END); 37 assert(!error); 38 39 s64 size = ftell(f); 40 assert(size >= 0); 41 rewind(f); 42 43 u8 *buf = am_mem_arena_push(arena, size); 44 assert(buf); 45 46 usz items_read = fread(buf, 1, size, f); 47 assert(items_read == (usz)size); 48 49 error = fclose(f); 50 assert(!error); 51 52 return am_str(buf, size); 53 } 54 55 u64 u64_from_string(Str s) { 56 u64 result = 0; 57 for (usz i = 0; i < s.size; i++) { 58 assert(s.str[i] >= '0' && s.str[i] <= '9'); 59 60 u64 place_value = 1; 61 for (usz p = 0; p < (s.size - i - 1); p++) { 62 place_value *= 10; 63 } 64 65 result += (s.str[i] - '0') * place_value; 66 } 67 return result; 68 } 69 70 int main(void) { 71 MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc()); 72 Str input = open_file(&a, "day01_input.txt"); 73 StrList lines = am_str_split(&a, input, (u8 *)"\n", 1); 74 75 u64 top[3] = {0}; 76 u64 calories = 0; 77 78 for (StrListNode *line = lines.first; line; line = line->next) { 79 calories += u64_from_string(line->s); 80 81 if (am_str_eq(line->s, AM_STR_LIT("")) || line == lines.last) { 82 if (calories > top[0]) { 83 top[0] = calories; 84 } 85 86 u64 sum = top[0] + top[1] + top[2]; 87 u64 min = MIN(top[0], MIN(top[1], top[2])); 88 u64 max = MAX(top[0], MAX(top[1], top[2])); 89 90 top[0] = min; 91 top[1] = sum - min - max; 92 top[2] = max; 93 94 calories = 0; 95 } 96 } 97 98 am_mem_arena_release(&a); 99 100 printf("Day 1.1: %" PRIu64 "\n", top[2]); 101 printf("Day 1.2: %" PRIu64 "\n", top[0] + top[1] + top[2]); 102 return 0; 103 }