#include "aoc.h" #include #include typedef struct Vec2i { i64 x; i64 y; } Vec2i; static Vec2i parse_numbers(str line, Arena *arena) { bool x_set = false; Vec2i result = {0}; for (isize i = 0; i < line.len; i++) { if (isdigit(line.data[i])) { isize end = i + 1; while (end < line.len && isdigit(line.data[end])) { end++; } str num_str = str_sub(line, i, end); if (!x_set) { result.x = (i32) parse_i64(num_str, *arena); x_set = true; } else { result.y = (i32) parse_i64(num_str, *arena); return result; } i = end; } } NOT_REACHABLE(); } static bool solve(Vec2i a, Vec2i b, Vec2i p, Vec2i *solution) { i64 det = a.x * b.y - a.y * b.x; ASSERT(det != 0); i64 numerator_a = p.x * b.y - p.y * b.x; i64 numerator_b = p.y * a.x - p.x * a.y; bool solved = false; if ((numerator_a % det == 0) && (numerator_b % det == 0)) { i64 n_a = numerator_a / det; i64 n_b = numerator_b / det; if (n_a >= 0 && n_b >= 0) { solution->x = n_a; solution->y = n_b; solved = true; } } else { // no integer solution } return solved; } int main(int argc, char **argv) { Arena *arena = make_arena(Megabytes(1)); str input = read_file(arena, argv[1]); str line; i64 part_1 = 0; i64 part_2 = 0; while (input.len > 0) { str a_line = str_next_token(&input, STR("\n")); str b_line = str_next_token(&input, STR("\n")); str prize_line = str_next_token(&input, STR("\n")); str empty_line = str_next_token(&input, STR("\n")); ASSERT(str_trim(empty_line).len == 0); Vec2i a = parse_numbers(a_line, arena); Vec2i b = parse_numbers(b_line, arena); Vec2i p = parse_numbers(prize_line, arena); Vec2i p_ = { p.x + 10000000000000ull, p.y + 10000000000000ull }; #if 0 printf("a: %ld %ld\n", a.x, a.y); printf("b: %ld %ld\n", b.x, b.y); printf("p: %ld %ld\n", p.x, p.y); printf("\n"); #endif Vec2i n; if (solve(a, b, p, &n)) { part_1 += n.x * 3 + n.y; } if (solve(a, b, p_, &n)) { part_2 += n.x * 3 + n.y; } } printf("%ld\n", part_1); printf("%ld\n", part_2); }