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

この問題も穴埋めです。


またまたaccumulateをよく見ながら考えてみる。


問題をよくみると、mapがある。
虫食いは4つ。


僕の考え方はこんな感じ。
mapの中で受け取ったリストのすべての数字を一旦「1」に変換しちゃう。
また、リストのなかにはいっているリストはcount-leaves自体で数えきっちゃう。
そうしてやるとリストのなかに、


もともと数字だったら「1」
リストだったらそのリストの内容の項目数


そういう整数がはいったリストができるので、そいつをアキュムレータで足していくと言う作業をやる。
そんな考え方で作ったのがこれだ。

#!/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 (count-leaves t)
  (accumulate + 0 (map (lambda (x) (if (pair? x) (count-leaves x) 1)) t)))


;; main
(define (main args)

  (display "(count-leaves '(1 2 3 (4 5 (6 7) 8 9) 10 11 (12) 13)): ")
  (display (count-leaves '(1 2 3 (4 5 (6 7) 8 9) 10 11 (12) 13)))
  (newline)

  0)


実行

(count-leaves '(1 2 3 (4 5 (6 7) 8 9) 10 11 (12) 13)): 13

できている!