Ну и протрахался же. После one-linerов и простых чисел с факториалами (особенно глупа 53) вдруг бабах - задача чуть ли не на ООП. Да, я нарисовал объекты всякие - Card, Rank, Hand, Game... уже решив, понял, что всё, что нужно - это функция ранжирования, и всё тоже излагается вполне кондово.
val order = "23456789TJQKA"
case class Card(src: String) extends Ordered[Card] {
val v = order.indexOf(src(0))
require(v >= 0)
val s = src(1)
def compare(other: Card) = v compare other.v
}
val ranks = List("SF", "4", "FH", "F", "S", "3", "2+2", "2", "1").reverse
case class Rank(name: String, value: Int) extends Ordered[Rank] {
require(ranks contains name)
def compare(other: Rank) = {
val rc = ranks.indexOf(name) compare ranks.indexOf(other.name)
if (rc != 0) rc else value compare other.value
}
}
case class Hand(cards: List[Card]) extends Ordered[Hand] {
require (cards.size == 5)
val straight = 1 to 4 forall (i => cards(i).v == cards(i-1).v - 1)
val flush = cards.forall(_.s == cards(0).s)
def sameKind(from: Int, n: Int) = ((from+1) to (from+n-1)) forall(i => (cards(i).v == cards(from).v))
val rank: Rank = if (flush && straight) Rank("SF", cards(0).v)
else if (sameKind(0, 4)) Rank("4", cards(0).v)
else if (sameKind(1, 4)) Rank("4", cards(1).v)
else if (sameKind(0, 3) && sameKind(3,2)) Rank("FH", cards(0).v * 100 + cards(3).v)
else if (sameKind(0, 2) && sameKind(2,3)) Rank("FH", cards(2).v * 100 + cards(0).v)
else if (flush) Rank("F", cards(0).v)
else if (straight) Rank("F", cards(0).v)
else if (sameKind(0, 3)) Rank("3", cards(0).v)
else if (sameKind(1, 3)) Rank("3", cards(1).v)
else if (sameKind(2, 3)) Rank("3", cards(2).v)
else if (sameKind(0, 2) && sameKind(2,2)) Rank("2+2", math.max(cards(0).v,cards(2).v) * 10000 + math.min(cards(0).v,cards(2).v))
else if (sameKind(0, 2) && sameKind(3,2)) Rank("2+2", math.max(cards(0).v,cards(3).v) * 10000 + math.min(cards(0).v,cards(3).v))
else if (sameKind(1, 2) && sameKind(3,2)) Rank("2+2", math.max(cards(1).v,cards(3).v) * 10000 + math.min(cards(1).v,cards(3).v))
else if (sameKind(0, 2)) Rank("2", cards(0).v)
else if (sameKind(1, 2)) Rank("2", cards(1).v)
else if (sameKind(2, 2)) Rank("2", cards(2).v)
else if (sameKind(3, 2)) Rank("2", cards(3).v)
else Rank("1", cards(0).v)
def compare(other: Hand) = {
val rc = rank compare other.rank
if (rc != 0) rc else {
val at: Int = (0 to 4 dropWhile (i => 0 == (cards(i) compare other.cards(i)))).head
cards(at).compare(other.cards(at))
}
}
}
def hand(cards: List[String]) = Hand((cards map Card).sorted.reverse)
def game(s: String) = (s split ' ' grouped 5 toList) map (_.toList) map hand
val games = poker split '\n' map game
val firstWins = games count (g => g(0) > g(1))
println("\n\n" + firstWins)