August 13, 2018

4clojure 178 - Best Hand

Following on from Recognize Playing Cards, determine the best poker hand that can be made with five cards. The hand rankings are listed below for your convenience.

  1. Straight flush: All cards in the same suit, and in sequence
  2. Four of a kind: Four of the cards have the same rank
  3. Full House: Three cards of one rank, the other two of another rank
  4. Flush: All cards in the same suit
  5. Straight: All cards in sequence (aces can be high or low, but not both at once)
  6. Three of a kind: Three of the cards have the same rank
  7. Two pair: Two pairs of cards have the same rank
  8. Pair: Two cards have the same rank
  9. High card: None of the above conditions are met
(ns live.test
  (:require [cljs.test :refer-macros [deftest is run-tests]]))
  
(defn best-hand [h]
  (let [[s r] (apply map list h)
        rs (set (map frequencies (partition 5 1 "A23456789TJQKA")))
        s? (rs (frequencies r))
        f? (apply = s)
        g (frequencies (vals (frequencies r)))]
    (cond
     (and s? f?) :straight-flush
     (g 4) :four-of-a-kind
     (and (g 2) (g 3)) :full-house
     f? :flush
     s? :straight
     (g 3) :three-of-a-kind
     (= 2 (g 2)) :two-pair
     (g 2) :pair
     :else :high-card)))
     
(deftest best-hand-test
  (is (= :high-card (best-hand ["HA" "D2" "H3" "C9" "DJ"])))
  (is (= :pair (best-hand ["HA" "HQ" "SJ" "DA" "HT"])))
  (is (= :two-pair (best-hand ["HA" "DA" "HQ" "SQ" "HT"])))
  (is (= :three-of-a-kind (best-hand ["HA" "DA" "CA" "HJ" "HT"])))
  (is (= :straight (best-hand ["HA" "DK" "HQ" "HJ" "HT"])))
  (is (= :straight (best-hand ["HA" "H2" "S3" "D4" "C5"])))
  (is (= :flush (best-hand ["HA" "HK" "H2" "H4" "HT"])))
  (is (= :full-house (best-hand ["HA" "DA" "CA" "HJ" "DJ"])))
  (is (= :four-of-a-kind (best-hand ["HA" "DA" "CA" "SA" "DJ"])))
  (is (= :straight-flush (best-hand ["HA" "HK" "HQ" "HJ" "HT"]))))
  
(run-tests)
Tags: coding exercises KLIPSE 4clojure Clojure