假设我想获得相当于给定值的账单/硬币面额的所有组合,同时给出一组可用面额。
例如,对于(change 14 #{1 2 5 10})
,我期待
(
{10 1, 5 0, 2 2, 1 0}
{10 1, 5 0, 2 1, 1 2}
{10 0, 5 2, 2 2, 1 0}
{10 0, 5 2, 2 1, 1 2}
;; ...
)
我的尝试是
(defn change [amount denominations]
(let [dens (sort > denominations)
vars (repeatedly (count dens) lvar)]
(run* [q]
(== q (zipmap dens vars))
(everyg #(fd/in % (fd/interval 0 amount)) vars)
(== amount (apply + (map * dens vars))))))
但自然最后一行不起作用。我还没有找到一种方法来对reduce
序列进行某种vars
,或者用其他方式来设置对每个lvar单独无效的目标,但是对于整体(同时也在做)一些具有外部值的操作,在此示例中为amount
和denominations
。
答案 0 :(得分:2)
我还没有找到一种方法来设置对每个lvar单独无效的目标,但是对于整体(同时在本例中还使用外部值,金额和面额进行一些操作)
这样做的一种方法是定义递归关系函数,该函数采用逻辑vars
,面额和期望的sum
,并使用conso
为每对设置目标vars
和dens
个项目:
(defn productsumo [vars dens sum]
(fresh [vhead vtail dhead dtail product run-sum]
(conde
[(emptyo vars) (== sum 0)]
[(conso vhead vtail vars)
(conso dhead dtail dens)
(fd/* vhead dhead product)
(fd/+ product run-sum sum)
(productsumo vtail dtail run-sum)])))
请注意fresh
和vars
的头部和尾部的dens
逻辑变量,product
以存储每个&#的头部产品的run-sum
34;传递"和sum
变量,用于约束所有产品的总和,使它们等于conso
。 vars
和递归的组合允许我们为整个dens
和(defn change [amount denoms]
(let [dens (sort > denoms)
vars (repeatedly (count dens) lvar)]
(run* [q]
(== q (zipmap dens vars))
(everyg #(fd/in % (fd/interval 0 amount)) vars)
(productsumo vars dens amount))))
设置目标。
然后将其插入现有功能:
(change 14 #{1 2 5 10})
=>
({10 0, 5 0, 2 0, 1 14}
{10 1, 5 0, 2 0, 1 4}
{10 0, 5 1, 2 0, 1 9}
{10 0, 5 0, 2 1, 1 12}
{10 1, 5 0, 2 1, 1 2}
{10 1, 5 0, 2 2, 1 0}
{10 0, 5 0, 2 2, 1 10}
{10 0, 5 2, 2 0, 1 4}
{10 0, 5 1, 2 1, 1 7}
{10 0, 5 0, 2 3, 1 8}
{10 0, 5 0, 2 4, 1 6}
{10 0, 5 1, 2 2, 1 5}
{10 0, 5 0, 2 5, 1 4}
{10 0, 5 2, 2 1, 1 2}
{10 0, 5 0, 2 6, 1 2}
{10 0, 5 1, 2 3, 1 3}
{10 0, 5 0, 2 7, 1 0}
{10 0, 5 2, 2 2, 1 0}
{10 0, 5 1, 2 4, 1 1})
最后得到答案:
var myObject = {
myAlert: function(str) {
alert(str);
}
};
myObject.myAlert('Hello');
var MyConstructor = function() {
};
MyConstructor.myAlert = function(str) {
alert(str);
}
MyConstructor.myAlert('Bye');
我怀疑可能有更简洁/优雅的解决方案,但这很有效。