[2023][ruby][7.x] refactoring

main
Alpha Chen 11 months ago
parent 9b6dd4cc53
commit cc41e835ac
Signed by: alpha
SSH Key Fingerprint: SHA256:3fOT8fiYQG/aK9ntivV3Bqtg8AYQ7q4nV6ZgihOA20g

@ -1,46 +1,31 @@
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
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) def self.strength(cards)
v = self.type <=> other.type tally = cards.tally
v.zero? ? self.cards <=> other.cards : v strengths = [
end HAND_STRENGTH.fetch(tally.values.sort),
*cards.map { CARD_STRENGTH.fetch(_1) },
]
strengths.map { (?a.ord + _1).chr }.join
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)
end
end
Hand = Data.define(:cards) do
def type
tally = self.cards.map(&:rank).tally
jokers = tally.delete(?J) || 0 jokers = tally.delete(?J) || 0
counts = tally.values.sort counts = tally.values.sort
if counts.empty? if counts.empty?
@ -48,30 +33,18 @@ module PartTwo
else else
counts[-1] += jokers counts[-1] += jokers
end end
case counts strengths = [
when [5] then 5 # five of a kind HAND_STRENGTH.fetch(counts),
when [1, 4] then 4 # four of a kind *cards.map { CARD_STRENGTH.fetch(_1) },
when [2, 3] then 3.5 # full house ]
when [1, 1, 3] then 3 # three of a kind strengths.map { (?a.ord + _1).chr }.join
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 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…
Cancel
Save