[RUBY] Great poor (how to write)

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).

Postscript

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

Great poor (how to write)
How to write Rails
How to write dockerfile
How to write docker-compose
How to write Mockito
How to write migrationfile
How to write good code
How to write java comments
[Refactoring] How to write routing
[Note] How to write Dockerfile/docker-compose.yml
How to write Junit 5 organized
How to write Rails validation
How to write Rails seed
[Ruby] How to write blocks
How to write Rails routing
Studying Java # 6 (How to write blocks)
Baseball ball count (how to write)
How to write a ternary operator
Rails on Tiles (how to write)
[Rails] How to write exception handling?
How to write Java variable declaration
Y-shaped road tour (how to write)
How to write easy-to-understand code [Summary 3]
[RSpec] How to write test code
[Basic] How to write a Dockerfile Self-learning ②
Summary of how to write annotation arguments
[Introduction to Java] How to write a Java program
How to deploy
[Java] How to output and write files!
How to write Spring AOP pointcut specifier
How to write an RSpec controller test
[SpringBoot] How to write a controller test
How to write and explain Dockerfile, docker-compose
JDBC promises and examples of how to write
Rails: How to write a rake task nicely
[JavaFX] How to write Eclipse permissions in build.gradle
How to write offline 15th reference question answer
[Rails] How to write when making a subquery
Java Development Basics ~ How to Write Programs * Exercise 1 ~
How to write an if statement to improve readability-java
JUnit 5: How to write test cases in enum
Offline real-time how to write F06 implementation example
How to write code that thinks object-oriented Ruby
How to write test code with Basic authentication
How to write React Native bridge ~ Android version ~
[Java] Memo on how to write the source
How to write Java String # getBytes in Kotlin?
Notes on how to write comments in English
How to develop OpenSPIFe
How to call AmazonSQSAsync
How to use Map
How to use rbenv
How to use letter_opener_web
How to use with_option
How to use fields_for
How to use java.util.logging
How to use map
How to use collection_select
How to adapt Bootstrap
How to use Twitter4J
How to use active_hash! !!