-
Notifications
You must be signed in to change notification settings - Fork 1
/
Program.cs
116 lines (101 loc) · 3.34 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
using AdventOfCode.Common;
Console.WriteLine($"Part 1: {GetScore("23456789TJQKA", false)}");
Console.WriteLine($"Part 2: {GetScore("J23456789TQKA", true)}");
static int GetScore(string cardOrder, bool jokerEnabled) => Resources.GetInputFileLines()
.Select(line => Hand.FromString(line, cardOrder, jokerEnabled))
.Order()
.Select((hand, rank) => (rank + 1) * hand.Bid)
.Sum();
file record Hand : IComparable
{
private readonly string _hand;
private readonly string _cardOrder;
public int Bid { get; }
public HandType Type { get; }
private Hand(string hand, int bid, string cardOrder, HandType type)
{
_hand = hand;
_cardOrder = cardOrder;
Bid = bid;
Type = type;
}
public int CompareTo(object? obj)
{
if (ReferenceEquals(this, obj))
{
return 0;
}
var hand = obj as Hand ?? throw new Exception();
var t1 = (int)Type;
var t2 = (int)hand.Type;
var cmp = t1.CompareTo(t2);
if (cmp != 0)
{
return cmp;
}
for (var i = 0; i < _hand.Length; ++i)
{
cmp = _cardOrder.IndexOf(_hand[i]).CompareTo(_cardOrder.IndexOf(hand._hand[i]));
if (cmp != 0)
{
return cmp;
}
}
return 0;
}
public static Hand FromString(string definition, string cardOrder, bool jokerEnabled)
{
if (definition.Split(' ') is not [string hand, string bid])
{
throw new ArgumentException("Invalid definition", nameof(definition));
}
return new Hand(hand, int.Parse(bid), cardOrder, GetType(hand, cardOrder, jokerEnabled));
}
private static HandType GetType(string hand, string cardOrder, bool jokerEnabled)
{
var histogram = new int[cardOrder.Length];
int max = 0;
for (int i = 0; i < hand.Length; i++)
{
var index = cardOrder.IndexOf(hand[i]);
histogram[index] += 1;
max = Math.Max(histogram[index], max);
}
return (max, jokerEnabled ? histogram[0] : 0) switch
{
(5, _) => HandType.FiveOfAkind,
(4, 0) => HandType.FourOfaKind,
(4, _) => HandType.FiveOfAkind,
(3, 3) => histogram.Contains(2)
? HandType.FiveOfAkind
: HandType.FourOfaKind,
(3, 2) => HandType.FiveOfAkind,
(3, 1) => HandType.FourOfaKind,
(3, 0) => histogram.Contains(2)
? HandType.FullHouse
: HandType.ThreeOfaKind,
(2, 2) => histogram.Where(c => c == 2).Count() == 2
? HandType.FourOfaKind
: HandType.ThreeOfaKind,
(2, 1) => histogram.Where(c => c == 2).Count() == 2
? HandType.FullHouse
: HandType.ThreeOfaKind,
(2, 0) => histogram.Where(c => c == 2).Count() == 2
? HandType.TwoPairs
: HandType.OnePair,
(1, 1) => HandType.OnePair,
(1, 0) => HandType.HighCard,
_ => throw new InvalidOperationException(),
};
}
}
file enum HandType
{
HighCard = 1,
OnePair = 2,
TwoPairs = 3,
ThreeOfaKind = 4,
FullHouse = 5,
FourOfaKind = 6,
FiveOfAkind = 7,
}