docs: add xml comments
This commit is contained in:
@@ -12,24 +12,49 @@ public class PuzzleSolverTests
|
|||||||
result.Should().Be(expected);
|
result.Should().Be(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(TestData.GetTotalCardCountData), MemberType = typeof(TestData))]
|
||||||
|
public void GetTotalCardCount_GivenCards_ItShouldReturnExpectedValue(string[] cards, int expected)
|
||||||
|
{
|
||||||
|
var result = _sut.GetTotalCardCount(cards);
|
||||||
|
result.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestData
|
public static class TestData
|
||||||
{
|
{
|
||||||
|
private static readonly string[] ExampleInput =
|
||||||
|
[
|
||||||
|
"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53",
|
||||||
|
"Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19",
|
||||||
|
"Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1",
|
||||||
|
"Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83",
|
||||||
|
"Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36",
|
||||||
|
"Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11",
|
||||||
|
];
|
||||||
|
|
||||||
private static string[] Input => File.ReadAllLines("INPUT.txt");
|
private static string[] Input => File.ReadAllLines("INPUT.txt");
|
||||||
|
|
||||||
|
public static IEnumerable<object[]> GetTotalCardCountData =>
|
||||||
|
new List<object[]>
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
ExampleInput,
|
||||||
|
30,
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
Input,
|
||||||
|
5920640,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
public static IEnumerable<object[]> SumCardValuesData =>
|
public static IEnumerable<object[]> SumCardValuesData =>
|
||||||
new List<object[]>
|
new List<object[]>
|
||||||
{
|
{
|
||||||
new object[]
|
new object[]
|
||||||
{
|
{
|
||||||
new[]
|
ExampleInput,
|
||||||
{
|
|
||||||
"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53",
|
|
||||||
"Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19",
|
|
||||||
"Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1",
|
|
||||||
"Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83",
|
|
||||||
"Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36",
|
|
||||||
"Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11",
|
|
||||||
},
|
|
||||||
13,
|
13,
|
||||||
},
|
},
|
||||||
new object[]
|
new object[]
|
||||||
|
|||||||
@@ -19,40 +19,116 @@ public class Program
|
|||||||
var puzzleSolver = new PuzzleSolver();
|
var puzzleSolver = new PuzzleSolver();
|
||||||
|
|
||||||
var input = await File.ReadAllLinesAsync(args[0]);
|
var input = await File.ReadAllLinesAsync(args[0]);
|
||||||
var result = puzzleSolver.SumCardValues(input);
|
var result = args.Length is 2 && args[1] == "part2"
|
||||||
|
? puzzleSolver.GetTotalCardCount(input)
|
||||||
|
: puzzleSolver.SumCardValues(input);
|
||||||
|
|
||||||
Console.WriteLine($"The sum of all card values is {result}.");
|
if (args.Length is 2 && args[1] == "part2")
|
||||||
|
{
|
||||||
|
Console.WriteLine($"The total number of cards is {result}.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"The total value of the cards is {result}.");
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Solves the puzzle.
|
||||||
|
/// </summary>
|
||||||
public class PuzzleSolver
|
public class PuzzleSolver
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Sums the value of the cards.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cards">The cards.</param>
|
||||||
|
/// <returns>The sum of the cards.</returns>
|
||||||
public int SumCardValues(string[] cards) => cards
|
public int SumCardValues(string[] cards) => cards
|
||||||
.Select(Card.Parse)
|
.Select(Card.Parse)
|
||||||
.Sum(c => c.GetCardValue());
|
.Sum(c => c.GetCardValue());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of cards.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cards">The cards.</param>
|
||||||
|
/// <returns>The total number of cards.</returns>
|
||||||
|
public int GetTotalCardCount(string[] cards)
|
||||||
|
{
|
||||||
|
var cardStringsToProcess = new List<string>(cards);
|
||||||
|
|
||||||
|
for (var i = 0; i < cardStringsToProcess.Count; i++)
|
||||||
|
{
|
||||||
|
var currentCardString = cardStringsToProcess[i];
|
||||||
|
var currentCardStringIndex = Array.IndexOf(cards, currentCardString);
|
||||||
|
var currentCard = Card.Parse(currentCardString);
|
||||||
|
var numOfMatchingNumbersForCurrentCard = currentCard.MatchingNumbers.Count;
|
||||||
|
var cardIndexesToCopy = Enumerable.Range(
|
||||||
|
currentCardStringIndex + 1,
|
||||||
|
Math.Min(
|
||||||
|
numOfMatchingNumbersForCurrentCard,
|
||||||
|
cards.Length - currentCardStringIndex - 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach (var index in cardIndexesToCopy)
|
||||||
|
{
|
||||||
|
cardStringsToProcess.Add(cards[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cardStringsToProcess.Count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a card.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The identifier.</param>
|
||||||
|
/// <param name="winningNumbers">The winning numbers.</param>
|
||||||
|
/// <param name="numbers">The numbers.</param>
|
||||||
|
/// <returns>An instance of <see cref="Card"/>.</returns>
|
||||||
public class Card(
|
public class Card(
|
||||||
int id,
|
int id,
|
||||||
List<int> winningNumbers,
|
List<int> winningNumbers,
|
||||||
List<int> numbers
|
List<int> numbers
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the identifier.
|
||||||
|
/// </summary>
|
||||||
public int Id { get; init; } = id;
|
public int Id { get; init; } = id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the winning numbers.
|
||||||
|
/// </summary>
|
||||||
public List<int> WinningNumbers { get; init; } = winningNumbers;
|
public List<int> WinningNumbers { get; init; } = winningNumbers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the numbers.
|
||||||
|
/// </summary>
|
||||||
public List<int> Numbers { get; init; } = numbers;
|
public List<int> Numbers { get; init; } = numbers;
|
||||||
|
|
||||||
public int GetCardValue()
|
/// <summary>
|
||||||
{
|
/// Gets the matching numbers.
|
||||||
var commonNumbers = WinningNumbers.Intersect(Numbers).ToList();
|
/// </summary>
|
||||||
|
public List<int> MatchingNumbers => Numbers.Intersect(WinningNumbers).ToList();
|
||||||
|
|
||||||
return commonNumbers.Count is 1
|
/// <summary>
|
||||||
? 1
|
/// Gets the value of the card.
|
||||||
: (int)Math.Pow(2, commonNumbers.Count - 1);
|
/// </summary>
|
||||||
}
|
/// <returns>The value of the card.</returns>
|
||||||
|
public int GetCardValue() => MatchingNumbers.Count is 1
|
||||||
|
? 1
|
||||||
|
: (int)Math.Pow(2, MatchingNumbers.Count - 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses the specified input.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">The input.</param>
|
||||||
|
/// <returns>An instance of <see cref="Card"/>.</returns>
|
||||||
public static Card Parse(string input)
|
public static Card Parse(string input)
|
||||||
{
|
{
|
||||||
var parts = input.Split(':');
|
var parts = input.Split(':');
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ dotnet run -- <path-to-input-file> part2
|
|||||||
| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/) | ✅ | The trickiest part here was accounting for overlapping digit words. |
|
| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/) | ✅ | The trickiest part here was accounting for overlapping digit words. |
|
||||||
| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/) | ✅ | The key to me here was to parse the input into a useful model. |
|
| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/) | ✅ | The key to me here was to parse the input into a useful model. |
|
||||||
| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/GearRatios/) | ✅ | The edge case that got me here was lines ending with a part number. |
|
| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/GearRatios/) | ✅ | The edge case that got me here was lines ending with a part number. |
|
||||||
| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/Scratchcards/) | ⌛ |
|
| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/Scratchcards/) | ✅ | Part 2 gets out of hand quickly with just 200 cards. |
|
||||||
| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | ⌛ |
|
| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | ⌛ |
|
||||||
| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/) | ⌛ |
|
| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/) | ⌛ |
|
||||||
| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/) | ⌛ |
|
| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/) | ⌛ |
|
||||||
|
|||||||
Reference in New Issue
Block a user