「第1回オフラインリアルタイムどう書くの参考問題」をJavaで解く


参考問題』に対する解答。

  • スートは役とは関係ない
  • 3Kで4Kになることはない
  • 1のときは10
Main.java
package poker;

public class Main {
    private static int toInt(char ch) {
        switch(ch) {
        case '1' : return 10;
        case 'J' : return 11;
        case 'Q' : return 12;
        case 'K' : return 13;
        case 'A' : return  1;
        default:
            return (int)(ch - '0');
        }
    }
    private static int[] toCards(char[] str) {
        int n = str.length;
        int[] cards = new int[n];
        int j = 0;
        for(int i = 1; i < n; i+=2) {
            cards[j++] = toInt(str[i]);
            if(str[i] == '1') i++;
        }
        return cards;
    }
    public static String judge(String str) {
        int[] cards = toCards(str.toCharArray());
        int[] d = new int[14];
        for(int c: cards) {
            d[c]++;
        }
        int[] cnt = count(d);
        int nk = cnt[1];
        int np = cnt[0];
        boolean is3K = nk == 3;
        boolean is4K = nk == 4;
        boolean is1P = np == 1;
        boolean is2P = np == 2;
        if      (is4K)          return "4K";
        else if (is3K &&  is1P) return "FH";
        else if (is3K)          return "3K";
        else if (is2P)          return "2P";
        else if (is1P)          return "1P";
        else                    return "--";
    }
    private static int[] count(int[] d) {
        int n = 0;
        int n3or4 = -1;
        for(int v: d) {
            if      (v     ==  2) n++;
            else if (n3or4 == -1) {
              if      (v == 3) n3or4 = 3;
              else if (v == 4) n3or4 = 4;
            }
        }
        int[] r = {n, n3or4};
        return r;
    }
    public static void main(String[] args) {
        System.out.println(judge("D3C3C10D10S3"));// FH
        System.out.println(judge("S8D10HJS10CJ"));// 2P
        String[] Q =
            {"DASAD10CAHA", 
             "S10HJDJCJSJ",
             "S10HAD10DAC10",
             "HJDJC3SJS3",
              "S3S4H3D3DA", 
              "S2HADKCKSK",
              "SASJDACJS10", 
              "S2S10H10HKD2",
              "CKH10D10H3HJ", 
              "C3D3S10SKS2",
              "S3SJDAC10SQ", 
              "C3C9SAS10D2"};
        for(String q: Q) {
            System.out.println(judge(q));
        }

    }
}

スートは関係ないので、カードの種類を整数で区別するようにして、長さ14の配列を使って役を判定。入力の長さがnだったら、たぶんO(n)で判定できる。でも今回はカードは5枚固定なので、ソートを使って、可読性を上げるべきだったかもしれない。