#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); return divided; } int li_cost(int ax, int ay, int bx, int by, int px, int 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 b_x_movement = (r.num / r.denom); long b_cost = b_x_movement / bx; long a_x_movement = px - b_x_movement; long a_cost = a_x_movement / ax; printf("%d\n", b_cost + a_cost); return b_cost + a_cost; } int best_cost(int ax, int ay, int bx, int by, int px, int py) { int best_cost_so_far = 0; for (int i = 0; i <= 100; i++) { px -= ax; py -= ay; if (px % bx != 0 || py % by != 0) continue; if (px / bx != py / by) continue; int cost = (i + 1) * 3 + px / bx; if (best_cost_so_far == 0 || best_cost_so_far > cost) best_cost_so_far = cost; } return best_cost_so_far; } int main() { int ax, ay, bx, by, px, py; char *line; int cost = 0; int 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("Part 1: %d\n", cost); printf("Part 2: %lld\n", cost_2); aoc_free(); return 0; }