Skip to content

Commit

Permalink
Add AoC 2024 day 13 solver
Browse files Browse the repository at this point in the history
  • Loading branch information
h3x4d3c1m4l committed Dec 14, 2024
1 parent 91196f1 commit a61a88b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
15 changes: 15 additions & 0 deletions assets/advent_of_code/2024_13_sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400

Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176

Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450

Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279
1 change: 1 addition & 0 deletions lib/solvers/advent_of_code/2024/_all_solvers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export 'day_05_solver.dart';
export 'day_06_solver.dart';
export 'day_11_solver.dart';
export 'day_12_solver.dart';
export 'day_13_solver.dart';
58 changes: 58 additions & 0 deletions lib/solvers/advent_of_code/2024/day_13_solver.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:h3x_devtools/solvers/advent_of_code/2024/aoc_2024_solver.dart';

typedef _ClawMachineAnalysis = ({int buttonAX, int buttonAY, int buttonBX, int buttonBY, int priceX, int priceY});

class Day13Solver extends AdventOfCode2024Solver {

@override
final int dayNumber = 13;

@override
String getSolution(String input) {
String splitString = input.contains('\r\n\r\n') ? '\r\n\r\n' : input.contains('\r\r') ? '\r\r' : '\n\n';
List<_ClawMachineAnalysis> clawMachineAnalysis = input.split(splitString).map((lineSet) {
List<List<String?>> matches = RegExp(r'X\+(\d*), Y\+(\d*)|X=(\d*), Y=(\d*)').allMatches(lineSet).map((e) => e.groups([0, 1, 2, 3, 4])).toList();
return (buttonAX: int.parse(matches[0][1]!), buttonAY: int.parse(matches[0][2]!), buttonBX: int.parse(matches[1][1]!), buttonBY: int.parse(matches[1][2]!), priceX: int.parse(matches[2][3]!), priceY: int.parse(matches[2][4]!));
}).toList();

// Part 1
int usedTokensPart1 = 0;
for (({int buttonAX, int buttonAY, int buttonBX, int buttonBY, int priceX, int priceY}) analysis in clawMachineAnalysis) {
usedTokensPart1 += _getUsedTokens(analysis, false) ?? 0;
}

// Part 2
int usedTokensPart2 = 0;
for (({int buttonAX, int buttonAY, int buttonBX, int buttonBY, int priceX, int priceY}) analysis in clawMachineAnalysis) {
usedTokensPart2 += _getUsedTokens(analysis, true) ?? 0;
}

return 'Fewest tokens: $usedTokensPart1, fewest tokens correct: $usedTokensPart2';
}

}

int? _getUsedTokens(_ClawMachineAnalysis analysis, bool part2) {
double a1 = analysis.buttonAX.toDouble(), b1 = analysis.buttonBX.toDouble(), equals1 = analysis.priceX.toDouble() + (part2 ? 10000000000000 : 0);
double a2 = analysis.buttonAY.toDouble(), b2 = analysis.buttonBY.toDouble(), equals2 = analysis.priceY.toDouble() + (part2 ? 10000000000000 : 0);

// Use method of elimination
double elimFactor = -a1 / a2;
double b2Elim = b2 * elimFactor;
double equalsElim = equals2 * elimFactor;

double bAfterElim = b1 + b2Elim;
double equalsAfterElim = equals1 + equalsElim;

double bButtonPresses = equalsAfterElim / bAfterElim;
double aButtonPresses = (equals1 - b1 * bButtonPresses) / a1;

const double epsilon = 0.001;
if ((aButtonPresses - aButtonPresses.round()).abs() <= epsilon &&
(bButtonPresses - bButtonPresses.round()).abs() <= epsilon) {
// Valid result
return aButtonPresses.round() * 3 + bButtonPresses.round();
}

return null;
}

0 comments on commit a61a88b

Please sign in to comment.