ちょっと面白いことをやってるのを見つけた。
cf. 往復運動(レシプロ運動)を表現する連番リストを作る(srfi-1 iota の変種) – 分室の分室
リストを作るんであれば unfold
が使えると思ってやってみた。省略可能な引数 shift
の処理には let-optionals*
を使った。
(use srfi-1) (define reciprocating-motion (lambda (count start step limit . restargs) (let-optionals* restargs ((shift 0)) (unfold (lambda (seed) (zero? (car seed))) (lambda (seed) (+ (cadr seed) shift)) (lambda (seed) (let* ((c (car seed)) (s (caddr seed)) (v (+ (cadr seed) s))) (cond ((< v 0) (list (- c 1) (- 0 v) (* s -1))) ((> v limit) (list (- c 1) (- limit (- v limit)) (* s -1))) (else (list (- c 1) v s))))) (list count start step))))) (print (reciprocating-motion 20 5 3 30)) (print (reciprocating-motion 20 5 3 30 50)) (print (reciprocating-motion 20 5 -5 30))
takatoh@apostrophe $ gosh reciprocating-motion.scm (5 8 11 14 17 20 23 26 29 28 25 22 19 16 13 10 7 4 1 2) (55 58 61 64 67 70 73 76 79 78 75 72 69 66 63 60 57 54 51 52) (5 0 5 10 15 20 25 30 25 20 15 10 5 0 5 10 15 20 25 30)
できてると思う。