mirror of
https://github.com/jcreek/advent-of-code.git
synced 2026-07-13 11:13:47 +00:00
150 lines
5.1 KiB
C#
150 lines
5.1 KiB
C#
namespace AOC.Tests.Y2023;
|
|
|
|
[TestFixture]
|
|
[Parallelizable(ParallelScope.All)]
|
|
public class Day06
|
|
{
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
realData = File.ReadAllLines(Path.Combine(TestContext.CurrentContext.TestDirectory, "Y2023", "Data",
|
|
$"{GetThisClassName()}.dat"));
|
|
}
|
|
|
|
protected string GetThisClassName() { return GetType().Name; }
|
|
private string[] realData;
|
|
|
|
[TestCase(@"Time: 7 15 30
|
|
Distance: 9 40 200", 288)]
|
|
[TestCase(null, 1660968)] // The actual answer
|
|
public void Part1(string input, int? expected)
|
|
{
|
|
string[] lines = input != null ? input.Split("\n") : realData;
|
|
|
|
List<int> times = lines[0].Split(" ").Where(s => int.TryParse(s, out _)).Select(int.Parse).ToList();
|
|
List<int> distances = lines[1].Split(" ").Where(s => int.TryParse(s, out _)).Select(int.Parse).ToList();
|
|
List<int> waysToBeatMaxDistance = new();
|
|
// populate waysToBeatMaxDistance with 0s for the same list length as times
|
|
for (int i = 0; i < times.Count; i++)
|
|
{
|
|
waysToBeatMaxDistance.Add(0);
|
|
}
|
|
|
|
int startingSpeedInMilimetersPerSecond = 0;
|
|
int amountToIncreaseSpeedPerSecondHoldingTheButtonInMilimetersPerSecond = 1;
|
|
|
|
// for each race, determine how many different ways you can beat the maximum distance
|
|
for (int i = 0; i < times.Count; i++)
|
|
{
|
|
int raceTime = times[i];
|
|
int distanceToBeat = distances[i];
|
|
|
|
for (int j = 1; j < raceTime; j++)
|
|
{
|
|
// Hold the button for j seconds
|
|
int speed = startingSpeedInMilimetersPerSecond +
|
|
amountToIncreaseSpeedPerSecondHoldingTheButtonInMilimetersPerSecond * j;
|
|
|
|
// Calculate the distance traveled
|
|
int distanceTraveled = speed * (raceTime - j);
|
|
|
|
// If the distance traveled is greater than the distance to beat, update the count of ways to beat the max distance
|
|
if (distanceTraveled > distanceToBeat)
|
|
{
|
|
Console.WriteLine(
|
|
$"Can beat race {i} by holding the button for {j} seconds to travel {distanceTraveled}");
|
|
waysToBeatMaxDistance[i] += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
int result = 0;
|
|
for (int i = 0; i < times.Count; i++)
|
|
{
|
|
if (result == 0)
|
|
{
|
|
result = waysToBeatMaxDistance[i];
|
|
}
|
|
else
|
|
{
|
|
result *= waysToBeatMaxDistance[i];
|
|
}
|
|
}
|
|
|
|
if (expected != null)
|
|
{
|
|
Assert.That(result, Is.EqualTo(expected.Value));
|
|
}
|
|
|
|
Console.WriteLine($"Part 1: {result}");
|
|
}
|
|
|
|
[TestCase(@"Time: 7 15 30
|
|
Distance: 9 40 200", 71503)]
|
|
[TestCase(null, 26499773)] // The actual answer
|
|
public void Part2(string input, int? expected)
|
|
{
|
|
string[] lines = input != null ? input.Split("\n") : realData;
|
|
|
|
string realTime = lines[0].Replace("Time:", "").Replace(" ", "");
|
|
string realDistance = lines[1].Replace("Distance:", "").Replace(" ", "");
|
|
|
|
|
|
List<long> times = new() { long.Parse(realTime) };
|
|
List<long> distances = new() { long.Parse(realDistance) };
|
|
List<int> waysToBeatMaxDistance = new();
|
|
// populate waysToBeatMaxDistance with 0s for the same list length as times
|
|
for (int i = 0; i < times.Count; i++)
|
|
{
|
|
waysToBeatMaxDistance.Add(0);
|
|
}
|
|
|
|
int startingSpeedInMilimetersPerSecond = 0;
|
|
int amountToIncreaseSpeedPerSecondHoldingTheButtonInMilimetersPerSecond = 1;
|
|
|
|
// for each race, determine how many different ways you can beat the maximum distance
|
|
for (int i = 0; i < times.Count; i++)
|
|
{
|
|
long raceTime = times[i];
|
|
long distanceToBeat = distances[i];
|
|
|
|
for (long j = 1; j < raceTime; j++)
|
|
{
|
|
// Hold the button for j seconds
|
|
long speed = startingSpeedInMilimetersPerSecond +
|
|
amountToIncreaseSpeedPerSecondHoldingTheButtonInMilimetersPerSecond * j;
|
|
|
|
// Calculate the distance traveled
|
|
long distanceTraveled = speed * (raceTime - j);
|
|
|
|
// If the distance traveled is greater than the distance to beat, update the count of ways to beat the max distance
|
|
if (distanceTraveled > distanceToBeat)
|
|
{
|
|
// Console.WriteLine($"Can beat race {i} by holding the button for {j} seconds to travel {distanceTraveled}");
|
|
waysToBeatMaxDistance[i] += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
long result = 0;
|
|
for (int i = 0; i < times.Count; i++)
|
|
{
|
|
if (result == 0)
|
|
{
|
|
result = waysToBeatMaxDistance[i];
|
|
}
|
|
else
|
|
{
|
|
result *= waysToBeatMaxDistance[i];
|
|
}
|
|
}
|
|
|
|
if (expected != null)
|
|
{
|
|
Assert.That(result, Is.EqualTo(expected.Value));
|
|
}
|
|
|
|
Console.WriteLine($"Part 2: {result}");
|
|
}
|
|
}
|