Plaster

common-lisp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (ql:quickload :amb) (shadow 't) (defun solve () (macrolet ((bind (letters &body body) (let ((digits '(0 1 2 3 4 5 6 7 8 9))) `(amb:amb ,(mapcar (lambda (x) `(,x ',digits)) letters) ,@body)))) (let ((iterations 0)) (bind (v i o l n a t r s) (incf iterations) ;; numbers must not start with 0 (amb:constrain (/= 0 v)) (amb:constrain (/= 0 t)) (amb:constrain (/= 0 s)) (let ((letters (list v i o l n a t r s))) ;; the digits are all different (amb:constrain (= (length letters) (length (remove-duplicates letters)))) (flet ((make (&rest digits) (destructuring-bind (acc . digits) digits (loop for digit in digits do (setf acc (+ (* 10 acc) digit)) finally (return acc))))) (let ((violin (make v i o l i n)) (viola (make v i o l a)) (trio (make t r i o)) (sonata (make s o n a t a))) ;; VIOLIN * 2 + VIOLA = TRIO + SONATA (amb:constrain (= (+ (* violin 2) viola) (+ trio sonata))) (values letters iterations)))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CL-USER> (time (solve)) Evaluation took: 21.579 seconds of real time 21.572052 seconds of total run time (21.564395 user, 0.007657 system) [ Run times consist of 0.156 seconds GC time, and 21.417 seconds non-GC time. ] 99.97% CPU 75,518,131,253 processor cycles 15,040,192,400 bytes consed (1 7 6 4 8 0 2 5 3)

Annotations