feat: solved day 13 part 1 and part 2

This commit is contained in:
Stevan Freeborn
2024-12-14 12:58:28 -06:00
parent 46976b049c
commit abfa9e50ba
6 changed files with 312 additions and 3 deletions
+3
View File
@@ -0,0 +1,3 @@
namespace ClawContraption;
record Button(decimal XMovement, decimal YMovement);
+111
View File
@@ -0,0 +1,111 @@
using System.Text.RegularExpressions;
namespace ClawContraption;
partial class Machine
{
private readonly int? _maxPresses;
private readonly Button _buttonA;
private readonly Button _buttonB;
private readonly PrizeLocation _prizeLocation;
private decimal NumberOfButtonBPresses =>
((_prizeLocation.Y * _buttonA.XMovement) - (_prizeLocation.X * _buttonA.YMovement)) / ((_buttonB.YMovement * _buttonA.XMovement) - (_buttonB.XMovement * _buttonA.YMovement));
private decimal NumberOfButtonAPresses =>
(_prizeLocation.X - (_buttonB.XMovement * NumberOfButtonBPresses)) / _buttonA.XMovement;
private bool HasSolution => CheckForSolution();
public decimal TokenCost => HasSolution ? (NumberOfButtonBPresses * 1) + (NumberOfButtonAPresses * 3) : 0;
private Machine(Button buttonA, Button buttonB, PrizeLocation prizeLocation, int? maxPresses = null)
{
_buttonA = buttonA;
_buttonB = buttonB;
_prizeLocation = prizeLocation;
_maxPresses = maxPresses;
}
internal static Machine From(Button buttonA, Button buttonB, PrizeLocation prizeLocation, int? maxPresses) =>
new(buttonA, buttonB, prizeLocation, maxPresses);
public static Machine From(string[] input, int? maxPresses = null, long prizeLocationOffset = 0)
{
if (input.Length is not 3)
{
throw new ApplicationException("Input describing machine is not valid");
}
var buttonAInput = input[0];
var buttonBInput = input[1];
var prizeInput = input[2];
var buttonAMatches = ButtonARegex().Match(buttonAInput);
var buttonBMatches = ButtonBRegex().Match(buttonBInput);
var prizeMatches = PrizeRegex().Match(prizeInput);
if (buttonAMatches.Groups.Count is not 3)
{
throw new ApplicationException("input for button A missing values");
}
if (buttonBMatches.Groups.Count is not 3)
{
throw new ApplicationException("input for button B missing values");
}
if (prizeMatches.Groups.Count is not 3)
{
throw new ApplicationException("input for prize missing values");
}
var buttonA = new Button(
int.Parse(buttonAMatches.Groups[1].Value),
int.Parse(buttonAMatches.Groups[2].Value)
);
var buttonB = new Button(
int.Parse(buttonBMatches.Groups[1].Value),
int.Parse(buttonBMatches.Groups[2].Value)
);
var prize = new PrizeLocation(
int.Parse(prizeMatches.Groups[1].Value) + prizeLocationOffset,
int.Parse(prizeMatches.Groups[2].Value) + prizeLocationOffset
);
return new(buttonA, buttonB, prize, maxPresses);
}
private bool CheckForSolution()
{
if (Math.Floor(NumberOfButtonAPresses) != NumberOfButtonAPresses)
{
return false;
}
if (Math.Floor(NumberOfButtonBPresses) != NumberOfButtonBPresses)
{
return false;
}
if (_maxPresses.HasValue && NumberOfButtonAPresses > _maxPresses)
{
return false;
}
if (_maxPresses.HasValue && NumberOfButtonBPresses > _maxPresses)
{
return false;
}
return true;
}
[GeneratedRegex(@"Button A: X\+(\d+), Y\+(\d+)")]
private static partial Regex ButtonARegex();
[GeneratedRegex(@"Button B: X\+(\d+), Y\+(\d+)")]
private static partial Regex ButtonBRegex();
[GeneratedRegex(@"Prize: X=(\d+), Y=(\d+)")]
private static partial Regex PrizeRegex();
}
+3
View File
@@ -0,0 +1,3 @@
namespace ClawContraption;
record PrizeLocation(decimal X, decimal Y);
+14 -3
View File
@@ -1,5 +1,7 @@
using System.Diagnostics;
using ClawContraption;
if (args.Length is 0)
{
Console.WriteLine("Please provide a path to the input file.");
@@ -13,12 +15,21 @@ if (File.Exists(args[0]) is false)
}
var isPart2 = args.Length is 2 && args[1] is "part2";
var input = await File.ReadAllLinesAsync(args[0]);
var input = await File.ReadAllTextAsync(args[0]);
var stopwatch = new Stopwatch();
stopwatch.Start();
// TODO: Implement solution
var offset = isPart2 ? 10_000_000_000_000 : 0;
int? maxPresses = isPart2 ? null : 100;
var machines = input
.Split($"{Environment.NewLine}{Environment.NewLine}")
.Select(s => s.Split(Environment.NewLine))
.Select(s => Machine.From(s, maxPresses, offset))
.ToList();
var result = machines.Sum(m => m.TokenCost);
stopwatch.Stop();
Console.WriteLine($". ({stopwatch.ElapsedMilliseconds}ms)");
Console.WriteLine($"The fewest tokens to when all possible games is {result}. ({stopwatch.ElapsedMilliseconds}ms)");