这里有一种使用core的方法。思维方式
我们将定义
secondo
(如
firsto
)在下一个函数中查看集合中每对项的第二项。
(defn secondo [l s]
(fresh [x]
(resto l x)
(firsto x s)))
我们将定义
nonconseco
要递归检查是否没有连续值,请执行以下操作:
(defn nonconseco [l]
(conde
[(== l ())]
[(fresh [x] (== l (list x)))]
[(fresh [lhead lsecond ltail]
(conso lhead ltail l)
(secondo l lsecond)
(project [lhead lsecond] ;; project to get your map keys
(!= (:key lhead) (:key lsecond)))
(nonconseco ltail))]))
和一个函数来查找
coll
没有任何连续的相同值:
(defn non-consecutive [coll]
(first
(run 1 [q]
(permuteo coll q)
(nonconseco q))))
这可用于您的示例输入:
(non-consecutive
[{:title "Deep House Track" :key "F#"}
{:title "Breakup Song" :key "B"}
{:title "Love Song" :key "A"}
{:title "Inspirational Song" :key "A"}
{:title "Summer Song" :key "A"}
{:title "Power Ballad" :key "D"}])
=>
({:title "Love Song", :key "A"}
{:title "Breakup Song", :key "B"}
{:title "Inspirational Song", :key "A"}
{:title "Deep House Track", :key "F#"}
{:title "Summer Song", :key "A"}
{:title "Power Ballad", :key "D"})
这里有一个
通用的
版本
Noncoseco公司
它只关注值,而不是
:key
地图中的:
(defn nonconseco [l]
(conde
[(== l ())]
[(fresh [x] (== l (list x)))]
[(fresh [lhead lsecond ltail]
(conso lhead ltail l)
(secondo l lsecond)
(!= lhead lsecond)
(nonconseco ltail))]))
(non-consecutive [1 1 2 2 3 3 4 4 5 5 5])
=> (3 2 3 4 2 4 5 1 5 1 5)
更新:这里有一个更快的版本,它使用谓词函数而不是关系逻辑:
(defn non-consecutive? [coll]
(every? (partial apply not=) (partition 2 1 coll)))
然后使用core。逻辑的
pred
要将该谓词应用于逻辑变量,请执行以下操作:
(run 10 [q]
(permuteo coll q)
(pred q non-consecutive?))