HAND_STRENGTH = [ [5], # five of a kind [1, 4], # four of a kind [2, 3], # full house [1, 1, 3], # three of a kind [1, 2, 2], # two pair [1, 1, 1, 2], # one pair [1, 1, 1, 1, 1], # high card ].reverse.each.with_index.to_h { [_1, _2] } module PartOne CARD_STRENGTH = ((?2..?9).to_a + %w[ T J Q K A ]).each.with_index.to_h def self.strength(cards) tally = cards.tally strengths = [ HAND_STRENGTH.fetch(tally.values.sort), *cards.map { CARD_STRENGTH.fetch(_1) }, ] strengths.map { (?a.ord + _1).chr }.join end end module PartTwo CARD_STRENGTH = ([?J] + (?2..?9).to_a + %w[ T Q K A ]).each.with_index.to_h def self.strength(cards) tally = cards.tally jokers = tally.delete(?J) || 0 counts = tally.values.sort if counts.empty? counts = [5] else counts[-1] += jokers end strengths = [ HAND_STRENGTH.fetch(counts), *cards.map { CARD_STRENGTH.fetch(_1) }, ] strengths.map { (?a.ord + _1).chr }.join end end hands = ARGF.read.scan(/(\w+)\s+(\d+)/).to_h { [_1.chars, _2.to_i ] } p hands # .sort_by {|(hand,_)| PartOne::strength(hand) } .sort_by {|(hand,_)| PartTwo::strength(hand) } .map.with_index {|(_,bid),i| bid * (i+1) } .sum