抽象化 抽象化 抽象化
2007/05/14
id:ibaza:20070514:1179106514 さんのを見たら凄! ロジックが見事に抽象化されています。素数リストと探索リストなんて出てこない。
id:smeghead:20070513:prime は、Wikipediaの手続き型で説明されたロジックを素直に実装しちゃったことが失敗の原因だったんですね。
やはりlisp脳には程遠いorz.
でもやっぱ、今の実力でがんばった結果を書いとく。
;2から n までの検索用リストを作成する。 (defun make-search-lst (n &optional (lst nil)) (if (= n 1) lst (make-search-lst (1- n) (cons n lst)))) ;numで指定された数の倍数をlstから削除する。 (defun remove-multiple (num lst) (remove-if #'(lambda (n) (if (zerop (mod n num)) t)) lst)) ;s-lstの中から素数を抽出し返却する。 (defun create-prime-lst (s-lst &optional (p-lst nil)) (if (and (not (null p-lst)) (< (car (last s-lst)) (* (car (last p-lst)) (car (last p-lst))))) (append p-lst s-lst) (create-prime-lst (remove-multiple (car s-lst) s-lst) (append p-lst (list (car s-lst)))))) (mapcan #'(lambda (x) (format t "~d " x)) (create-prime-lst (make-search-lst 100)))
副作用のある関数(setf)の使用を回避した。
追記20070515
最後です。
(defun make-search-lst (n &optional (lst nil)) (if (= n 1) lst (make-search-lst (1- n) (cons n lst)))) (defun remove-multiple (num lst) (remove-if #'(lambda (x) (zerop (mod x num))) lst)) (defun break? (p-lst s-lst) (and (not (null p-lst)) (< (sqrt (car (last s-lst))) (car (last p-lst))))) (defun collect-prime-number (s-lst &optional (p-lst nil)) (if (break? p-lst s-lst) (append p-lst s-lst) (collect-prime-number (remove-multiple (car s-lst) s-lst) (append p-lst (list (car s-lst)))))) (mapcan #'(lambda (x)(format t "~3d " x)) (collect-prime-number (make-search-lst 100)))