(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
宏。
谢谢大家!