84 lines
2.5 KiB
C
84 lines
2.5 KiB
C
#include "aoc.h"
|
|
#include <stdlib.h>
|
|
|
|
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);
|
|
}
|