2005/04/18

名前付き let に興奮。って、おまえはその昔大学でλ式やったんじゃないの? 学生のときにもっと勉強しておけばよかったっていう言葉の意味がわかりつつあるのは、きっと大人になったからなんだろう。いや、学生のころも、勉強はした。けど、抽象的な対象ばっかり扱っていたし、何より自分のコンピュータが買えなかったのが悔しい。あと、コンピュータ数学のゼミが体育会系で疎遠だったのも悲しい。

まあ、いいや。とにかく素数は避けられない。

(define prime-list
(let ((primes '(2)))
(lambda (upper-int)
(let next-prime ((test-int 3) (ls primes))
(if (< test-int upper-int)
(if (integer? (/ test-int (car (reverse ls))))
(next-prime (+ test-int 1) primes)
(if (null? (cdr ls))
(begin (set! primes (cons test-int primes))
(next-prime (+ test-int 1) primes))
(next-prime test-int (reverse (cdr (reverse ls))))))
primes)))))

(prime-list 91) =>
(89 83 79 73 71 67 61 59 53 47 43 41 37 31 29 23 19 17 13 11 7 5 3 2)

目下の問題

  • ifがおおすぎ

  • 代入をなんとかしたい。でも、こういう結果(判定ではなくリストを得る)を求める以上は無理かな

  • リストの末尾を削るには reverse して car して reverse するしかないの?

3 comments :

Anonymous said...

・named let (test-int のループ)の中でまた named let (ls のループ) → set! 追放
・primes の初期値は '(), test-int の初期値は 2, の方がかっこいい
・でなければ, test-int は 2 ずつ増やす
・ls の初期値を (reverse primes) にして, reverse reverse を避ける
とかどうかな?

k16 said...

ものすごく的を得た指摘、ありがとうございます。もやもやが解消しそうです(特に reverse reverse 問題)。外側の名前付きlet で最新の prime たちを固定する感じですかね。さっそく改良してみます。

k16 said...

「的を得た」→「当を得た」ですね。失礼しました。