#include "aoc.h" #include static const u8 PRED_BIT = 0x01; static const u8 SUCC_BIT = 0x02; // matrix[a][b] & PRED_BIT != 0 means that a must precede b. // matrix[a][b] & SUCC_BIT != 0 means that a must succeed b. // by symmetry, (matrix[a][b] & PRED_BIT) == (matrix[b][a] & SUCC_BIT). // matrix[a][b] == 0 means that there is no constraint between a and b. // by inspection, the inputs are all >= 0 and < 100. static u8 matrix[100][100] = {0}; static int compare(const void *pa, const void *pb) { i32 a = *(const i32 *)pa; i32 b = *(const i32 *)pb; if (matrix[a][b] & PRED_BIT) return -1; if (matrix[a][b] & SUCC_BIT) return 1; return 0; } int main(int argc, char **argv) { Arena *arena = make_arena(Megabytes(1)); str input = read_file(arena, argv[1]); str line; while ((line = str_next_token(&input, STR("\n"))).len > 0) { str fst, snd; str_split(line, STR("|"), &fst, &snd); i32 a = parse_i64(fst, *arena); i32 b = parse_i64(snd, *arena); matrix[a][b] |= PRED_BIT; matrix[b][a] |= SUCC_BIT; } i32 part_1 = 0; i32 part_2 = 0; while ((line = str_next_token(&input, STR("\n"))).len > 0) { str value_str; struct { i32 *data; isize len, cap; } values = {0}; void *watermark = arena->top; while ((value_str = str_next_token(&line, STR(","))).len > 0) { i32 value = parse_i64(value_str, *arena); *push(&values, arena) = value; } arena->top = watermark; bool row_ok = true; for (isize i = 0; i < values.len && row_ok; i++) { i32 value = values.data[i]; for (isize j = 0; j < values.len; j++) { if (i == j) continue; i32 other = values.data[j]; if (matrix[value][other]) { if (i < j && !(matrix[value][other] & PRED_BIT)) { row_ok = false; break; } if (i > j && !(matrix[value][other] & SUCC_BIT)) { row_ok = false; break; } } } } if (row_ok) { part_1 += values.data[values.len / 2]; } else { qsort(values.data, values.len, sizeof(i32), compare); part_2 += values.data[values.len / 2]; } } printf("%d\n", part_1); printf("%d\n", part_2); }