Задание:
КНИГА * 3 = НАУКА
Постановка задачи:
Представим ребус в более удобном для восприятия виде:
КНИГА * 3 ----------- = НАУКАВместо слов КНИГА, 3 и НАУКА необходимо подобрать такие цифры, чтобы получилось математически верное выражение. Причём, разным буквам должны соответствовать разные цифры.
Рассмотрим разряды всех трёх чисел. Будем считать, что первый разряд – это единицы, второй – десятки, третий – сотни и т.д.
Таким образом, наш числовой ребус поразрядно можно представить следующим образом:
К5 | Н4 | И3 | Г2 | А1 | |
* | 31 | ||||
= | Н5 | А4 | У3 | К2 | А1 |
Для начала создадим правило, которое будет выполнять следующие задачи:
; Вывод на экран формулировки числового ребуса ; Занесение в список фактов, соответствующих буквам и цифрам ; Это правило выполняется всегда, поэтому его условная часть пуста (defrule startup => (printout t "The problem is" t) (printout t " xxxxx" " | KNIGA" t) (printout t " * x" " | 3" t) (printout t " --------- | ------" t) (printout t " = xxxxx" " | NAUKA" t) (assert (number 0) (number 1) (number 2) (number 3) (number 4) (number 5) (number 6) (number 7) (number 8) (number 9) (letter A) (letter G) (letter I) (letter K) (letter N) (letter U) (letter Z) ) )
Создадим второе правило, согласно которому будут формироваться все возможные комбинации из указанных в первом правиле букв и цифр.
; Правило, согласно которому в список фактов будут занесены все возможные ; комбинации из одной буквы и одной цифры (например, комбинации А0...А9, G0...G9 и т.д.) (defrule generate (number ?x) (letter ?y) => (assert (combination ?y ?x)) )Согласно данному правилу, если в списке фактов присутствуют факты, имеющие вид (number ?x) (letter ?y) , где вместо переменных стоят вполне конкретные значения, в список фактов добавляется еще один факт (combination ?y ?x), в котором вместо переменных стоят значения из фактов.
Далее формируем третье правило. Оно реализует следующие задачи:
; Правило, которое позволяет найти среди фактов те, которые удовлетворяют условию задачи ; и выводит на экран полученное решение (или решения, если их несколько) (defrule find-solution (combination A ?a) (combination Z ?z&~?a) (test (= (mod (* ?a ?z) 10) ?a)) (combination G ?g&~?a&~?z) (combination K ?k&~?a&~?z&~?g) (test (= (mod (+ (* ?a ?z) (* (* ?g ?z) 10)) 100) (+ (* 10 ?k) ?a))) (combination I ?i&~?a&~?z&~?g&~?k) (combination U ?u&~?a&~?z&~?g&~?k&~?i) (test (= (mod (+ (* ?a ?z) (* (* ?g ?z) 10) (* (* ?i ?z) 100)) 1000) (+ (* 100 ?u) (* 10 ?k) ?a))) (combination N ?n&~?a&~?z&~?g&~?k&~?i&~?u) (test (= (mod (+ (* ?a ?z) (* (* ?g ?z) 10) (* (* ?i ?z) 100) (* (* ?n ?z) 1000) (* (* ?k ?z) 10000)) 100000) (+ (* 10000 ?n) (* 1000 ?a) (* 100 ?u) (* 10 ?k) ?a))) (test (> ?k 0)) (test (> ?n 0)) => (printout t "Solution is:" t t) (printout t " K = " ?k t) (printout t " N = " ?n t) (printout t " I = " ?i t) (printout t " G = " ?g t) (printout t " A = " ?a t) (printout t " U = " ?u t) (printout t " Z = " ?z t) (printout t t) (printout t " " ?k ?n ?i ?g ?a " | KNIGA" t) (printout t " * " ?z " | 3" t) (printout t " " "-----------------------" t) (printout t " = " ?n ?a ?u ?k ?a " | NAUKA" t t) )В терминах CLIPS комбинации из одной буквы и одной цифры можно представить в виде фактов:
(combination A ?a) (combination Z ?z&~?a) (test (= (mod (* ?a ?z) 10) ?a))Здесь:
(test (> ?k 0)) (test (> ?n 0)) (test (> ?z 0))То есть, эта конструкция обеспечивает выполнение начального условия: число не может начинаться с цифры 0.
; Вывод на экран формулировки числового ребуса ; Занесение в список фактов, соответствующих буквам и цифрам ; Это правило выполняется всегда, поэтому его условная часть пуста (defrule startup => (printout t "The problem is" t) (printout t " xxxxx" " | KNIGA" t) (printout t " * x" " | 3" t) (printout t " --------- | ------" t) (printout t " = xxxxx" " | NAUKA" t) (assert (number 0) (number 1) (number 2) (number 3) (number 4) (number 5) (number 6) (number 7) (number 8) (number 9) (letter A) (letter G) (letter I) (letter K) (letter N) (letter U) (letter Z) ) ) ; Правило, согласно которому в список фактов будут занесены все возможные ; комбинации из одной буквы и одной цифры (например, комбинации А0...А9, G0...G9 и т.д.) (defrule generate (number ?x) (letter ?y) => (assert (combination ?y ?x)) ) ; Правило, которое позволяет найти среди фактов те, которые удовлетворяют условию задачи ; и выводит на экран полученное решение (или решения, если их несколько) (defrule find-solution (combination A ?a) (combination Z ?z&~?a) (test (= (mod (* ?a ?z) 10) ?a)) (combination G ?g&~?a&~?z) (combination K ?k&~?a&~?z&~?g) (test (= (mod (+ (* ?a ?z) (* (* ?g ?z) 10)) 100) (+ (* 10 ?k) ?a))) (combination I ?i&~?a&~?z&~?g&~?k) (combination U ?u&~?a&~?z&~?g&~?k&~?i) (test (= (mod (+ (* ?a ?z) (* (* ?g ?z) 10) (* (* ?i ?z) 100)) 1000) (+ (* 100 ?u) (* 10 ?k) ?a))) (combination N ?n&~?a&~?z&~?g&~?k&~?i&~?u) (test (= (mod (+ (* ?a ?z) (* (* ?g ?z) 10) (* (* ?i ?z) 100) (* (* ?n ?z) 1000) (* (* ?k ?z) 10000)) 100000) (+ (* 10000 ?n) (* 1000 ?a) (* 100 ?u) (* 10 ?k) ?a))) (test (> ?k 0)) (test (> ?n 0)) (test (> ?z 0)) => (printout t "Solution is:" t t) (printout t " K = " ?k t) (printout t " N = " ?n t) (printout t " I = " ?i t) (printout t " G = " ?g t) (printout t " A = " ?a t) (printout t " U = " ?u t) (printout t " Z = " ?z t) (printout t t) (printout t " " ?k ?n ?i ?g ?a " | KNIGA" t) (printout t " * " ?z " | 3" t) (printout t " " "-----------------------------" t) (printout t " = " ?n ?a ?u ?k ?a " | NAUKA" t t) )