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

如何在clojure中使用频率组合相同的频率并显示一次?,clojure,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] "Retu

我在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))))
我还编写了所有其他扑克手函数,如flush?,direct?等等


此外,我还必须定义另一个函数,这样它接受两个顺序,如'859'873,如果第一个顺序的第一个差值较大,则返回true,否则返回false。有人能告诉我怎么做吗?

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

(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个同类、满座等

更新了有关直线和直线冲洗的更多信息:

对于直线电机,一种方法是:

提取等级,这样你就会有一个类似'143245'的列表 将此列表排序以获取'2 3 4 5 14 获取第一个元素:2和最后一个元素14 构建一个包含2到15的范围,以获得'2 3 4 5 6 7 8 9 10 11 12 13 14 与排序的序列进行比较。在这种情况下,结果是错误的。 重试,但首先将14替换为1。 替换=>'1 3 2 4 5 排序=>'12345 范围16=>'12345 这一次,范围和排序列表匹配,因此这是一条直线。 冲水时,只需取出所有西装,然后确保它们都相等:

(defn flush? [cards] 
    (apply = (map second cards)))  ; this is when suit is the second character
现在,简单地结合这两个布尔条件来确定这是否是一个直齐平

(defn straight-flush? [cards]
     (and (straight? cards) (flush? cards)))
看看你是否能解决这个问题,找到大量不同的方法来解决这个问题。当我解决这个问题时,我使用了相似但不完全相同的函数

下面是一个更完整的解决方案,使用西服第一D7而不是排名第一的7D

我想这会让你更接近你想要的

user=> (frequencies [14 14 7 5 5])
{14 2, 7 1, 5 2}
您可以将其用于:

然后你可以使用:


把所有这些放在一起,你就会得到你想要的。我将把它作为练习留给读者。当我想知道是否有一种简单的方法可以做某事时,我经常求助于。

让我看看我是否理解。你是在问如何从序列中删除重复项吗?不是。如果你知道扑克手,那么[5H AD 5C 7D AS]有两对牌,即两张牌具有相同的等级5,两张牌具有相同的等级A,读作14。现在,通过使用我的函数,它显示:[14 7 5],因为它对它们进行排序,但我希望它显示14 5 7,也就是说,在7之前显示14 5次,因为,5H和5C形成一对,所以它的排名将高于单卡7。嗨,@toolkit:您的解决方案给出结果5 14 7,它应该给出14 5 7,对吗?我现在面临一个问题,当[2h3h 4H 5H AH]作为输入时,我前面编写的函数返回了54 3 2 1。因为,这是直接刷新的情况,这里A的值被认为是1,它应该返回5 4 3 2 1,但您的函数返回14 5 4 3 2。@EricaMaine我建议创建一组谓词函数,然后您可以根据需要将它们组合在一起。有直线运动的功能吗?脸红一对三个一类?等等。如果你不想自己弄明白,我有一个完整的解决方案?我试着为我提到的示例添加if=ranks'145432'54321ranks,但它似乎不起作用。我不知道为什么OHi@toolkit,你能解释一下你的直接功能吗?我的意思是我的代码中已经有了一个直函数。关于r函数,这一个到哪里去了?我也试过你的方法,为什么它会给出7145?它应该是14 5 7,对吗?你想按等级对[14 14 7 5 5]的不同元素排序,然后按频率排序,是吗试试看:uuuuuuuuuuuuuuuuuuuu[14 7 5]uuuuuuuuuuuuuuuuuuuuuuu14 7 5]为了得到更严格的解决方案,您可以考虑为排序提供一个比较器。看。
user=> (frequencies [14 14 7 5 5])
{14 2, 7 1, 5 2}
user=> (sort-by (frequencies [14 14 7 5 5]) [14 14 7 5 5])
(7 14 14 5 5)
user=> (distinct [14 14 7 5 5])
(14 7 5)