第8回 練習問題の解答

練習1

練習1 (入力:リスト、出力:数値)

(1) 数を要素とするリストを入力とし、各要素を2乗して、その合計値を返す関数 sum2 を作成せよ。

(2) リストの要素数を数える関数 size を作成せよ。例えば (list 1 2 3 'ok 'ng) を入力すると 5 を返す。
(define sum2
  (lambda (lst)
    (if (null? lst)
        0
        (+ (* (car lst) (car lst)) (sum2 (cdr lst))))))

(define size
  (lambda (lst)
    (if (null? lst)
        0
        (+ 1 (size (cdr lst))))))

練習2 (入力:リスト、出力:リスト)

(1) 数を要素とするリストを入力とし、各要素を2乗したリストを返す関数 pow2-list を作成せよ。例えば (list 1 2 3 4) を入力すると (list 1 4 9 16) を返す。

(2) 数を要素とするリストと数 d を入力とし、リストの各要素について d で割った余りを求める関数 mod-list を作成せよ。例えば (list 1 2 3 4 5 6 7) と 3 を入力すると (list 1 2 0 1 2 0 1) を返す。なお、modulo により余りを計算できる。
(define pow2-list
  (lambda (lst)
    (if (null? lst)
        ()
        (cons (* (car lst) (car lst)) (pow2-list (cdr lst))))))

(define mod-list
  (lambda (lst d)
    (if (null? lst)
        ()
        (cons (modulo (car lst) d) (mod-list (cdr lst) d)))))

練習3 (入力:リストとリスト、出力:リスト)

(1) 2つのリスト lst1、lst2 を入力とし、lst1 の後に lst2 を接続したリストを返す関数 cat-list を作成せよ。例えば (list 1 2 3) と (list 4 5 6) を入力すると (list 1 2 3 4 5 6) を返す。

(2) 2つのリスト lst1、lst2 を入力とし、リストの要素を交互に要素とするリストを返す関数 merge-list を作成せよ。例えば (list 1 2 3) と (list 4 5 6) を入力すると (list 1 4 2 5 3 6) を返す。また、(list 1 2 3) と (list 4 5 6 7 8 9) を入力すると (list 1 4 2 5 3 6 7 8 9) を返す。
(define cat-list
  (lambda (lst1 lst2)
    (if (null? lst1)
        lst2
        (cons (car lst1) (cat-list (cdr lst1) lst2)))))

(define merge-list
  (lambda (lst1 lst2)
    (cond ((null? lst1) lst2)
          ((null? lst2) lst1)
          (else (cons (car lst1) (merge-list lst2 (cdr lst1)))))))

ドリルの解答

; (1)
(define max-list
  (lambda (lst)
    (define max-list00
      (lambda (lst max)
        (if (null? lst)
            max
            (if (> (car lst) max)
              (max-list00 (cdr lst) (car lst))
              (max-list00 (cdr lst) max)))))
    (max-list00 (cdr lst) (car lst))))

; (2)
(define variance-list
  (lambda (lst)
    (define pow2
      (lambda (x)
        (* x x)))
    (define ave1
      (lambda (lst s n)
        (if (null? lst)
            (/ s n)
            (ave1 (cdr lst) (+ s (car lst)) n))))
    (define ave2
      (lambda (lst s n)
        (if (null? lst)
            (/ s n)
            (ave2 (cdr lst) (+ s (pow2 (car lst))) n))))
    (- (ave2 lst 0 (length lst)) (pow2 (ave1 lst 0 (length lst))))))

; (3)
(define entropy
  (lambda (lst)
    (define log2
      (lambda (x)
        (/ (log x) (log 2))))
    (define plogp
      (lambda (p)
        (* p (log2 p))))
    (define sum-plogp
      (lambda (lst s)
        (if (null? lst)
            s
            (sum-plogp (cdr lst) (+ s (plogp (car lst)))))))
    (- (sum-plogp lst 0))))

; (4)
(define even-list
  (lambda (lst)
    (if (null? lst)
        ()
        (if (even? (car lst))
          (cons (car lst) (even-list (cdr lst)))
          (even-list (cdr lst))))))

; (5)
(define add-list
  (lambda (lst1 lst2)
    (if (null? lst1)
        ()
        (cons (+ (car lst1) (car lst2)) (add-list (cdr lst1) (cdr lst2))))))

; (6)
(define rev-list
  (lambda (lst)
    (define rev-list00
      (lambda (lst tsl)
        (if (null? lst)
            tsl
            (rev-list00 (cdr lst) (cons (car lst) tsl)))))
    (rev-list00 lst ())))