読者です 読者をやめる 読者になる 読者になる

SICPを読む会 1 問題1.3

読む会SICPを黙々と読む。

SICP Support for DrRacketのインストールを参考にDrRacketをインストールして実行環境を作成します。
DrRacketで言語宣言ペイン(上側のペイン)で、#lang planet neil/sicp と書いて実行しても調べたページとは違う挙動しましたが Schemeが実行出来るようなで練習問題を実施。

今日は問題1.3を実施。
今回は考え方としては3値のうち一番小さい値は何かという観点で手続きを定義します。
下記の一番最初のifの評価としては、『xはyよりも大きい、またはxはzよりも大きいのどちらもFalseになる = xは最も小さい』という周りくどい評価を実施しています。

> (define (square x) (* x x))
> (define (sum-of-squares x y)
    (+ (square x) (square y)))
> (define (f x y z)
    (if (or (>= x y) (>= x z)) 
        (if (or (>= y z) (>= y x)) 
            (sum-of-squares x y)
            (sum-of-squares z x)) 
        (sum-of-squares y z)))
> (f 3 4 5)
41
> (f 4 3 5)
41
> (f 4 5 3)
41

また、schemeではminという手続きが定義されており最小の値を求めることが出来るので、以下のように書き換えることが出来ます。

> (define (f x y z)
    (if (= (min x y z) x) (sum-of-squares y z)
        (if (= (min x y z) y) (sum-of-squares x z)
            (sum-of-squares x y))
        )
    )
> (f 3 4 5)
41
> (f 4 3 5)
41
> (f 5 4 3)
41

このような場合はifではなくcondを使ったほうが可読性が上がるので、condを使って書き換えます。

> (define (f x y z)
    (cond ((= (min x y z) x) (sum-of-squares y z))
          ((= (min x y z) y) (sum-of-squares x z))
          (else (sum-of-squares x y))))
> (f 3 4 5)
41
> (f 4 5 3)
41
> (f 5 3 4)
41