Claw midpoint

This commit is contained in:
Bill Rossi 2024-12-13 03:52:39 -05:00
parent 6e9cf2c26a
commit de73079754

View File

@ -0,0 +1,108 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#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;
}