advent-of-code

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

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 }