Files
AdventOfCode/AdventOfCode/Problems/AOC2023/Day7/CamelHand.cs
2023-12-07 19:28:00 -05:00

107 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2023.Day7;
internal class CamelHand : IComparable<CamelHand>
{
public static readonly List<char> CARDS = [ '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' ];
public static readonly List<char> CARDS_JOKER = [ 'J', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A' ];
public string Hand { get; set; }
public int Bid { get; set; }
public int Value { get; set; }
public HandType Type { get; set; }
public CamelHand(string data, bool useJoker = false)
{
var split = data.Split(' ');
Hand = split[0];
Bid = int.Parse(split[1]);
Type = useJoker ? GetJokerHandType(Hand) : GetHandType(Hand);
Value = CalculateValue(Hand, useJoker);
}
public static int CalculateValue(string hand, bool useJoker)
{
var total = 0;
for (int i = 0; i < hand.Length; i++)
{
var p = (hand.Length - i - 1);
var v = useJoker ? CARDS_JOKER.IndexOf(hand[i]) : CARDS.IndexOf(hand[i]);
total += (v + 1) * (int)Math.Pow(13, p);
}
return total;
}
public bool IsStrongerThan(CamelHand card)
{
if (Type > card.Type)
return true;
if(Type < card.Type)
return false;
return Value >= card.Value;
}
private static HandType GetJokerHandType(string hand)
{
var type = GetHandType(hand);
if (type == HandType.FiveOfKind)
return type;
if (!hand.Contains('J'))
return type;
var bestCard = hand.GroupBy(c => c)
.OrderByDescending(c => c.Count())
.First(c => c.Key != 'J').Key;
var newHand = hand.Replace('J', bestCard);
return GetHandType(newHand);
}
private static HandType GetHandType(string hand)
{
var cardGroups = hand.GroupBy(c => c).Select(g => g.Count()).ToArray();
if (cardGroups.Length == 1)
return HandType.FiveOfKind;
if(cardGroups.Contains(4))
return HandType.FourOfKind;
if (cardGroups.Contains(3) && cardGroups.Contains(2))
return HandType.FullHouse;
if(cardGroups.Contains(3))
return HandType.ThreeOfKind;
var pairs = cardGroups.Count(c => c == 2);
if (pairs == 2)
return HandType.TwoPair;
if (pairs == 1)
return HandType.OnePair;
return HandType.HighCard;
}
public int CompareTo(CamelHand? other)
{
if(other == null) return 1;
return IsStrongerThan(other) ? 1 : -1;
}
public override string ToString()
{
return $"[{Value}] {Hand}: {Type} | {Bid}";
}
public enum HandType
{
HighCard,
OnePair,
TwoPair,
ThreeOfKind,
FullHouse,
FourOfKind,
FiveOfKind
}
}