diff --git a/AoC_2025.Runner/Program.cs b/AoC_2025.Runner/Program.cs index d899cd1..252a70e 100644 --- a/AoC_2025.Runner/Program.cs +++ b/AoC_2025.Runner/Program.cs @@ -26,4 +26,10 @@ var day04 = new Day04(); string day04Path = @$"{rootPath}\AoC-PuzzleInputs\2025\Prod\day04.txt"; Console.WriteLine(day04.SolvePart1(day04Path)); Console.WriteLine(day04.SolvePart2(day04Path)); +Console.WriteLine(); + +var day05 = new Day05(); +string day05Path = @$"{rootPath}\AoC-PuzzleInputs\2025\Prod\day05.txt"; +Console.WriteLine(day05.SolvePart1(day05Path)); +Console.WriteLine(day05.SolvePart2(day05Path)); Console.WriteLine(); \ No newline at end of file diff --git a/AoC_2025.Tests/Day05Test.cs b/AoC_2025.Tests/Day05Test.cs new file mode 100644 index 0000000..80d9f28 --- /dev/null +++ b/AoC_2025.Tests/Day05Test.cs @@ -0,0 +1,47 @@ +using AdvenOfCode.Contracts; + +namespace AoC_2025.Tests; + +public class Day05Test +{ + private readonly IPuzzleSolver _sut; + private static readonly string rootPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + private readonly string TestInputPath = @$"{rootPath}\AoC-PuzzleInputs\2025\Test\day05.txt"; + private readonly string ProdInputPath = @$"{rootPath}\AoC-PuzzleInputs\2025\Prod\day05.txt"; + + public Day05Test() + { + _sut = new Day05(); + } + [Fact] + public void Part01_Test_equals_3() + { + var actual = _sut.SolvePart1(TestInputPath); + + Assert.Equal(3, actual); + } + + [Fact] + public void Part01_Prod_equals_635() + { + var actual = _sut.SolvePart1(ProdInputPath); + + Assert.Equal(635, actual); + } + + [Fact] + public void Part02_Test_equals_14() + { + var actual = _sut.SolvePart2(TestInputPath); + + Assert.Equal(14, actual); + } + + [Fact] + public void Part02_Prod_equals_369761800782619() + { + var actual = _sut.SolvePart2(ProdInputPath); + + Assert.Equal(369761800782619, actual); + } +} \ No newline at end of file diff --git a/AoC_2025/Day04.cs b/AoC_2025/Day04.cs index b276e44..91b34b2 100644 --- a/AoC_2025/Day04.cs +++ b/AoC_2025/Day04.cs @@ -95,8 +95,8 @@ public class Day04 : IPuzzleSolver int lessThan) { var coordinatesWithLess = coordinatesWithNeighbours - .Where(entry => entry.neighbours.Count() < lessThan) - .Select(entry => entry.coordinate); + .Where(roll => roll.neighbours.Length < lessThan) + .Select(roll => roll.coordinate); return coordinatesWithLess; } } \ No newline at end of file diff --git a/AoC_2025/Day05.cs b/AoC_2025/Day05.cs new file mode 100644 index 0000000..689d898 --- /dev/null +++ b/AoC_2025/Day05.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using AdvenOfCode.Contracts; +using Range = (long from, long to); + +namespace AoC_2025; + +public class Day05 : IPuzzleSolver +{ + private (List freshIdRanges, List ids) ParsePuzzleInput(string path) + { + var puzzleInput = File.ReadAllLines(path) + .Select(line => line.Trim()) + .ToList(); + var middle = puzzleInput.IndexOf(""); + var freshIdRanges = puzzleInput[..middle]; + var ids = puzzleInput[(middle + 1)..]; + return (freshIdRanges, ids); + } + + public long SolvePart1(string pathToPuzzleInput) + { + var database = ParsePuzzleInput(pathToPuzzleInput); + var freshIdRanges = ParseRanges(database.freshIdRanges); + var ids = ParseIds(database.ids); + var freshIds = FilterFreshIds(ids, freshIdRanges); + return freshIds.Count(); + } + + public long SolvePart2(string pathToPuzzleInput) + { + var database = ParsePuzzleInput(pathToPuzzleInput); + var freshIdRanges = ParseRanges(database.freshIdRanges); + var sumIds = SumIdsInRanges(freshIdRanges); + return sumIds; + } + + private IEnumerable FilterFreshIds(IEnumerable ids, Range[] freshIdRanges) + { + var freshIds = ids.Where(id => IsIdInRanges(id, freshIdRanges)); + return freshIds; + } + + private IEnumerable ParseIds(List ids) + { + var parsedIds = ids.Select(id => long.Parse(id)); + return parsedIds; + } + + private Range[] ParseRanges(IEnumerable ranges) + { + return ranges.Select(range => + { + var split = range.Split('-', StringSplitOptions.RemoveEmptyEntries); + return (long.Parse(split[0]), long.Parse(split[1])); + }) + .OrderBy(range => range.Item1) + .ThenBy(range => range.Item2) + .ToArray(); + } + + private bool IsIdInRanges(long id, IEnumerable ranges) + { + return ranges.Any(range => IsIdInRange(id, range)); + } + + private bool IsIdInRange(long id, Range range) + { + return range.from <= id && range.to >= id; + } + + private long CountIdsInRange(long from, long to) + { + return to - from + 1; + } + + private long SumIdsInRanges(IEnumerable ranges) + { + var sumFreshIds = 0L; + var highestSeenId = -1L; + foreach (var range in ranges) + { + var lowestNewId = Math.Max(highestSeenId + 1, range.from); + highestSeenId = Math.Max(highestSeenId, range.to); + sumFreshIds += Math.Max(0, highestSeenId - lowestNewId + 1); + } + + return sumFreshIds; + } +} \ No newline at end of file