challenge ポーカーの役判定

引数に手札を与えると、ポーカーの役を表示するプログラムを作ってください。

条件:

  • スートはS,D,H,C、ランクはA,2~9,T,J,Q,Kのそれぞれ一文字で表します。
  • 手札は S2D5H3CQS9 のように10文字で指定されます。特にソートはされていません。
  • 手札にジョーカーは含まれません。
  • ストレートで取りうるランクの種類はA2345, 23456 ... 9TJQK, TJQKAの10種類で、JQKA2のようにK-A-2をまたぐものはストレートではありません。

実行例:

% ./poker SQSJSASKST
Royal flush

% ./poker D9D7D6D5D8
Straight flush

% ./poker C2D2S2H3H2
Four of a kind

% ./poker C2D3S2H3H2
Full house

% ./poker S9S4S8STSJ
Flush

% ./poker C4H7D5S6H3
Straight

% ./poker S6H6C5DQC6
Three of a kind

% ./poker S6HQC5DQC6
Two pair

% ./poker S6H4C5DQC6
One pair

% ./poker SJSQSKSAC2
No pair

お題にしようと思っていたのに間違えてしまいました。今から変更可能でしょうか?

(説明)
当初間違ってトピックに投稿していたので、このようなコメントを付けていたのですが、
このコメントに気づいた管理人さんにお題に移していただきました。
(最初の2つだけ投稿日時が早いのはそのためです)

Posted feedbacks - OCaml

素直に

 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
#light
open List

let poker cs =
  let is_all_elems_same l = tryfind ((<>) (hd l)) (tl l) |> Option.is_none
  let tally l =
    let h = Hashtbl.create (length l)
    for x in l do
      if Hashtbl.mem h x then Hashtbl.replace h x (Hashtbl.find h x + 1)
                         else Hashtbl.add     h x 1
    h
  (* 手札の情報をスートとランクの 2 つの情報に分離 *)
  let maxi = String.length cs - 1
  let suit = [for i in 0..2..maxi -> cs.[i]]
  let rank = [for i in 1..2..maxi -> String.index "A23456789TJQK" cs.[i] + 1]
             |> sort (-)
  (* 判定基準となる条件役を算出 *)
  let rst = rank = [1;10;11;12;13]
  let flu = is_all_elems_same suit
  let str = is_all_elems_same (mapi (fun i x -> x - i) rank)
  let pnt = [for p in (tally rank) when p.Value > 1 -> p.Value] |> sort (-)
  (* 役判定 *)
  match rst, flu, str, pnt with
    true, true, _,    _     -> "Royal flush"
  | _,    true, true, _     -> "Straight flush"
  | _,    _,    _,    [4]   -> "Four of a kind"
  | _,    _,    _,    [2;3] -> "Full house"
  | _,    true, _,    _     -> "Flush"
  | _,    _,    true, _     -> "Straight"
  | _,    _,    _,    [3]   -> "Three of a kind"
  | _,    _,    _,    [2;2] -> "Two pair"
  | _,    _,    _,    [2]   -> "One pair"
  | _ -> "No pair"

let _ =
  let ($) f g x = f (g x)
  ["SQSJSASKST";"D9D7D6D5D8";"C2D2S2H3H2";"C2D3S2H3H2";"S9S4S8STSJ"
   "C4H7D5S6H3";"S6H6C5DQC6";"S6HQC5DQC6";"S6H4C5DQC6";"SJSQSKSAC2"]
  |> iter (printfn "%s" $ poker)

Index

Feed

Other

Link

Pathtraq

loading...