計算機プログラムの構造と解釈 第二版 P69 問題2.36

この問題は結構好きな問題で、「ハッ!」っとすることがおおかった。
いままでのながれの例に漏れず虫食いの問題です。


ポイントとしては

( (1 2 3) (4 5 6) (7 8 9) (10 11 12))

というリストの、1と4と7と10をどうやって取り出すか?ってことかな。
これは、mapとcarで実現できる。

そんで手続きのパターンとしてはcdrダウンしつつ、consアップだ。
ってところをふまえれば、何とかなりそうな気がする。


まあ、そんな感じでなんとなくわかりそうになったところで、
実装をしてみる。

#!/usr/local/bin/gosh
;; -*- coding: utf-8 -*-

(use ggc.debug.trace)
(use math.mt-random)

(define nil '())


(define (accumulate op initial sequence)
  (if (null? sequence)
    initial
    (op (car sequence)
        (accumulate op initial (cdr sequence)))))


(define (accumulate-n op init seqs)
  (if (null? (car seqs))
    nil 
    (cons (accumulate op init (map car seqs))
          (accumulate-n op init (map cdr seqs)))))

(define s '((1 2 3) (4 5 6) (7 8 9) (10 11 12))) 

;; main
(define (main args)

  (display "s: ")
  (display s)
  (newline)

  (display "(map car s) :")
  (display (map car s)) 
  (newline)

  (display "(map cdr s) :")
  (display (map cdr s)) 
  (newline)

  (display "(cons 22 (cons 26 (cons 30 nil))): ")
  (display (cons 22 (cons 26 (cons 30 nil))))
  (newline)

  (display "(accumulate-n + 0 s ): ")
  (display (accumulate-n + 0 s)) 
  (newline)

  0)


実行

s: ((1 2 3) (4 5 6) (7 8 9) (10 11 12))
(map car s) :(1 4 7 10)
(map cdr s) :((2 3) (5 6) (8 9) (11 12))
(cons 22 (cons 26 (cons 30 nil))): (22 26 30)
(accumulate-n + 0 s ): (22 26 30)

よし。