SICPを読む(56) 問題 2.36 転置行列

はまりまくってしまった。

答えに至るまでの過程を書いてみたい。

問題 2.36

与えられた行列の足し算をする問題。

(define s '(( 1  2  3)
            ( 4  5  6)
            ( 7  8  9)
            (10 11 12)))
; => (22 36 30)

他の言語なら一瞬で解けそうな問題だが、僕にはさっぱり答えが出てこない。


理由は簡単。考え方が悪かった。

ボトムアップで解けば簡単だった。

僕が答えに至るまでの過程。


まずは、転置行列にすれば良いと思い、mapした。

(map car s) ; (1 4 7 10)

carすれば、2次元配列の先頭が取れる。これをfoldで足せば、答えが出そうだ。

(fold-right + 0 (map car s)) ; 22

おぉ。

(map cdr s)には、

(map cdr s) ; ((2 3) (5 6) (8 9) (11 12))

残りが入ってる。

consで繋ぎ合わせると・・・。

(cons (map car s)
      (map cdr s)) ; ((1 4 7 10) (2 3) (5 6) (8 9) (11 12)

答えが見えてきた。後は穴埋めを埋めるだけだ。

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

(accumulate-n + 0 s) ; (22 26 30)

でたでたでたでた!!


最初は設問の穴埋めを埋めようと思って必死に考えてたが、「ボトムアップで考えれば簡単だった!!」

ハマった時は問題を単純にして考えようと思う。