Day 13: Claw Contraption
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
You are viewing a single thread.
View all comments 2 points
C#
public partial class Day13 : Solver
{
private record struct Button(int X, int Y);
private record struct Machine(int X, int Y, Button A, Button B);
private List<Machine> machines = [];
[GeneratedRegex(@"^Button (A|B): X\+(\d+), Y\+(\d+)$")]
private static partial Regex ButtonSpec();
[GeneratedRegex(@"^Prize: X=(\d+), Y=(\d+)$")]
private static partial Regex PrizeSpec();
public void Presolve(string input) {
var machine_specs = input.Trim().Split("\n\n").ToList();
foreach (var spec in machine_specs) {
var lines = spec.Split("\n").ToList();
if (ButtonSpec().Match(lines[0]) is not { Success: true } button_a_match
|| ButtonSpec().Match(lines[1]) is not { Success: true } button_b_match
|| PrizeSpec().Match(lines[2]) is not { Success:true} prize_match) {
throw new InvalidDataException($"parse error: ${lines}");
}
machines.Add(new Machine(
int.Parse(prize_match.Groups[1].Value),
int.Parse(prize_match.Groups[2].Value),
new Button(int.Parse(button_a_match.Groups[2].Value), int.Parse(button_a_match.Groups[3].Value)),
new Button(int.Parse(button_b_match.Groups[2].Value), int.Parse(button_b_match.Groups[3].Value))
));
}
}
private string Solve(bool unit_conversion) {
BigInteger total_cost = 0;
foreach (var machine in machines) {
long prize_x = machine.X + (unit_conversion ? 10000000000000 : 0);
long prize_y = machine.Y + (unit_conversion ? 10000000000000 : 0);
BigInteger det = machine.A.X * machine.B.Y - machine.B.X * machine.A.Y;
if (det == 0) continue;
BigInteger det_a = prize_x * machine.B.Y - machine.B.X * prize_y;
BigInteger det_b = prize_y * machine.A.X - machine.A.Y * prize_x;
var (a, a_rem) = BigInteger.DivRem(det_a, det);
var (b, b_rem) = BigInteger.DivRem(det_b, det);
if (a_rem != 0 || b_rem != 0) continue;
total_cost += a * 3 + b;
}
return total_cost.ToString();
}
public string SolveFirst() => Solve(false);
public string SolveSecond() => Solve(true);
}