SICP 연습문제 2.36 친절한 풀이

문제

accumulate-n 프로시저는 accumulate와 비슷하지만 '차례열들의 차례열’을 세 번째 인자로 받는다는 게 다르다. 이때, 모든 차례열의 원소 수는 같다고 친다. 이 프로시저는 인자로 받은 어큐뮬레이션 프로시저를 가지고 모든 차례열의 첫 번째 원소를 한데 엮고, 이어서 두 번째 원소를 모두 엮는 방식으로 차례열들의 모든 원소를 묶어서 그 결과로 차례열 하나를 내놓는다. 예컨데, s가 차례열 네 개로 이루어진 차례열 ((1 2 3) (4 5 6) (7 8 9) (10 11 12))라고 할 때, (accumulate-n + 0 s)를 계산한 값은 (22 26 30)이라는 차례열이 된다. 아래 빈 곳을 채워 accumulate-n 프로시저의 정의를 마무리하라.

(define (accumulate-n op init seqs)
(if (null? (car seqs))
nil
(cons (accumulate op init <??>)
(accumulate-n op init <??>))))

문제로 부터 얻은 것

맵을 사용해서 차례열을 처리하는 스킬이 조금 더 늘었습니다.

문제풀이

accumulate-n 프로시저의 cons는 두 부분으로 나뉘어 있습니다. accumulate-n의 목적을 생각해 본다면, cons의 첫번째 원소인 (accumulate op init )는 모든 시퀸스의 첫번째 원소의 합을 반환해야 합니다. 이 목적을 위해 프로시저를 람다식으로 구현하면 아래와 같습니다. (op와 init의 자리에는 +와 0이 온다는 것을 기억해 주시기 바랍니다.)

(accumulate op init (map (lambda (x) (car x)) seqs))



그리고 cons의 두번째 원소인 (accumulate-n op init )의 물음표에는 첫번째 인자들을 제외한 차례열들이 와야 합니다.

(accumulate-n op init (map (lambda (x) (cdr x)) seqs))



완성된 accumulate-n과 문제의 테스트 코드는 아래와 같습니다.

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

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

(accumulate-n + 0 s)



문제의 요구를 잘 수행하는 모습



읽어주셔서 감사합니다.