Skip to content

Instantly share code, notes, and snippets.

@waynejo
Last active January 19, 2024 13:06
Show Gist options
  • Save waynejo/68ed1250c8b59073a1e41e816f4c52fe to your computer and use it in GitHub Desktop.
Save waynejo/68ed1250c8b59073a1e41e816f4c52fe to your computer and use it in GitHub Desktop.
import java.io.FileInputStream
import scala.io.StdIn
enum HandType(val index: Int):
case FiveOfAKind extends HandType(0)
case FourOfAKind extends HandType(1)
case FullHouse extends HandType(2)
case ThreeOfAKind extends HandType(3)
case TwoPair extends HandType(4)
case OnePair extends HandType(5)
case HighCard extends HandType(6)
case class Pair(hand: String, bid: Int)
object Pair:
def apply(s: String): Pair =
val Array(hand, bid) = s.split(" ")
Pair(hand, bid.toInt)
def handType(s: String): HandType =
val cardCounts = s.foldLeft(Map.empty[Char, Int])((acc, c) =>
acc.updated(c, acc.getOrElse(c, 0) + 1)
)
val matches = cardCounts.removed('*').values.toVector.sorted.reverse
val wildcardCount = cardCounts.getOrElse('*', 0)
val matchesWithWildCard = if (matches.isEmpty) Vector(wildcardCount) else matches.updated(0, matches(0) + wildcardCount)
matchesWithWildCard match
case Vector(5) => HandType.FiveOfAKind
case Vector(4, 1) => HandType.FourOfAKind
case Vector(3, 2) => HandType.FullHouse
case Vector(3, 1, 1) => HandType.ThreeOfAKind
case Vector(2, 2, 1) => HandType.TwoPair
case Vector(2, 1, 1, 1) => HandType.OnePair
case _ => HandType.HighCard
object HandOrdering extends Ordering[String] {
def compare(a: String, b: String) =
val aHandType = handType(a)
val bHandType = handType(b)
if (aHandType != bHandType) {
aHandType.index.compareTo(bHandType.index)
} else {
val score = "AKQJT98765432*"
val aScore = a.map(c => score.indexOf(c))
val bScore = b.map(c => score.indexOf(c))
aScore.zip(bScore).map(x => x._1.compareTo(x._2)).find(_ != 0).getOrElse(0)
}
}
def solve7_1(inputs: Vector[Pair]): BigInt =
inputs.sortBy(_.hand)(HandOrdering).reverse.zipWithIndex
.map { case (Pair(_, bid), index) => BigInt(bid * (index + 1)) }.sum
def solve7_2(inputs: Vector[Pair]): BigInt =
inputs.map(input => input.copy(hand=input.hand.replaceAll("J", "*"))).sortBy(_.hand)(HandOrdering).reverse.zipWithIndex
.map { case (Pair(_, bid), index) => BigInt(bid * (index + 1)) }.sum
@main def solve7(): Unit =
val in = new FileInputStream("example7-2.in")
System.setIn(in)
val inputs = Iterator.continually(StdIn.readLine())
.takeWhile(line => null != line)
.toVector
println(solve7_1(inputs.map(Pair.apply)))
println(solve7_2(inputs.map(Pair.apply)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment