与えた条件を満たす候補
Posted feedbacks - Common Lisp
S式に変換するところでめちゃくちゃ苦労した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | (defpackage doukaku43 (:use common-lisp))
(in-package :doukaku43)
(defun make-sexp (operators)
"入力から式を生成。"
(labels ((tmp (ops)
(loop for op in ops
with i = -1
appending
(if (eq op 'not)
(list 'not)
(list `(nth ,(incf i) l) op)) into lst
finally
(return `(,@lst (nth ,(incf i) l)))))
(parse-not (ops)
(let ((pos (position 'not ops :from-end t)))
(if pos
(parse-not (replace ops `((not ,(nth (1+ pos) ops)) nil) :start1 pos))
(delete nil ops))))
(infix2prefix (ops)
(loop for (op x) on (cdr ops) by #'cddr with res = (car ops)
do (setf res `(,op ,res ,x))
finally (return res))))
(infix2prefix (parse-not (tmp operators)))))
;; テスト
(make-sexp '(and or not and)) ; => (AND (OR (AND (NTH 0 L) (NTH 1 L)) (NOT (NTH 2 L))) (NTH 3 L))
(make-sexp '(not not not)) ; => (NOT (NOT (NOT (NTH 0 L))))
(defun func (operators)
"入力から式を計算する関数を返す。"
(let ((sexp (make-sexp operators)))
(lambda (l)
(declare (special l))
(eval sexp))))
(defun boolean-combination (n)
"[t,nil]のN個の全組み合わせ。"
(cond ((= n 1)
'((t) (nil)))
(t
(let ((it (boolean-combination (1- n))))
(loop for c in it appending
`((t ,@c) (nil ,@c)))))))
(defun arity (operators)
(- (length operators) (count 'not operators) -1))
(defun solve (operators)
(let ((expr (func operators)))
(loop for bools in (boolean-combination (arity operators))
when (funcall expr bools)
collecting bools)))
(solve '(and or not and)) ; => ((T T T T) (T T NIL T) (NIL T NIL T) (T NIL NIL T) (NIL NIL NIL T))
(solve '(not not not)) ; => ((NIL))
(solve '()) ; => ((T))
(solve '(and and and and and and)) ; => ((T T T T T T T))
(solve '(and)) ; => ((T T))
(solve '(or)) ; => ((T T) (NIL T) (T NIL))
(solve '(and or)) ; => ((T T T) (NIL T T) (T NIL T) (NIL NIL T) (T T NIL))
|


にしお
#3399()
Rating0/0=0.00
元ネタの 充足可能性問題 - Wikipedia は、 同じリテラル(x1とかnot x2とか)が複数回出てくることを想定しているので、 今回の問題のようにそれぞれ別の変数でだと乗法標準形 - Wikipediaにした場合に、答えが…と色々悩みどころでした。
[ reply ]