class Cards
class Card
attr_reader :suit, :rank
def initialize(suit, rank)
@suit = suit
@rank = rank
end
end
attr_reader :suits, :ranks
def initialize(cards)
@cards = cards.map{|e| e.kind_of?(Card) ? e : Card.new(*e)}
@ranks = @cards.map(&:rank).sort
@suits = @cards.map(&:suit)
end
def same_rank_counts
same_ranks = ranks.group_by{|r|r}.values
same_ranks.map(&:size).sort.reverse
end
def straight?
steps = ranks.map{|r|r-ranks[0]}
steps==[0,1,2,3,4] || steps==[0,9,10,11,12]
end
def flush?
suits.uniq.size == 1
end
def hand
case same_rank_counts
when [2,1,1,1]
:one_pair
when [2,2,1]
:two_pair
when [3,1,1]
:three_of_a_kind
when [3,2]
:full_house
when [4,1]
:four_of_a_kind
else
case [straight?, flush?]
when [true, false]
:straight
when [false, true]
:flush
when [true, true]
if ranks == [1,10,11,12,13]
:royal_flush
else
:straight_flush
end
else
:hi_card
end
end
end
end
if __FILE__ == $0
ranks = (1..13).to_a
suits = [:spade,:heart,:diamond,:club]
all_cards = suits.product(ranks)
result = Hash.new(0)
all_cards.combination(5).each_with_index{|a, i|
cards = Cards.new(a)
result[cards.hand] += 1
p result if i%100000 == 0
}
p result
end