Displaying posts written in

7月 2009

Common LispでFizz-Buzz問題・コンディションで

コンディションの練習のために、Fizz-Buzz問題をコンディションを使って解いてみた。「15で割り切れる」「3で割り切れる」「5で割り切れる」といった事態をそれぞれエラーと見なし、別の値を使うという選択肢(use-value)を用意した上で、loop時にFizz,Buzz,FizzBuzzという文字列を割り当てている。

(define-condition multiple-of-15 (error) ())
(define-condition multiple-of-3  (error) ())
(define-condition multiple-of-5  (error) ())
 
(defun fizz-buzz-cond (n)
  (restart-case
      (cond ((zerop (mod n 15)) (error 'multiple-of-15))
	    ((zerop (mod n 3))  (error 'multiple-of-3))
	    ((zerop (mod n 5))  (error 'multiple-of-5))
	    (t n))
    (use-value (value) value)))
 
(defun use-value-fn (value)
  #'(lambda (c)
      (declare (ignore c))
      (invoke-restart 'use-value value)))
 
(defun run-fizz-buzz ()
  (handler-bind ((multiple-of-15 (use-value-fn "FizzBuzz"))
		 (multiple-of-3  (use-value-fn "Fizz"))
		 (multiple-of-5  (use-value-fn "Buzz")))
    (loop for n from 1 to 100 do (format t "~a~%" (fizz-buzz-cond n)))))