正しい文(クイズ)
Posted feedbacks - Common Lisp
いい方法が思いつかなかったため多重ループ生成 & eval してしまいました。 入る数字は n=2 なら 8 未満、n>2 なら n^2 未満と評価できました。 というわけで理論上は停止性を保障できています。 ;; format の部分はもっときれいにやる方法がないものでしょうか……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | (defun bound (n) (if (= n 2) 8 (* n n)))
(defun solution-p (n &rest nums)
(let ((s (format nil (format nil "~~{~~~DR~~}" n) nums)))
(loop for i from 0 below n and a in nums
unless (= (1- a) (count (digit-char i n) s)) return nil
finally (return t))))
(defun gen-solver (n i bound chars vars)
(if (= i n)
`(if (solution-p ,n ,@vars)
(format t "この文は~@?あります~%"
(format nil "~~@{~~Cが~~~DR個~~^,~~}" ,n)
,@(apply #'nconc (mapcar #'list chars vars))))
`(loop for ,(nth i vars) from 0 below ,bound do
,(gen-solver n (1+ i) bound chars vars))))
(defun solve (n)
(let ((code (gen-solver n 0 (bound n)
(loop for i from 0 below n collect (digit-char i n))
(loop repeat n collect (gensym)))))
;; (eval code)
(funcall (compile nil (eval `(lambda () ,code))))
))
|
n>2 のときは n+2 未満しか入らないかな? あと、文に表れる数字の個数を使って枝刈りできますね。 これで n=8 のときが1分で終わりました。 n<=8 での出力結果はすべて shiro さんの #4367 と同じです。
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 | (defun bound (n) (if (= n 2) 8 (+ n 2)))
(defun check (n &rest nums)
(<= (reduce (lambda (s x) (+ s (- x (floor (log x n)) 1))) nums
:initial-value 0)
n))
(defun solution-p (n &rest nums)
(let ((s (format nil (format nil "~~{~~~DR~~}" n) nums)))
(loop for i from 0 below n and a in nums
unless (= (1- a) (count (digit-char i n) s)) return nil
finally (return t))))
(defun gen-solver (n i bound chars vars)
(if (= i n)
`(if (solution-p ,n ,@vars)
(format t "この文は~@?あります~%"
(format nil "~~@{~~Cが~~~DR個~~^,~~}" ,n)
,@(apply #'nconc (mapcar #'list chars vars))))
`(loop for ,(nth i vars) from 1 below ,bound
,@(if (> n (1+ i)) `(while (check ,n ,@(subseq vars 0 i))) ()) do
,(gen-solver n (1+ i) bound chars vars))))
(defun solve (n)
(let ((code (gen-solver n 0 (bound n)
(loop for i from 0 below n collect (digit-char i n))
(loop repeat n collect (gensym)))))
;; (eval code)
(funcall (compile nil (eval `(lambda () ,code))))
))
|




herumi
#4100()
Rating4/14=0.29
[ reply ]