advent-of-code

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

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 }