-
Notifications
You must be signed in to change notification settings - Fork 0
/
day07.rb
executable file
·149 lines (130 loc) · 3.22 KB
/
day07.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env ruby
class Hand
include Comparable
attr_accessor :cards, :bid
def initialize(cards, bid)
@cards = cards
@bid = bid
end
def <=>(other)
if other.rank == rank
-1 * cardranks.each_with_index.map { |cr, idx| cr <=> other.cardranks[idx] }.find { |v| v != 0 } || 0
else
other.rank <=> rank
end
end
def rank
@rank ||= if uniq_count.size == 1
# five of a kind
7
elsif uniq_count.size == 2 && uniq_count.any? { |k, v| v == 4 }
# four of a kind
6
elsif uniq_count.size == 2
# puts "FullHouse: #{cards.join}"
# full house
5
elsif uniq_count.size == 3 && uniq_count.any? { |k, v| v == 3 }
# three of a kind
4
elsif uniq_count.size == 3
# two pairs
3
elsif uniq_count.size == 4
# one pair
2
else
# high card
1
end
end
def cardranks
@cardranks ||= @cards.map { |card|
"AKQJT98765432".chars.reverse.find_index card
}
end
def uniq_count
@uniq_count ||= @cards.group_by { |c| c }.map { |k, v| [k, v.length] }.to_h
end
end
class Hand2
include Comparable
attr_accessor :cards, :bid
def initialize(cards, bid)
@cards = cards
@bid = bid
end
def <=>(other)
puts [cards.join, uniq_count].join(", ") if [rank, other.rank].any? { |r| r.nil? }
if other.rank == rank
-1 * cardranks.each_with_index.map { |cr, idx| cr <=> other.cardranks[idx] }.find { |v| v != 0 } || 0
else
other.rank <=> rank
end
end
def rank
@rank ||= if uniq_count.size == 1
# five of a kind
7
elsif uniq_count.size == 2 && uniq_count.any? { |k, v| v == 4 }
# four of a kind
(joker_count > 0) ? 7 : 6
elsif uniq_count.size == 2
# full house
(joker_count > 0) ? 7 : 5
elsif uniq_count.size == 3 && uniq_count.any? { |k, v| v == 3 }
case joker_count
when 0
4 # three of a kind
when 1, 3
6 # four of a kind
when 2
7 # five of kind
end
elsif uniq_count.size == 3
case joker_count
when 0
3 # two pairs
when 1
5 # full house
when 2
6 # four of a kind
end
elsif uniq_count.size == 4
case joker_count
when 0
2 # one pair
when 1, 2
4 # three of kind
end
else
# high card
1 + joker_count
end
end
def cardranks
@cardranks ||= @cards.map { |card|
"AKQT98765432J".chars.reverse.find_index card
}
end
def uniq_count
@uniq_count ||= @cards.group_by { |c| c }.map { |k, v| [k, v.length] }.to_h
end
def joker_count
@joker_count ||= @cards.count { |c| c == "J" }
end
end
hands2 = []
hands = File.readlines("./input07.txt").map { |line|
cards, bid = line.strip.split(" ")
hands2 << Hand2.new(cards.chars, bid.to_i)
Hand.new(cards.chars, bid.to_i)
}
puts hands.sort.reverse.each_with_index.map { |hand, idx|
# puts [hand.cards.join, hand.bid, hand.bid * (idx + 1)].join(": ")
hand.bid * (idx + 1)
}.inject(:+)
puts hands2.sort.reverse.each_with_index.map { |hand, idx|
puts [hand.cards.join, hand.cardranks.map(&:to_s).join("+"), hand.rank, hand.bid, hand.bid * (idx + 1)].join(": ")
hand.bid * (idx + 1)
}.inject(:+)