プログラミング言語論・第 1回レポートの答(一部)


2番

   (define (f x y) (cos (+ (* 3 x) (* 5 y))))
特に説明は要らないでしょう。なお、Schemeの cos関数は、 (他の多くのプログラミング言語の cos関数と同様に) 角度の単位はラジアンです。

3番

   (define (g x) (exp (/ 1 (* x x))))   
これも、特に説明は要らないでしょう。

4番

   (define (max3 x y z)
     (if (> x y)
	 (if (> x z) x z)
	 (if (> y z) y z)))
比較は 2回で済みます。

5番

   (define (mid3 x y z)
     (if (> x y)
	 (if (> y z) y   ; x > y > z
	     (if (> z x)
		 x       ; z > x > y
		 z))     ; x > z > y
	 (if (> x z) x   ; y > x > z
	     (if (> z y)
		 y       ; z > y > x
		 z))))
3回の比較が必要になる場合があります。

6番

   (define (foo g x1 y1 x2 y2)
      (graphics-draw-line g x1 y1 x2 y1)
      (graphics-draw-line g x2 y1 x1 y2)
      (graphics-draw-line g x1 y2 x2 y2)
      (graphics-draw-line g x2 y2 x1 y1))
これを実行するには次のようにします。
   (define gd (make-graphics-device #f))
   (foo gd 0 0 1 1)

7番

   (define (gcd m n)
	(if (= n 0)
	    m
	    (gcd n (modulo m n))))
mnの大小を気にしている人がいましたが、 m<nの時でもこれで大丈夫です。

8番

解いている人が少なかったので、2回目のレポートで再出題します。

(参考)ディオファントゥス方程式 a x + b y = c の解き方

9番

   (define (binary n)
      (if (= n 0) '()
	  (cons (modulo n 2) (binary (quotient n 2)))))
ただし、この場合、結果が逆順になります。 (binary 11)(1 1 0 1)です。

通常の順番にするには、引数を増やした補助関数を定義します。

   (define (binary-aux n acc)
       (if (= n 0) acc
           (binary-aux (quotient n 2)
                       (cons (modulo n 2) acc))))

   (define (binary n) (binary-aux n '()))
引数を増やした補助関数を定義するのは、良く使うテクニックです。

10番

   ; 日曜 -- 0, 月曜 -- 1, 火曜 -- 2, ..., 土曜 -- 7
   (define (taiiku-no-hi y)
	   (let* ((day  (zeller y 10 8))       ; y年 10月 8日の曜日
		  (rest (modulo (- 1 day) 7))) ; 次の月曜まで、あと何日か?
	    (+ 8 rest)))
8日は第2週の最初の日です。8日以降の最初の月曜日が第 2月曜日です。 例えば、8日が火曜日の時、dayの値は火曜日を表す数の 2になります。 月曜日は 1で表されるので、 月曜日までの日数は 1-2を 7で割った余りとして求められます。
Koji Kagawa (kagawa@eng.?????)