Skip to content

Commit

Permalink
Merge pull request #5 from tiberiushunter/day8-2023
Browse files Browse the repository at this point in the history
Add Day 8 2023 Solution
  • Loading branch information
tiberiushunter authored Dec 12, 2023
2 parents 5c1b5c7 + c182a45 commit 9f96106
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 48 deletions.
25 changes: 25 additions & 0 deletions AdventOfCode.Solutions/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace AdventOfCode.Solutions.Extensions;
public static class EnumerableExtensions
{
public static IEnumerable<long> LongRange(long start, long length)
{
var limit = start + length;

while (start < limit)
{
yield return start;
start++;
}
}

public static IEnumerable<T> InfiniteSelect<T>(this IEnumerable<T> source)
{
while (true)
{
foreach (T item in source)
{
yield return item;
}
}
}
}
14 changes: 0 additions & 14 deletions AdventOfCode.Solutions/Helpers/EnumerableHelper.cs

This file was deleted.

6 changes: 3 additions & 3 deletions AdventOfCode.Solutions/_2020/Day15.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public string PartA(string input)
{
var startingNumbers = input
.Split(',')
.Select(n => int.Parse(n))
.Select(int.Parse)
.ToArray();

return GetSpokenNumberAtTurn(startingNumbers, 2020).ToString();
Expand All @@ -20,13 +20,13 @@ public string PartB(string input)
{
var startingNumbers = input
.Split(',')
.Select(n => int.Parse(n))
.Select(int.Parse)
.ToArray();

return GetSpokenNumberAtTurn(startingNumbers, 30000000).ToString();
}

private int GetSpokenNumberAtTurn(int[] startingNumbers, int numberOfTurns)
private static int GetSpokenNumberAtTurn(int[] startingNumbers, int numberOfTurns)
{
int[] spokenNumbers = new int[numberOfTurns];
int currentNumber = 0;
Expand Down
45 changes: 23 additions & 22 deletions AdventOfCode.Solutions/_2020/Day7.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using AdventOfCode.Domain.Interfaces;
using AdventOfCode.Solutions.Helpers;
using System.Text.RegularExpressions;
using System.Linq;

namespace AdventOfCode.Solutions._2020;

Expand All @@ -17,13 +18,9 @@ public string PartA(string input)

foreach (var bag in bags)
{
foreach (var innerBag in bag.InnerBags)
{
if (innerBag.Colour == "shiny gold")
{
suspects.Add(bag);
}
}
suspects.AddRange(from innerBag in bag.InnerBags
where innerBag.Colour == "shiny gold"
select bag);
}

while (bagCount != suspects.Count)
Expand Down Expand Up @@ -61,9 +58,10 @@ public string PartB(string input)
{
if (bag.Colour == "shiny gold")
{
foreach (var innerBag in bag.InnerBags)
for (int i = 0; i < bag.InnerBags.Count; i++)
{
for (int i = 0; i < innerBag.NumberOfBags; i++)
var innerBag = bag.InnerBags[i];
for (int j = 0; j < innerBag.InnerBags.Count; j++)
{
nextLevelBags.Add(innerBag);
bagCount++;
Expand All @@ -82,7 +80,7 @@ public string PartB(string input)
{
foreach (Bag innerBag in bag.InnerBags)
{
for (int j = 0; j < innerBag.NumberOfBags; j++)
for (int j = 0; j < innerBag.InnerBags.Count; j++)
{
currentLevelBags.Add(innerBag);
bagCount++;
Expand All @@ -93,7 +91,7 @@ public string PartB(string input)
}

nextLevelBags = currentLevelBags;
currentLevelBags = new List<Bag>();
currentLevelBags = [];
}

return bagCount.ToString();
Expand All @@ -110,14 +108,23 @@ private static List<Bag> GenerateBags(string[] input)
var match = bagRegex.Match(line);
if (match.Success)
{
string[] innerBags = match.Groups[2].Value.Split(new char[] { ',', '.' }, StringSplitOptions.RemoveEmptyEntries);
string[] innerBags = match.Groups[2].Value.Split(",.".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var innerBagsList = new List<Bag>(innerBags.Length);

for (int i = 0; i < innerBags.Length; i++)
{
string[] innerBagDetails = innerBags[i].Trim().Split(" ");
innerBagsList.Add(new Bag(int.Parse(innerBagDetails[0]), innerBagDetails[1] + " " + innerBagDetails[2]));

var innerBagInnerBags = new List<Bag>();

for (int j = 0; j < int.Parse(innerBagDetails[0]); j++)
{
innerBagInnerBags.Add(new Bag());
}

innerBagsList.Add(new Bag(innerBagDetails[1] + " " + innerBagDetails[2], innerBagInnerBags));
}

bags.Add(new Bag(match.Groups[1].Value, innerBagsList));
}
}
Expand All @@ -126,19 +133,13 @@ private static List<Bag> GenerateBags(string[] input)

internal class Bag
{
public int NumberOfBags;
public string Colour { get; set; }
public List<Bag> InnerBags;
public string? Colour { get; set; }
public List<Bag> InnerBags { get; set; } = [];

public Bag(int numOfBags, string colour)
{
NumberOfBags = numOfBags;
Colour = colour;
}
public Bag() { }

public Bag(string colour, List<Bag> innerBags)
{
NumberOfBags = 1;
Colour = colour;
InnerBags = innerBags;
}
Expand Down
4 changes: 2 additions & 2 deletions AdventOfCode.Solutions/_2023/Day5.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using AdventOfCode.Domain.Interfaces;
using AdventOfCode.Solutions.Helpers;
using AdventOfCode.Solutions.Extensions;
using System.Text.RegularExpressions;

namespace AdventOfCode.Solutions._2023;
Expand Down Expand Up @@ -61,7 +61,7 @@ public string PartB(string input)

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

var seedToSoil = DeserializeInputToMap(inputSections[1]);
Expand Down
12 changes: 6 additions & 6 deletions AdventOfCode.Solutions/_2023/Day7.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public string PartA(string input)

List<Hand> hands = sets
.Select(set => set.Split(' '))
.Select(set => new Hand(
int.Parse(set[1]),
set[0].Select(card => CharCardToPlayingCard(card)).ToList())).ToList();
.Select(hand => new Hand(
int.Parse(hand[1]),
hand[0].Select(card => CharCardToPlayingCard(card)).ToList())).ToList();

List<Hand>[] handTypes = [[], [], [], [], [], [], []];

Expand Down Expand Up @@ -44,9 +44,9 @@ public string PartB(string input)

List<Hand> hands = sets
.Select(set => set.Split(' '))
.Select(set => new Hand(
int.Parse(set[1]),
set[0].Select(card => CharCardToPlayingCardJokerWildCards(card)).ToList())).ToList();
.Select(hand => new Hand(
int.Parse(hand[1]),
hand[0].Select(card => CharCardToPlayingCardJokerWildCards(card)).ToList())).ToList();

List<Hand>[] handTypes = [[], [], [], [], [], [], []];

Expand Down
106 changes: 106 additions & 0 deletions AdventOfCode.Solutions/_2023/Day8.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
using AdventOfCode.Domain.Interfaces;
using AdventOfCode.Solutions.Extensions;
using System.Text.RegularExpressions;

namespace AdventOfCode.Solutions._2023;

public class Day8 : IDay
{
public string Title => "Haunted Wasteland";

public string PartA(string input)
{
var parsedInput = input.Split("\n\n");

var instructions = parsedInput[0].ToCharArray();

var network = parsedInput[1]
.Split("\n")
.Select(line => Regex.Match(line, @"([A-Z]+) = \(([A-Z]+), ([A-Z]+)\)", RegexOptions.Compiled))
.ToDictionary(match => match.Groups[1].Value, match => (match.Groups[2].Value, match.Groups[3].Value));

var currentNode = "AAA";
int counter = 0;

foreach (var instruction in instructions.InfiniteSelect())
{
counter++;
switch (instruction)
{
case 'L':
currentNode = network[currentNode].Item1;
break;
case 'R':
currentNode = network[currentNode].Item2;
break;
}

if (currentNode == "ZZZ")
{
break;
}
}

return counter.ToString();
}

public string PartB(string input)
{
var parsedInput = input.Split("\n\n");

var instructions = parsedInput[0].ToCharArray();

var network = parsedInput[1]
.Split("\n")
.Select(line => Regex.Match(line, @"([A-Z]+) = \(([A-Z]+), ([A-Z]+)\)", RegexOptions.Compiled))
.ToDictionary(match => match.Groups[1].Value, match => (match.Groups[2].Value, match.Groups[3].Value));

var currentNodes = network.Where(a => a.Key.EndsWith("A")).Select(a => a.Key).ToList();
var minimumStepsForEachPath = new long[currentNodes.Count];

int counter = 0;

foreach (var instruction in instructions.InfiniteSelect())
{
counter++;

switch (instruction)
{
case 'L':
for (int i = 0; i < currentNodes.Count; i++)
{
currentNodes[i] = network[currentNodes[i]].Item1;
}
break;
case 'R':
for (int i = 0; i < currentNodes.Count; i++)
{
currentNodes[i] = network[currentNodes[i]].Item2;
}
break;
}

for (int i = 0; i < currentNodes.Count; i++)
{
if (currentNodes[i].EndsWith('Z') && minimumStepsForEachPath[i] == 0)
{
minimumStepsForEachPath[i] = counter;
}
}

if (minimumStepsForEachPath.All(a => a > 0))
{
break;
}
}

return minimumStepsForEachPath.Aggregate((a, b) => a * b / GreatestCommonDivisor(a, b)).ToString();
}

private static long GreatestCommonDivisor(long x, long y)
{
if (y == 0) { return x; }

return GreatestCommonDivisor(y, x % y);
}
}
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:|:star2:|:star2:|:star2:||||||||||||||||||
|2023|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|:star2:|||||||||||||||||

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

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

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

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

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

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

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

0 comments on commit 9f96106

Please sign in to comment.