#include #include #include #include #include "../../lib/aoc.h" typedef struct Ratio { long long num; long long denom; } Ratio; typedef struct Line { Ratio slope; Ratio offset; } Line; Ratio ratio_subtract(Ratio r1, Ratio r2) { Ratio r3; r3.num= r1.num * r2.denom - r2.num * r1.denom; r3.denom= r1.denom* r2.denom; return r3; } Ratio ratio_divide(Ratio r1, Ratio r2) { Ratio r3; r3.num = r1.num * r2.denom; r3.denom = r1.denom * r2.num; return r3; } bool proper(Ratio r) { return r.num % r.denom == 0; } Ratio intersect_x(Line l1, Line l2) { Ratio left_side = ratio_subtract(l1.slope, l2.slope); Ratio right_side = ratio_subtract(l2.offset, l1.offset); Ratio divided = ratio_divide(right_side, left_side); printf("left: %lld/%lld, right: %lld/%lld, divided: %lld/%lld\n", left_side.num, left_side.denom, right_side.num, right_side.denom, divided.num, divided.denom); return divided; } long long li_cost(int ax, int ay, int bx, int by, long long px, long long py) { printf("prize at %lld, %lld\n", px, py); Line b_line; b_line.slope.num = by; b_line.slope.denom = bx; b_line.offset.num = 0; b_line.offset.denom = 1; Line a_line; a_line.slope.num = ay; a_line.slope.denom = ax; a_line.offset.num = -1 * ((px * ay) - (py * ax)); a_line.offset.denom = ax; Ratio r = intersect_x(b_line, a_line); if (!proper(r)) { printf("bzzt\n"); return 0; } long long b_x_movement = (r.num / r.denom); if (b_x_movement % bx != 0) return 0; // Fuuuuuuuuuuuuuuck this long long b_cost = b_x_movement / bx; long long a_x_movement = px - b_x_movement; if (a_x_movement % ax != 0) return 0; // Fuuuuuuuuuuuuuuck this long long a_cost = (a_x_movement / ax) * 3; printf("b: %lld, a: %lld\n", b_x_movement, a_x_movement); printf("b presses: %lld, a presses: %lld\n", b_x_movement / bx, a_x_movement / ax); if (b_x_movement < 0 || a_x_movement < 0) return 0; printf("cost: %lld\n", b_cost + a_cost); return b_cost + a_cost; } int main() { int ax, ay, bx, by; long long px, py; char *line; long long cost = 0; long long cost_2 = 0; while((line = aoc_read_line()) != NULL) { sscanf(line, "Button A: X+%d, Y+%d", &ax, &ay); sscanf(aoc_read_line(), "Button B: X+%d, Y+%d", &bx, &by); sscanf(aoc_read_line(), "Prize: X=%d, Y=%d", &px, &py); aoc_read_line(); cost += li_cost(ax, ay, bx, by, px, py); cost_2 += li_cost(ax, ay, bx, by, px + 10000000000000, py + 10000000000000); printf("\n"); } printf("Part 1: %lld\n", cost); printf("Part 2: %lld\n", cost_2); aoc_free(); return 0; }