sumとaverage

プログラミングGaucheを読んでいる途中ですが、リストの再帰処理の復習として合計と平均算出を実装してみる。

sum

0を初期値とし、要素の値を加えた値を引数として渡して再帰していく。最後にその値を返すという末尾再帰による実装。

(define (sum lis)
  (let sum-loop ((n 0) 
                 (ls lis))
    (if  (null? ls) 
         n
         (let ( (val (car ls) ) )
           (if (or (real? val) (integer? val) )
               (sum-loop (+ n val) (cdr ls) )
               (sum-loop n (cdr ls) )
           )
        )
     )
   )
)

(print (sum '(1 2 3 4 5) ) )
(print (sum '(1  2.5  3.3 4 5) ) )
  • >
15
15.8

ここまでしてみましたが、foldを使うともっと簡単にできましたね。こちらも結果値の初期値を0として結果値と要素値を足すだけ。

(define (sum lis)
  (fold (lambda (x t) 
          (+ x t) )
        0
        lis)
)

average

累計と要素カウントをしながら再帰していく。最後に累計値/要素数を返すという末尾再帰による実装。

(define (average lis)
  (let avr-loop ((total 0) 
                 (n 0)
                 (ls lis))
    (if  (null? ls) 
         (/ total n)
         (let ( (val (car ls) ) )
           (if (or (real? val) (integer? val) )
               (avr-loop (+ total val) (+  n 1)  (cdr ls) )
               (avr-loop total (+ n 1)   (cdr ls) )
               )
        )
     )
  )
)
(print (average '(1 2 3 4 5) ) )
  • >
3
3.16