http://nabetani.sakura.ne.jp/hena/ord5dahimi/
Given the cards and hands of the card game "Millionaire" (also known as "Millionaire"), the problem is to output all the combinations of hands that can be put out next.
The joker is a wildcard, so it's a good idea how to handle it. Here, the processing when the joker is included in the hand is different.
Ruby
class Card
Rank = %W(3 4 5 6 7 8 9 T J Q K A 2)
def initialize(str)
@value = str
@rank = (str == "Jo") ? 13 : Rank.index(str[1])
end
attr_reader :value, :rank
alias to_s value
end
module Daihinmin
module_function
def play(input)
table, hand = input.split(",")
return "-" unless hand
hand = hand.scan(/../).map { |c| Card.new(c) }
joker = hand.find {|c| c.value == "Jo"}
table = table.scan(/../).map { |c| Card.new(c) }
t_rank = table.map(&:rank).min
t_num = table.size
cs = hand.group_by(&:rank).select { |k, v| k > t_rank }.values
result = cs.select { |ary| ary.size >= t_num }
.flat_map { |ary| ary.combination(t_num).to_a }
if joker && t_num >= 2
result +=
cs.select { |ary| ary.size >= t_num - 1 && ary[0] != joker }
.flat_map {|ary|
ary.combination(t_num - 1).map { |cards| cards + [joker] }
}
end
result.empty? ? "-" : result.map(&:join).join(",")
end
end
if __FILE__ == $0
[
"DJ,",
"H7,HK",
"S3,D4D2",
"S9,C8H4",
"S6,S7STCK",
"H4,SAS8CKH6S4",
"ST,D6S8JoC7HQHAC2CK",
"SA,HAD6S8S6D3C4H2C5D4CKHQS7D5",
"S2,D8C9D6HQS7H4C6DTS5S6C7HAD4SQ",
"Jo,HAC8DJSJDTH2",
"S4Jo,CQS6C9DQH9S2D6S3",
"CTDT,S9C2D9D3JoC6DASJS4",
"H3D3,DQS2D6H9HAHTD7S6S7Jo",
"D5Jo,CQDAH8C6C9DQH7S2SJCKH5",
"C7H7,S7CTH8D5HACQS8JoD6SJS5H4",
"SAHA,S7SKCTS3H9DJHJH7S5H2DKDQS4",
"JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT",
"HTST,SJHJDJCJJoS3D2",
"C7D7,S8D8JoCTDTD4CJ",
"DJSJ,DTDKDQHQJoC2",
"C3H3D3,CKH2DTD5H6S4CJS5C6H5S9CA",
"D8H8S8,CQHJCJJoHQ",
"H6D6S6,H8S8D8C8JoD2H2",
"JoD4H4,D3H3S3C3CADASAD2",
"DJHJSJ,SQDQJoHQCQC2CA",
"H3D3Jo,D4SKH6CTS8SAS2CQH4HAC5DADKD9",
"C3JoH3D3,S2S3H7HQCACTC2CKC6S7H5C7",
"H5C5S5D5,C7S6D6C3H7HAH6H4C6HQC9",
"H7S7C7D7,S5SAH5HAD5DAC5CA",
"D4H4S4C4,S6SAH6HAD6DAC6CAJo",
"DTCTSTHT,S3SQH3HQD3DQC3CQJo",
"JoS8D8H8,S9DTH9CTD9STC9CAC2"
].each do |input|
puts Daihinmin.play(input)
end
end
I was wondering how to express the card, so I classified it here (Card
class). The ranks of the cards are quantified and Integers from 0 are given in order of weakness (Card # rank
). The strongest joker alone ranks 13. The representation of the card represented by String can be obtained with Card # value
.
As a process, first set the field card to table
and the hand to hand
. If the joker exists, it will enter joker
(if it does not exist, it will be nil
).
Cs
is a group of cards in your hand that are ranked higher than the rank of the cards in the field (t_rank
).
From cs
, leave more than the number of cards in the field (t_num
), and then take a combination of the number of cards in the field and store it in result
.
If you have a joker in your hand and the number of cards in the field (t_num
) is 2 or more, do the same with the joker as a wildcard.
Since the result is represented by String (using Array # join), Card # to_s
is set as an alias of Card # value
.
In addition, since the output has an indefinite order, I skip the test (laugh).
I also wrote a test.
if __FILE__ == $0
def same?(input, expect)
inputs = input.split(",")
expects = expect.split(",")
return false unless inputs.size == expects.size
equal = ->(a, b) {
a == b || a.scan(/../).sort == b.scan(/../).sort
}
is_found = ->(ans) {
s = expects.find { |e| equal.(e, ans) }
return false unless s
expects.delete(s)
true
}
inputs.all?(&is_found)
end
[
["DJ,", "-"],
["H7,HK", "HK"],
["S3,D4D2", "D4,D2"],
["S9,C8H4", "-"],
["S6,S7STCK", "CK,ST,S7"],
["H4,SAS8CKH6S4", "S8,CK,H6,SA"],
["ST,D6S8JoC7HQHAC2CK", "Jo,C2,CK,HA,HQ"],
["SA,HAD6S8S6D3C4H2C5D4CKHQS7D5", "H2"],
["S2,D8C9D6HQS7H4C6DTS5S6C7HAD4SQ", "-"],
["Jo,HAC8DJSJDTH2", "-"],
["S4Jo,CQS6C9DQH9S2D6S3", "DQCQ,D6S6,H9C9"],
["CTDT,S9C2D9D3JoC6DASJS4", "JoC2,SJJo,DAJo"],
["H3D3,DQS2D6H9HAHTD7S6S7Jo", "JoHA,JoD6,JoH9,D6S6,D7S7,JoS6,HTJo,JoDQ,S2Jo,JoD7,JoS7"],
["D5Jo,CQDAH8C6C9DQH7S2SJCKH5", "CQDQ"],
["C7H7,S7CTH8D5HACQS8JoD6SJS5H4", "HAJo,JoSJ,H8S8,H8Jo,CQJo,CTJo,JoS8"],
["SAHA,S7SKCTS3H9DJHJH7S5H2DKDQS4", "-"],
["JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT", "CTDT,H9D9,S9D9,DACA,CTST,H9S9,DTST"],
["HTST,SJHJDJCJJoS3D2", "DJCJ,SJDJ,JoHJ,CJHJ,SJJo,HJSJ,DJJo,JoCJ,JoD2,SJCJ,DJHJ"],
["C7D7,S8D8JoCTDTD4CJ", "D8S8,JoS8,CTJo,DTJo,JoCJ,CTDT,D8Jo"],
["DJSJ,DTDKDQHQJoC2", "JoDK,HQDQ,DQJo,C2Jo,JoHQ"],
["C3H3D3,CKH2DTD5H6S4CJS5C6H5S9CA", "S5H5D5"],
["D8H8S8,CQHJCJJoHQ", "JoCQHQ,JoHJCJ"],
["H6D6S6,H8S8D8C8JoD2H2", "D2H2Jo,D8JoS8,D8S8C8,C8D8H8,JoC8S8,H8JoC8,S8H8C8,JoS8H8,C8JoD8,D8H8S8,D8JoH8"],
["JoD4H4,D3H3S3C3CADASAD2", "DACASA"],
["DJHJSJ,SQDQJoHQCQC2CA", "SQJoCQ,DQCQJo,JoSQHQ,SQCQHQ,DQHQSQ,HQDQCQ,HQDQJo,SQDQCQ,CQJoHQ,SQJoDQ"],
["H3D3Jo,D4SKH6CTS8SAS2CQH4HAC5DADKD9", "HASADA"],
["C3JoH3D3,S2S3H7HQCACTC2CKC6S7H5C7", "-"],
["H5C5S5D5,C7S6D6C3H7HAH6H4C6HQC9", "C6D6S6H6"],
["H7S7C7D7,S5SAH5HAD5DAC5CA", "SADACAHA"],
["D4H4S4C4,S6SAH6HAD6DAC6CAJo", "C6H6S6D6,SAJoDACA,S6H6C6Jo,SACAJoHA,HADASAJo,HADAJoCA,CADAHASA,D6C6JoH6,S6D6C6Jo,H6JoS6D6"],
["DTCTSTHT,S3SQH3HQD3DQC3CQJo", "HQSQJoDQ,SQCQDQJo,DQCQHQJo,SQHQJoCQ,CQDQHQSQ"],
["JoS8D8H8,S9DTH9CTD9STC9CAC2", "H9C9D9S9"],
].each do |input, expect|
p same? Daihinmin.play(input), expect
end
end
Recommended Posts