Skip to content

Instantly share code, notes, and snippets.

@nekoTheShadow
Created November 15, 2015 21:32
Show Gist options
  • Save nekoTheShadow/fccc1107a6ee818a6e78 to your computer and use it in GitHub Desktop.
Save nekoTheShadow/fccc1107a6ee818a6e78 to your computer and use it in GitHub Desktop.
(use srfi-42)
(use util.stream)
; == 準備こここから ==
; 再帰的定義に基づき、第n項を求める
; (somos 4 10) => 314 [k=4のときの第10項]
(define (somos k n)
(if (>= k n)
1
(/ (sum-ec (: j 1 (+ 1 (quotient k 2)))
(* (somos k (- n j)) (somos k (- n (- k j)))))
(somos k (- n k)))))
; k=4として第10項をもとめたいとする
; このとき第6項:3 => 第7項:7 => 第8項:23 => 第9項:59だから、次のように引数を指定する
; (calculate-somos 3 7 23 59) => 314
(define (calculate-somos . ls)
(let loop ((j 1) (sum 0) (l1 (cdr ls)) (l2 (reverse (cdr ls))))
(if (> j (/ (length ls) 2))
(/ sum (car ls))
(loop (+ j 1) (+ sum (* (car l1) (car l2))) (cdr l1) (cdr l2)))))
; (make-somos-generator 3 7 23 59)を考える
; このとき戻り値のstreamは次のような無限リストを表現している:(3 7 23 59 314 ...)
(define (make-somos-generator . ls)
(stream-cons
(car ls)
(apply make-somos-generator
(append (cdr ls) (list (apply calculate-somos ls))))))
; == 準備ここまで ==
; 以下のmake-somos-sequence関数はkの値を引数で与えてやる(kは4以上の整数)と
; 適切な「ソモスの数列」を無限リストとして返却する
; ごくふつうの再帰を用いる
(define (make-somos-sequence1 k)
(stream-map
(cut somos k <>)
(stream-iota -1 1)))
; 末尾再帰っぽく
(define (make-somos-sequence2 k)
(apply make-somos-generator (make-list k 1)))
; 数列を数列らしく扱ったつもり/stream-mapをなんとしても使いたかった
(define (make-somos-sequence3 k)
(let ((somos-k (stream-delay (make-somos-sequence3 k))))
(stream-append
(make-stream k 1)
(apply stream-map calculate-somos
(list-ec (: i k) (stream-drop somos-k i))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment