SICP

SICP を読んでみる #47 第二章 pp.69-70

問題解答

問2.36

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

(define (lh l)
  (if (null? (cdr l))
      (list (caar l))
      (cons (caar l)
            (lh (cdr l)))))

(define (ll l)
  (if (null? (cdr l))
      (list (cdar l))
      (cons (cdar l)
            (ll (cdr l)))))

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

(define (accumulate-n op init seqs)
  (if (null? (car seqs))
      ()
      (cons (accumulate op init (lh seqs))
            (accumulate-n op init (ll seqs)))))


(accumulate-n + 0 l)

できたけど、絶対これじゃない感が。。。。そして正解を見て鼻血出ました。

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

map か、、、たしかに。というか、答えを見れば当たり前だなと思うんですよね。何であんな冗長な書き方しか思い浮かばなかったのか。

問2.37
四苦八苦しながら作成。

(define (dot-product v w)
  (accumulate + 0 (map * v w)))

(define (matrix-*-vector m v)
  (map (lambda (x) (dot-product x v)) m))

(define (transpose mat)
  (accumulate-n cons () mat))

(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (transpose (map (lambda (v) (matrix-*-vector m v)) cols))))

matrix-*-matrix は、答えを見ると方法が違った。

(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (map (lambda (x)
      (map (lambda (y) (dot-product x y)) cols)) m)))

考え方的には間違っていない。。。ハズ。ただ、最後に transpose しているのはダサいし余分な処理なのでよくない感じはする。それに比べて参考解答は素直に処理していて普通の計算方法そのもの。

うーーーん。。まだ、自分でこれを一からパッと作れる気がしないです。単純な二重ループなんですけどね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です