【发布时间】:2019-03-23 15:31:48
【问题描述】:
(ns verbal-arithmetic
(:require
[clojure.core.logic :refer [all run* everyg lvar == membero fresh conde succeed fail conso resto]]
[clojure.core.logic.fd :as fd]))
(comment
"Solving cryptarithmetic puzzle"
" SEND
+ MORE
______
MONEY")
(defn send-more-money-solutions []
(run* [s e n d m o r y]
(fd/in s e n d m o r y (fd/interval 0 9))
(fd/!= s 0)
(fd/!= m 0)
(fd/distinct [s e n d m o r y])
(fd/eq (= (apply + [(* 1000 s) (* 100 e) (* 10 n) d
(* 1000 m) (* 100 o) (* 10 r) e])
(apply + [(* 10000 m) (* 1000 o) (* 100 n) (* 10 e) y])))))
上面的例子不起作用,因为apply 在fd/eq 中不能正常工作。以下版本的send-more-money-solutions 有效,因为我不使用apply。我需要使用apply 来概括解决方案以处理具有不同长度的任意字符串。
(defn send-more-money-solutions []
(run* [s e n d m o r y]
(fd/in s e n d m o r y (fd/interval 0 9))
(fd/!= s 0)
(fd/!= m 0)
(fd/distinct [s e n d m o r y])
(fd/eq (= (+ (* 1000 s) (* 100 e) (* 10 n) d
(* 1000 m) (* 100 o) (* 10 r) e)
(+ (* 10000 m) (* 1000 o) (* 100 n) (* 10 e) y)))))
我该怎么办? (对于上面,我有一个想法,我可以编写一个宏(虽然还不确定如何),但实际上我需要能够使用作为逻辑变量序列的变量。如下所示)
(fd/eq (= (+ (apply + lvars1) (apply + lvars2))
(apply + lvars3)))
错误信息看起来像
java.lang.IllegalArgumentException: Can't call nil, form: (nil + [(* 1000 s) (* 100 e) (* 10 n) d (* 1000 m) (* 100 o) (* 10 r) e] G__1124704)
我认为fd/eq 宏中发生了一些奇怪的事情,所以我应该尝试不使用eq 宏。
提前谢谢大家!
【问题讨论】:
-
仅供参考,在遇到此问题之前,我正在处理此提交 github.com/wontheone1/core-logic-walk-through/commit/…
-
试过 reduce 而不是
apply也遇到了同样的问题。
标签: clojure clpfd logic-programming clojure-core.logic cryptarithmetic-puzzle