Finished day 7, part 1!
This commit is contained in:
1 parent
c1731aaff3
commit
abad3d0e51
3 files changed
+1216
No files matched your search
@@ -0,0 +1,166 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module HandTypeName
|
||||
FIVE_OF_A_KIND = 7
|
||||
FOUR_OF_A_KIND = 6
|
||||
FULL_HOUSE = 5
|
||||
THREE_OF_A_KIND = 4
|
||||
TWO_PAIR = 3
|
||||
ONE_PAIR = 2
|
||||
HIGH_CARD = 1
|
||||
|
||||
end
|
||||
|
||||
class HandType
|
||||
def initialize(type_name, card_value)
|
||||
@type_name = type_name
|
||||
@card_value = card_value.split("").sort.join("")
|
||||
end
|
||||
|
||||
def ==(o)
|
||||
o.class == self.class && o.type_name == @type_name && o.card_value == @card_value
|
||||
end
|
||||
|
||||
def <=>(o)
|
||||
@type_name <=> o.type_name
|
||||
end
|
||||
|
||||
attr_accessor :type_name
|
||||
attr_accessor :card_value
|
||||
end
|
||||
|
||||
|
||||
def compare_card(card1, card2)
|
||||
ordered_cards = "AKQJT98765432".reverse
|
||||
if !ordered_cards.include?(card1) || !ordered_cards.include?(card2)
|
||||
raise Exception.new("Unknown card #{card1} or #{card2}")
|
||||
end
|
||||
ordered_cards.index(card1) <=> ordered_cards.index(card2)
|
||||
end
|
||||
|
||||
class Hand
|
||||
def initialize(cards, bid)
|
||||
@cards = cards
|
||||
@bid = bid
|
||||
end
|
||||
|
||||
def _card_map
|
||||
card_map = {}
|
||||
@cards.each_char do |card|
|
||||
if card_map.include? card
|
||||
card_map[card] += 1
|
||||
else
|
||||
card_map[card] = 1
|
||||
end
|
||||
end
|
||||
card_map
|
||||
end
|
||||
|
||||
def _reversed_card_map
|
||||
ret = {}
|
||||
_card_map.each_pair do |key, value|
|
||||
if ret.include? value
|
||||
ret[value].append key
|
||||
else
|
||||
ret[value] = [key]
|
||||
end
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
def _get_five_of_a_kind
|
||||
if _card_map.values.include? 5
|
||||
return HandType.new HandTypeName::FIVE_OF_A_KIND, _reversed_card_map[5][0]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def _get_four_of_a_kind
|
||||
if _card_map.values.include? 4
|
||||
return HandType.new HandTypeName::FOUR_OF_A_KIND, _reversed_card_map[4][0]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def _get_full_house
|
||||
if _card_map.values.include?(3) && _card_map.values.include?(2)
|
||||
return HandType.new HandTypeName::FULL_HOUSE, _reversed_card_map[3][0] + _reversed_card_map[2][0]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def _get_three_of_a_kind
|
||||
if _card_map.values.include?(3)
|
||||
return HandType.new HandTypeName::THREE_OF_A_KIND, _reversed_card_map[3][0]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def _get_two_pairs
|
||||
if _card_map.values.include?(2) && (_reversed_card_map[2].length == 2)
|
||||
return HandType.new HandTypeName::TWO_PAIR, _reversed_card_map[2][0] + _reversed_card_map[2][1]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def _get_one_pair
|
||||
if _card_map.values.include?(2)
|
||||
return HandType.new HandTypeName::ONE_PAIR, _reversed_card_map[2][0]
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def _get_high_card
|
||||
high_card = @cards.split("").sort {|c1, c2| compare_card(c1, c2)} .last
|
||||
HandType.new HandTypeName::HIGH_CARD, high_card
|
||||
end
|
||||
|
||||
def get_type
|
||||
(_get_five_of_a_kind or
|
||||
_get_four_of_a_kind or
|
||||
_get_full_house or
|
||||
_get_three_of_a_kind or
|
||||
_get_two_pairs or
|
||||
_get_one_pair or
|
||||
_get_high_card)
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
if (get_type <=> other.get_type) != 0
|
||||
return get_type <=> other.get_type
|
||||
end
|
||||
((0...5).map {|i| compare_card(@cards[i], other.cards[i])}.drop_while { |v| v == 0}.first) or 0
|
||||
end
|
||||
|
||||
def self.deserialize(line)
|
||||
parts = line.split(/\s+/)
|
||||
self.new parts[0], parts[1].to_i
|
||||
|
||||
end
|
||||
|
||||
|
||||
attr_accessor :cards
|
||||
attr_accessor :bid
|
||||
end
|
||||
|
||||
|
||||
def play_part_1_game(input)
|
||||
input.strip.split("\n")
|
||||
.filter {|line| !line.empty?}
|
||||
.map {|line| Hand.deserialize line}
|
||||
.sort
|
||||
.each_with_index
|
||||
.map {|hand, idx| hand.bid * (idx + 1)}
|
||||
.reduce 0, :+
|
||||
end
|
||||
|
||||
|
||||
|
||||
if __FILE__ == $0
|
||||
input_file_name = File.join(File.dirname(__FILE__), "day_7_input.txt")
|
||||
input_content = File.open(input_file_name).read
|
||||
|
||||
puts "Solution to part 1: #{play_part_1_game input_content}"
|
||||
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user