Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day 5 2023 Solution #2

Merged
merged 1 commit into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions AdventOfCode.Solutions/Helpers/EnumerableHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace AdventOfCode.Solutions.Helpers;
public static class EnumerableHelper
{
public static IEnumerable<long> LongRange(long start, long length)
{
var limit = start + length;

while (start < limit)
{
yield return start;
start++;
}
}
}
121 changes: 121 additions & 0 deletions AdventOfCode.Solutions/_2023/Day5.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using AdventOfCode.Domain.Interfaces;
using AdventOfCode.Solutions.Helpers;
using System.Text.RegularExpressions;

namespace AdventOfCode.Solutions._2023;

public class Day5 : IDay
{
public string Title => "If You Give A Seed A Fertilizer";

public string PartA(string input)
{
var inputSections = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries);

var seeds = Regex.Match(inputSections[0], @"seeds: ((?:(?:\d+) *)*)", RegexOptions.Compiled)
.Groups[1]
.Value
.Split(' ')
.Select(long.Parse);

var seedToSoilMap = DeserializeInputToMap(inputSections[1]);
var soilToFertilizerMap = DeserializeInputToMap(inputSections[2]);
var fertilizerToWaterMap = DeserializeInputToMap(inputSections[3]);
var waterToLightMap = DeserializeInputToMap(inputSections[4]);
var lightToTemperatureMap = DeserializeInputToMap(inputSections[5]);
var temperatureToHumidityMap = DeserializeInputToMap(inputSections[6]);
var humidityToLocationMap = DeserializeInputToMap(inputSections[7]);

var smallestLocation = long.MaxValue;

foreach (var seed in seeds)
{
long soil = DestinationFromSourceNumber(seedToSoilMap, seed);
long fetilizer = DestinationFromSourceNumber(soilToFertilizerMap, soil);
long water = DestinationFromSourceNumber(fertilizerToWaterMap, fetilizer);
long light = DestinationFromSourceNumber(waterToLightMap, water);
long temperature = DestinationFromSourceNumber(lightToTemperatureMap, light);
long humidity = DestinationFromSourceNumber(temperatureToHumidityMap, temperature);
long location = DestinationFromSourceNumber(humidityToLocationMap, humidity);

if (location < smallestLocation)
{
smallestLocation = location;
}
}

return smallestLocation.ToString();
}

public string PartB(string input)
{
var inputSections = input.Split("\n\n", StringSplitOptions.RemoveEmptyEntries);

var seedRanges = Regex.Match(inputSections[0], @"seeds: ((?:(?:\d+) *)*)", RegexOptions.Compiled)
.Groups[1]
.Value
.Split(' ')
.Select(long.Parse);

var seeds = new List<long>();

for (int i = 0; i < seedRanges.Count(); i += 2)
{
seeds.AddRange(EnumerableHelper.LongRange(seedRanges.ElementAt(i), seedRanges.ElementAt(i + 1)));
}

var seedToSoil = DeserializeInputToMap(inputSections[1]);
var soilToFertilizer = DeserializeInputToMap(inputSections[2]);
var fertilizerToWater = DeserializeInputToMap(inputSections[3]);
var waterToLight = DeserializeInputToMap(inputSections[4]);
var lightToTemperature = DeserializeInputToMap(inputSections[5]);
var temperatureToHumidity = DeserializeInputToMap(inputSections[6]);
var humidityToLocation = DeserializeInputToMap(inputSections[7]);

var smallestLocation = long.MaxValue;

foreach (var seed in seeds)
{
long soil = DestinationFromSourceNumber(seedToSoil, seed);
long fetilizer = DestinationFromSourceNumber(soilToFertilizer, soil);
long water = DestinationFromSourceNumber(fertilizerToWater, fetilizer);
long light = DestinationFromSourceNumber(waterToLight, water);
long temperature = DestinationFromSourceNumber(lightToTemperature, light);
long humidity = DestinationFromSourceNumber(temperatureToHumidity, temperature);
long location = DestinationFromSourceNumber(humidityToLocation, humidity);

if (location < smallestLocation)
{
smallestLocation = location;
}
};

return smallestLocation.ToString();
}

private static long DestinationFromSourceNumber(List<(long, long, long)> sourceToDestinationMap, long source)
{
foreach ((long destinationRangeStart,
long sourceRangeStart,
long rangeLength) in sourceToDestinationMap
.Select(x => (destinationRangeStart: x.Item1, sourceRangeStart: x.Item2, rangeLength: x.Item3))
.Where(x => source >= x.sourceRangeStart && source <= x.sourceRangeStart + x.rangeLength))
{
return source + (destinationRangeStart - sourceRangeStart);
}

return source;
}

private static List<(long, long, long)> DeserializeInputToMap(string input)
{
var inputMapRegex = @"(?:(\d+) (\d+) (\d+))";

return Regex.Matches(input, inputMapRegex, RegexOptions.Compiled)
.Select(a => (
destinationRangeStart: long.Parse(a.Groups[1].Value),
sourceRangeStart: long.Parse(a.Groups[2].Value),
rangeLength: long.Parse(a.Groups[3].Value)))
.ToList();
}
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Feel free to run through the solutions (*Note: Potential Spoilers* :see_no_evil:
|2020|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|||||||
|2021|:star2:|:star2:|||||||||||||||||||||||
|2022|||||||||||||||||||||||||
|2023|:star2:|:star2:|:star2:|:star2:|||||||||||||||||||||
|2023|:star2:|:star2:|:star2:|:star2:|:star2:||||||||||||||||||||

<!-- GETTING STARTED -->
## Getting Started
Expand Down
30 changes: 30 additions & 0 deletions Tests/AdventOfCode.Solutions.Tests/_2023/Day5Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace AdventOfCode.Solutions.Tests._2023;

public class Day5Tests : DayTests
{
[Test]
public async Task PartA()
{
// Arrange
string expected = "26273516";

// Act
var solution = await _solverService.SolveDay(2023, 5);

// Assert
solution.PartA.Solution.Should().Be(expected);
}

[Test]
public async Task PartB()
{
// Arrange
string expected = "34039469";

// Act
var solution = await _solverService.SolveDay(2023, 5);

// Assert
solution.PartB.Solution.Should().Be(expected);
}
}