mirror of
https://github.com/parnic/advent-of-code-2023.git
synced 2025-06-16 16:50:14 -05:00
Day 7
I probably should have just tried replacing the J's with every possible card, but alas...this terrible thing works.
This commit is contained in:
@ -42,6 +42,8 @@
|
|||||||
<EmbeddedResource Include="inputs\05a.txt" />
|
<EmbeddedResource Include="inputs\05a.txt" />
|
||||||
<EmbeddedResource Include="inputs\06.txt" />
|
<EmbeddedResource Include="inputs\06.txt" />
|
||||||
<EmbeddedResource Include="inputs\06a.txt" />
|
<EmbeddedResource Include="inputs\06a.txt" />
|
||||||
|
<EmbeddedResource Include="inputs\07.txt" />
|
||||||
|
<EmbeddedResource Include="inputs\07a.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
1000
inputs/07.txt
Normal file
1000
inputs/07.txt
Normal file
File diff suppressed because it is too large
Load Diff
5
inputs/07a.txt
Normal file
5
inputs/07a.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
32T3K 765
|
||||||
|
T55J5 684
|
||||||
|
KK677 28
|
||||||
|
KTJJT 220
|
||||||
|
QQQJA 483
|
244
src/07.cs
Normal file
244
src/07.cs
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using aoc2023.Util;
|
||||||
|
using Math = System.Math;
|
||||||
|
|
||||||
|
namespace aoc2023;
|
||||||
|
|
||||||
|
internal class Day07 : Day
|
||||||
|
{
|
||||||
|
private static readonly char[] order = new[]
|
||||||
|
{
|
||||||
|
'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'
|
||||||
|
};
|
||||||
|
|
||||||
|
private Dictionary<List<int>, int> hands = new();
|
||||||
|
|
||||||
|
internal override void Parse()
|
||||||
|
{
|
||||||
|
var lines = Util.Parsing.ReadAllLines($"{GetDay()}");
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
var split = line.Split(' ');
|
||||||
|
List<int> hand = new();
|
||||||
|
foreach (var card in split[0])
|
||||||
|
{
|
||||||
|
hand.Add(order.IndexOf(card));
|
||||||
|
}
|
||||||
|
|
||||||
|
hands.Add(hand, int.Parse(split[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetHandValue(List<int> hand)
|
||||||
|
{
|
||||||
|
Dictionary<int, int> cardCounts = new();
|
||||||
|
foreach (var card in hand)
|
||||||
|
{
|
||||||
|
if (!cardCounts.TryAdd(card, 1))
|
||||||
|
{
|
||||||
|
cardCounts[card]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// five of a kind
|
||||||
|
if (cardCounts.Count == 1)
|
||||||
|
{
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// four of a kind
|
||||||
|
if (cardCounts.Any(c => c.Value == 4))
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// full house
|
||||||
|
if (cardCounts.Count == 2 && cardCounts.ContainsValue(2) && cardCounts.ContainsValue(3))
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// three of a kind
|
||||||
|
if (cardCounts.Count == 3 && cardCounts.ContainsValue(3) && cardCounts.Count(c => c.Value == 1) == 2)
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// two pair
|
||||||
|
if (cardCounts.Count(c => c.Value == 2) == 2 && cardCounts.ContainsValue(1))
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// one pair
|
||||||
|
if (cardCounts.Count(c => c.Value == 2) == 1 && cardCounts.Count(c => c.Value == 1) == 3)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetHandValuePart2(List<int> hand)
|
||||||
|
{
|
||||||
|
Dictionary<int, int> cardCounts = new();
|
||||||
|
int numWilds = 0;
|
||||||
|
foreach (var card in hand)
|
||||||
|
{
|
||||||
|
if (card == -1)
|
||||||
|
{
|
||||||
|
numWilds++;
|
||||||
|
}
|
||||||
|
else if (!cardCounts.TryAdd(card, 1))
|
||||||
|
{
|
||||||
|
cardCounts[card]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numWilds == 0)
|
||||||
|
{
|
||||||
|
return GetHandValue(hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
// five of a kind
|
||||||
|
if (cardCounts.Any(c => c.Value + numWilds == 5) || numWilds == 5)
|
||||||
|
{
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// four of a kind
|
||||||
|
if (cardCounts.Any(c => c.Value + numWilds == 4))
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// full house
|
||||||
|
{
|
||||||
|
int wilds = numWilds;
|
||||||
|
bool hasTwo = false;
|
||||||
|
bool hasThree = false;
|
||||||
|
foreach (var cc in cardCounts)
|
||||||
|
{
|
||||||
|
if (cc.Value + wilds >= 3 && !hasThree)
|
||||||
|
{
|
||||||
|
wilds -= Math.Max(0, 3 - cc.Value);
|
||||||
|
hasThree = true;
|
||||||
|
}
|
||||||
|
else if (cc.Value + wilds >= 2 && !hasTwo)
|
||||||
|
{
|
||||||
|
wilds -= Math.Max(0, 2 - cc.Value);
|
||||||
|
hasTwo = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasTwo && hasThree)
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// three of a kind
|
||||||
|
if (cardCounts.Any(c => c.Value + numWilds == 3))
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// one pair
|
||||||
|
if (cardCounts.Count(c => c.Value == 2) == 1 || numWilds >= 1)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandWinsTie(List<int> hand, List<int> other)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < hand.Count; j++)
|
||||||
|
{
|
||||||
|
if (hand[j] > other[j])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other[j] > hand[j])
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<(List<int> hand, int bet, int value)> SortHands(Dictionary<List<int>, int> h, Func<List<int>, int> valueFunc)
|
||||||
|
{
|
||||||
|
List<(List<int> hand, int bet, int value)> ordered = new();
|
||||||
|
foreach (var hand in h)
|
||||||
|
{
|
||||||
|
bool inserted = false;
|
||||||
|
var value = valueFunc(hand.Key);
|
||||||
|
for (int i = 0; i < ordered.Count && !inserted; i++)
|
||||||
|
{
|
||||||
|
if (value > ordered[i].value)
|
||||||
|
{
|
||||||
|
ordered.Insert(i, (hand.Key, hand.Value, value));
|
||||||
|
inserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == ordered[i].value)
|
||||||
|
{
|
||||||
|
if (HandWinsTie(hand.Key, ordered[i].hand))
|
||||||
|
{
|
||||||
|
ordered.Insert(i, (hand.Key, hand.Value, value));
|
||||||
|
inserted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inserted)
|
||||||
|
{
|
||||||
|
ordered.Add((hand.Key, hand.Value, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ordered;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override string Part1()
|
||||||
|
{
|
||||||
|
var ordered = SortHands(hands, GetHandValue);
|
||||||
|
long total = 0;
|
||||||
|
for (int i = 0; i < ordered.Count; i++)
|
||||||
|
{
|
||||||
|
total += (ordered.Count - i) * ordered[i].bet;
|
||||||
|
}
|
||||||
|
return $"Total winnings: <+white>{total}";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override string Part2()
|
||||||
|
{
|
||||||
|
Dictionary<List<int>, int> handsp2 = [];
|
||||||
|
foreach (var hand in hands)
|
||||||
|
{
|
||||||
|
var l = new List<int>(hand.Key);
|
||||||
|
for (int i = 0; i < l.Count; i++)
|
||||||
|
{
|
||||||
|
if (l[i] == order.IndexOf('J'))
|
||||||
|
{
|
||||||
|
l[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handsp2.Add(l, hand.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ordered = SortHands(handsp2, GetHandValuePart2);
|
||||||
|
long total = 0;
|
||||||
|
for (int i = 0; i < ordered.Count; i++)
|
||||||
|
{
|
||||||
|
total += (ordered.Count - i) * ordered[i].bet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"Total winnings: <+white>{total}";
|
||||||
|
}
|
||||||
|
}
|
@ -11,4 +11,17 @@ public static class Extensions
|
|||||||
list.Add(elem);
|
list.Add(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int IndexOf<T>(this ICollection<T> list, T elem) where T : IEquatable<T>
|
||||||
|
{
|
||||||
|
for (int idx = 0; idx < list.Count; idx++)
|
||||||
|
{
|
||||||
|
if (list.ElementAt(idx).Equals(elem))
|
||||||
|
{
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user