リスト修行 素因数分解(2)
どうやら、前回の素因数分解にはバグがあったみたい(修正しました)
という訳で、素因数分解を速度アップしながら改善していこう〜
作戦
12の素因数分解について考えてみる。
- まず2〜12までのリストを用意する
- (2 3 4 5 6 7 8 9 10 11 12)
- 前回はここで絞りすぎた。
- いきなり素因数分解を始める。
- 12の時、2で割り切れるので、6。結果に2を加える。(2)
- 6の時、2で割り切れるので,3。結果に2を加える。(2 2)
- 3があったが、2で割り切れない。
- ここで、先頭の2を切ってふるいにかける。
- (3 5 7 9 11)
- ふるいの中は半分に。
- もう一回素因数分解する
- 3の時、3で割り切れるので1。結果に3を加える。(2 2 3)
- 1になったので、終了。
全てのリストをふるいにかける必要はなさそうだ。値が素数の時だけ、最後までふるいにかければいい。
コーディング
かなり頑張った。
(define (factor n) (define (primers-iter l) (filter (lambda (o) (not (zero? (modulo o (car l))))) (cdr l))) (define (iter m l) (cond ((= m 1) '()) ((zero? (modulo m (car l))) (cons (car l) (iter (/ m (car l)) l))) (else (iter m (primers-iter l))))) (iter n (iota (- n 1) 2)))
てすと。
(factor 1) ; () (factor 12) ; (2 2 3) (factor 123) ; (3 41) (factor 1234) ; (2 617) (factor 12345) ; (3 5 823) (factor 123456) ; (2 2 2 2 2 2 3 643) (factor 1234567) ; (127 9721)
特に2のn乗の素因数分解が早い
(factor 4194304) ; (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
まだまだ改善の余地がありそうだけど、バグは取れたし、高速化出来た。
敵あらわる
factorハヤスギ
% factor 11111111111111111 11111111111111111: 2071723 5363222357
えぇぇぇぇ・・・一瞬で出たよ。
が・頑張る。