smm/core.clj
(ns smm.core
(:refer-clojure :exclude [==])
(:use [clojure.core.logic])
(:require [clojure.core.logic.fd :as fd]))
;;; S E N D
;;; + M O R E
;;; ---------
;;; M O N E Y
(defn digitso [nums n]
(fresh [h t]
(conso h t nums)
(conde
[(emptyo t) (== h n)]
[(fresh [n0 nn]
(fd/* nn 10 n0)
(fd/+ n0 h n)
(digitso t nn))])))
(defn solve []
(run 2 [q]
(fresh [s e n d m o r y send more money]
(fd/in s e n d m o r y (fd/domain 0 1 2 3 4 5 6 7 8 9))
(fd/!= s 0) (fd/!= m 0)
(fd/distinct [s e n d m o r y])
(digitso [d n e s] send)
(digitso [e r o m] more)
(digitso [y e n o m] money)
(fd/+ send more money)
(== q [s e n d '+ m o r e '= m o n e y]))))
user=> (use 'smm.core)
user=> (solve)
([9 5 6 7 + 1 0 8 5 = 1 0 6 5 2])