2017-05-09 9 views
4

사용 가능한 교단 세트가 주어지면서 주어진 금액에 해당하는 지폐/동전 종목의 모든 조합을 얻고 싶습니다.lvars의 순서를 조작하는 방법

그래서 예를 들어, (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)))))) 

했다 그러나 자연적으로 마지막 줄이 작동하지 않습니다. 나는 vars 시퀀스를 통해 일종의 reduce을 수행하는 방법을 찾지 못했고, 개별적인 lvar 각각에 대해 유효하지 않은 목표를 설정할 수있는 다른 방법을 찾지 못했지만, 전체적으로 (외부 값, amount 및 이 예에서는 denominations).

답변

2

나는 각 lvar에 대해 개별적으로 유효하지 않은 목표를 설정하는 방법을 찾지 못했지만 전체적으로 (이 예에서 외부 값, 금액 및 교단으로 일부 연산을 수행하는 동안)). 이렇게

한가지 방법은 논리 vars, 교파, 원하는 sum 소요 재귀 관계 함수를 정의하고, varsdens 아이템들의 각 쌍에 대한 목표를 설정 conso을 사용

(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)]))) 

공지 헤드와 varsdens의 꼬리에 대한 여기 fresh 로직 변수, 각각의 "통과"에 대한 각각의 헤드의 제품을 저장하는 productrun-sum 가변 그 모든 제품의 합계가 sum과 같도록 제한하는 데 사용됩니다. conso과 재귀를 조합하면 varsdens 전체에 대한 목표를 설정할 수 있습니다.

(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}) 

나는 더 간결/우아한 해결책이있을 수있다 생각하지만,이 작동합니다.

+0

위대한 해답과 설명, 감사합니다! – alepeino