如何在clojure中使用频率组合相同频率并显示一次?

时间:2014-10-14 17:26:16

标签: clojure

我在clojure中进行扑克牌游戏。我必须定义一个函数,使它以降序返回排名。例如:订单[“2H”“3S”“6C”“5D”“4D”]应返回(6 5 4 3 2)。但如果有这样的两对:[“5H”“AD”“5C”“7D”“AS”]那么它应该返回(14 5 7),但我的返回[14 14 7 5 5],如何我可以纠正这个吗?对于扑克牌的其他情况,它应该以相同的方式工作,以及对于一个完整的房子,它应该给出三种等级和两种等级的等级。所以,为此,我写了:

(defn order
                [hand]
                "Return a list of the ranks, sorted highest first"
                (let [ranks (reverse (sort (map #(.indexOf "--23456789TJQKA" %)
                                                (map #(str (first %)) hand))))]
                  (if (= ranks [14 5 4 3 2])
                    [5 4 3 2 1]
                    (into [] ranks))))

我还写过所有其他扑克手牌功能,比如冲洗?,直接?等

另外,我必须定义另一个函数,它需要两个命令,如'(8 5 9)'(8 7 3),如果第一个具有较大的第一个差值,则返回true,否则返回false。有人可以告诉我如何做到这一点吗?

2 个答案:

答案 0 :(得分:0)

更新以显示按计数排序,然后排名:

(defn ->r [hand]
  (let [ranks (zipmap "23456789TJKQA" (range 2 15)) ; creates a map like {\2 2, .... \A 14}
        count-then-rank
          (fn [x y] (compare 
                      [(second y) (first y)] 
                      [(second x) (first x)]))]
    (->> hand
         (map (comp ranks first)) ; returns the rank for each card eg: '(5 14 5 7 14)
         frequencies              ; returns a map of rank vs count eg: {5 2, 14 2, 7 1}
         (sort count-then-rank)   ; becomes a sorted list of tuples eg: '([14 2] [5 2] [7 1])
         (map first))))           ; extract the first value each time eg: '(14 5 7)

要获得更完整的解决方案,您可以使用频率来确定您是否有4种,3种,满屋等。

更新了有关直接和同花顺的更多信息:

对于直接,一种方法是:

  1. 提取排名,这样你就会有一个像'(14 3 2 4 5)
  2. 这样的清单
  3. 对此列表进行排序以获得'(2 3 4 5 14)
  4. 获取第一个元素:2,最后一个元素14
  5. 构建范围从2(含)到15(不含)到'(2 3 4 5 6 7 8 9 10 11 12 13 14)
  6. 与排序的序列进行比较。在这种情况下,结果是错误的。
  7. 重试,但首先用1替换14。
    • replace => '(1 3 2 4 5)
    • sort => '(1 2 3 4 5)
    • (范围1 6)=> '(1 2 3 4 5)
    • 这次,范围和排序列表匹配,所以这是直的。

  8. (defn straight? [cards]                             ; eg: ["AH" "3H" "2H" "4H" "5H"] 
      (let [ranks (zipmap "23456789TJKQA" (range 2 15))
            ranks-only (map (comp ranks first) cards)   ; eg: '(14 3 2 4 5)
            ace-high (sort ranks-only)                  ; eg: '(2 3 4 5 14)
            ace-low (sort (replace {14 1} ranks-only))  ; eg: '(1 2 3 4 5)
            consecutive #(= (range (first %) (inc (last %))) %)] ; eg: (= (range 1 6) '(1 2 3 4 5))
        (or (consecutive ace-high)
            (consecutive ace-low))))
    

    对于同花,只需提取所有套装,然后确保它们都相同:

    (defn flush? [cards] 
        (apply = (map second cards)))  ; this is when suit is the second character
    

    现在,只需将这两个布尔条件组合起来,以确定这是否为同花顺

    (defn straight-flush? [cards]
         (and (straight? cards) (flush? cards)))
    

    看看你是否可以解决4clojure best hand puzzle,开辟了大量不同的方法来解决这个问题。当我解决这个问题时,我使用了相似但不相同的功能。

    剧透更完整的解决方案(首先使用套装“D7”代替排名第一“7D”)

      

    https://github.com/toolkit/4clojure-solutions/blob/master/src/puzzle_solutions/best_hand.clj

答案 1 :(得分:0)

我认为frequencies会让您更接近您所寻找的目标。

user=> (frequencies [14 14 7 5 5])
{14 2, 7 1, 5 2}

您可以将其用于sorting

user=> (sort-by (frequencies [14 14 7 5 5]) [14 14 7 5 5])
(7 14 14 5 5)

然后你可以使用distinct

user=> (distinct [14 14 7 5 5])
(14 7 5)

将所有这些放在一起应该可以得到你想要的东西。我将把它作为读者的练习。当我想知道是否有一种简单的方法可以做某事时,我常常转向Clojure's cheatsheet