SICP 연습문제 2.35 친절한 풀이

문제

accumulate를 써서 2.2.2절에 나온 count-leaves 프로시저를 다시 정의해 보아라.

(define (count-leaves t)
(accumulate <??> <??> (map <??> <??>)))

문제로 부터 얻은 것

map에 들어가는 프로시저를 구성할 때, 더 상위 프로시저를 재귀로 써보는 연습을 할 수 있었습니다.

문제풀이

문제를 읽고 생각한 저의 풀이 전략은 이렇습니다. “accumulate의 map 인자 자리에 각 가지들에 달린 이파리의 개수를 포함한 리스트를 넘기고, accumulate로 그 리스트의 원소들의 합을 반환하면 되겠구나?” 그렇다면 코드는 아래와 같이 정리할 수 있습니다.

(define (count-leaves t)
(accumulate + 0 (map <??> <??>)))



남은 것은 트리를 인자로 받아서 이파리의 개수를 반환하는 프로시저입니다. 저는 우선 프로시저의 외부에 또 프로시저를 만들어서 구현했습니다. 트리를 서치하면서 만약 새로운 트리라면 다시 count-leaves를 적용하고, 숫자 즉 이파리라면 갯수인 1을 반환하는 프로시저 입니다.

(define (tree-to-number-of-leaves x)
(if (pair? x)
(count-leaves x)
1))



그리고 람다식으로 바꾸어 count-leaves에 이식했습니다.

(define (count-leaves t)
(accumulate +
0
(map (lambda (x)
(if (pair? x)
(count-leaves x)
1))
t)))




아래의 테스트 코드로 프로시저를 검사해 보겠습니다.

;              |   
; +-----+-----+
; | |
; +---+---+ +---+---+
; 1 2 3 |
; +---+---+
; 4 5

(count-leaves (list (list 1 2) (list 3 (list 4 5))))

이파리의 개수를 5개로 잘 구해내는 모습



읽어주셔서 감사합니다.