-
Notifications
You must be signed in to change notification settings - Fork 0
/
p054.scala
73 lines (62 loc) · 2.09 KB
/
p054.scala
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
import Function.tupled
object p054 {
class Hand (val cards: Array[String]) extends Ordered[Hand] {
val CARD_VALUES = "23456789TJQKA".toArray
val HAND_RANKS = Array (
"HighCard",
"OnePair",
"TwoPair",
"ThreeKind",
"Straight",
"Flush",
"FullHouse",
"FourKind",
"StraightFlush")
val values = for (c <- cards) yield (CARD_VALUES.indexOf(c(0)) + 1)
val suits = for (c <- cards) yield c(1)
lazy val rank: Int = HAND_RANKS.indexOf {
val distinct = values.toSet.size
lazy val longest = (
for ((_, group) <- values.groupBy(identity)) yield group.length
).max
distinct match {
case 2 => if (longest == 4) "FourKind" else "FullHouse"
case 3 => if (longest == 3) "ThreeKind" else "TwoPair"
case 4 => "OnePair"
case 5 => {
val straight = values.max - values.min == 4
val flush = suits.toSet.size == 1
if (straight && flush) "StraightFlush"
else if (straight) "Straight"
else if (flush) "flush"
else "HighCard"
}
}
}
override def compare(that: Hand): Int = {
def tiebreakers(values: Array[Int]) = {
def groupScore(value: Int, group: Array[Int]) =
value * math.pow(CARD_VALUES.length+1, group.length-1).toInt
(values groupBy identity map tupled(groupScore)).toArray.sorted.reverse
}
if (this.rank == that.rank) {
val (thisTiebreaker, thatTiebreaker) =
(tiebreakers(this.values) zip tiebreakers(that.values)
dropWhile tupled(_ == _)).head
thisTiebreaker - thatTiebreaker
} else {
this.rank - that.rank
}
}
}
def main(args: Array[String]) {
val filename = if (args.nonEmpty) args(0) else "p054.txt"
val t0 = System.nanoTime / 1000000
val ans = (io.Source.fromFile(filename).getLines map (_.split(' '))
map (cards => (new Hand(cards.slice(0,5)), new Hand(cards.slice(5,10))))
filter tupled(_ > _)).length
val t1 = System.nanoTime / 1000000
println(t1 - t0)
println(ans)
}
}