parent
9b6dd4cc53
commit
cc41e835ac
@ -1,77 +1,50 @@
|
|||||||
module PartOne
|
HAND_STRENGTH = [
|
||||||
CARD_ORDER = ((?2..?9).to_a + %w[ T J Q K A ]).each.with_index.to_h
|
[5], # five of a kind
|
||||||
|
[1, 4], # four of a kind
|
||||||
Card = Data.define(:rank) do
|
[2, 3], # full house
|
||||||
def <=>(other)
|
[1, 1, 3], # three of a kind
|
||||||
CARD_ORDER.fetch(self.rank) <=> CARD_ORDER.fetch(other.rank)
|
[1, 2, 2], # two pair
|
||||||
end
|
[1, 1, 1, 2], # one pair
|
||||||
end
|
[1, 1, 1, 1, 1], # high card
|
||||||
|
].reverse.each.with_index.to_h { [_1, _2] }
|
||||||
|
|
||||||
Hand = Data.define(:cards) do
|
module PartOne
|
||||||
def type
|
CARD_STRENGTH = ((?2..?9).to_a + %w[ T J Q K A ]).each.with_index.to_h
|
||||||
tally = self.cards.tally
|
|
||||||
case tally.values.sort
|
def self.strength(cards)
|
||||||
when [5] then 5 # five of a kind
|
tally = cards.tally
|
||||||
when [1, 4] then 4 # four of a kind
|
strengths = [
|
||||||
when [2, 3] then 3.5 # full house
|
HAND_STRENGTH.fetch(tally.values.sort),
|
||||||
when [1, 1, 3] then 3 # three of a kind
|
*cards.map { CARD_STRENGTH.fetch(_1) },
|
||||||
when [1, 2, 2] then 2.5 # two pair
|
]
|
||||||
when [1, 1, 1, 2] then 2 # one pair
|
strengths.map { (?a.ord + _1).chr }.join
|
||||||
when [1, 1, 1, 1, 1] then 1 # high card
|
|
||||||
else fail "couldn't calculate type: #{self.inspect}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def <=>(other)
|
|
||||||
v = self.type <=> other.type
|
|
||||||
v.zero? ? self.cards <=> other.cards : v
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module PartTwo
|
module PartTwo
|
||||||
CARD_ORDER = ([?J] + (?2..?9).to_a + %w[ T Q K A ]).each.with_index.to_h
|
CARD_STRENGTH = ([?J] + (?2..?9).to_a + %w[ T Q K A ]).each.with_index.to_h
|
||||||
|
|
||||||
Card = Data.define(:rank) do
|
def self.strength(cards)
|
||||||
def <=>(other)
|
tally = cards.tally
|
||||||
CARD_ORDER.fetch(self.rank) <=> CARD_ORDER.fetch(other.rank)
|
jokers = tally.delete(?J) || 0
|
||||||
end
|
counts = tally.values.sort
|
||||||
end
|
if counts.empty?
|
||||||
|
counts = [5]
|
||||||
Hand = Data.define(:cards) do
|
else
|
||||||
def type
|
counts[-1] += jokers
|
||||||
tally = self.cards.map(&:rank).tally
|
|
||||||
jokers = tally.delete(?J) || 0
|
|
||||||
counts = tally.values.sort
|
|
||||||
if counts.empty?
|
|
||||||
counts = [5]
|
|
||||||
else
|
|
||||||
counts[-1] += jokers
|
|
||||||
end
|
|
||||||
case counts
|
|
||||||
when [5] then 5 # five of a kind
|
|
||||||
when [1, 4] then 4 # four of a kind
|
|
||||||
when [2, 3] then 3.5 # full house
|
|
||||||
when [1, 1, 3] then 3 # three of a kind
|
|
||||||
when [1, 2, 2] then 2.5 # two pair
|
|
||||||
when [1, 1, 1, 2] then 2 # one pair
|
|
||||||
when [1, 1, 1, 1, 1] then 1 # high card
|
|
||||||
else fail "couldn't calculate type: #{self.inspect}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def <=>(other)
|
|
||||||
v = self.type <=> other.type
|
|
||||||
v.zero? ? self.cards <=> other.cards : v
|
|
||||||
end
|
end
|
||||||
|
strengths = [
|
||||||
|
HAND_STRENGTH.fetch(counts),
|
||||||
|
*cards.map { CARD_STRENGTH.fetch(_1) },
|
||||||
|
]
|
||||||
|
strengths.map { (?a.ord + _1).chr }.join
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
hands = ARGF.read.scan(/(\w+)\s+(\d+)/).to_h {|hand, bid|
|
hands = ARGF.read.scan(/(\w+)\s+(\d+)/).to_h { [_1.chars, _2.to_i ] }
|
||||||
[PartTwo::Hand.new(hand.chars.map { PartTwo::Card.new(_1) }), bid.to_i]
|
|
||||||
}
|
|
||||||
|
|
||||||
p hands
|
p hands
|
||||||
.sort_by(&:first)
|
# .sort_by {|(hand,_)| PartOne::strength(hand) }
|
||||||
|
.sort_by {|(hand,_)| PartTwo::strength(hand) }
|
||||||
.map.with_index {|(_,bid),i| bid * (i+1) }
|
.map.with_index {|(_,bid),i| bid * (i+1) }
|
||||||
.sum
|
.sum
|
||||||
|
Loading…
Reference in new issue