平成 25 年度 プログラミング言語 II 期末試験 解答例 問題1 次の()~()の

平成 25 年度 プログラミング言語 II 期末試験 解答例
問題1
次の(𝑎𝑎)~(𝑐𝑐)の計算結果を記述せよ。(プログラムや計算過程を記述する必要はない。)
(𝑎𝑎) �183 +
8 13 132 2 10
8
+
+
− × �×
9 10 83 5 8
3
(解答例)
496 8344/11205
(解答例)
496.7446675591254
(解答例)
5566024/11205
[求め方]
(* (+ 183 (/ 8 9) (/ 13 10) (/ 132 83) (* -1 (/ 2 5) (/ 10 8)))
(/ 8 3))
で計算する。
(𝑏𝑏) 1から10000までの偶数の和
(解答例)
25005000
[求め方]
(reduce + 0 (filter even? (range 1 10000))) で計算できる。
(𝑐𝑐) 1から10000までの数のうち37の倍数である数の和
(解答例)
1353645
[求め方]
(reduce + 0 (filter (lambda (x) (= (remainder x 37) 0)) (range 1 10000)))で計算できる。
問題2 次の(a)~(c)の式を置き換えモデルにより計算せよ。 (3点×3)
(a)
((lambda (x y z) (+ x (* y z))) 10 8 3)
(解答例)
((lambda (x y z) (+ x (* y z))) 10 8 3)
1
(2点×3)
= (+ 10 (* 8 3))
= 34
(b)
((lambda (x y z) (x (y z) 10)) (lambda (a b) (+ a (* 30 b))) (lambda (c) (+ 100 c)) 50)
(解答例)
((lambda (x y z) (x (y z) 10)) (lambda (a b) (+ a (* 30 b))) (lambda (c) (+ 100 c)) 50)
= ((lambda (a b) (+ a (* 30 b))) ((lambda (c) (+ 100 c)) 50) 10)
= ((lambda (a b) (+ a (* 30 b))) 150 10)
= (+ 150 (* 30 10))
= 450
(c)
((lambda (x y z) (x (y z) 10)) (lambda (a b) (a (* 30 b))) (lambda (c) (lambda (d) (- d c))) 50)
(解答例)
((lambda (x y z) (x (y z) 10)) (lambda (a b) (a (* 30 b))) (lambda (c) (lambda (d) (- d c))) 50)
= ((lambda (a b) (a (* 30 b))) ((lambda (c) (lambda (d) (- d c))) 50) 10)
= ((lambda (a b) (a (* 30 b))) (lambda (d) (- d 50)) 10)
= ((lambda (d) (- d 50)) 300)
= (- 300 50)
= 250
問題3 ある二つのリストを受け取り、
各リストの要素を前から順に交互に混ぜて一つのリストにする関数
mergeをSchemeで記述せよ。受け取った二つのリストの長さが異なる場合は途中から交互に混ぜることが
できなくなり長いほうのリストに余りが生じてしまうが、その場合は出力するリストの末尾にその余っ
た部分リストをつなげて出力するようにせよ。例えば、次のような結果になればよい。
> (merge '(1 2 3 4 5) '(a b c d e))
(1 a 2 b 3 c 4 d 5 e)
> (merge '(1 2 3 4 5 6 7 8 9 10) '(a b c d e f))
(1 a 2 b 3 c 4 d 5 e 6 f 7 8 9 10)
> (merge '(1 2 3 4 5 6) '(a b c d e f g h i))
(1 a 2 b 3 c 4 d 5 e 6 f g h i)
(解答例)
(define (merge x y)
(if (null? x)
y
(if (null? y)
x
(cons (car x) (merge y (cdr x))))))
2
問題4
1772521884131701942148を素因数分解せよ。ただし、プログラムや計算過程を記述する必要はない。
※素因数分解とはある与えられた正の整数を素数の積の形で表すことである。
※答えが完全な正解でなくても求めた素因数に応じて部分点や減点があるので注意。
(7点)
(解答例)
1772521884131701942148 = 2 × 2 × 7 × 13 × 19 × 631 × 2477 × 4481 × 4621 × 7919
[求め方]
例えば、次のようなプログラムを書けば素因数をすべて求められる。
(define (prime-decomp d x)
(if (= x 1)
'()
(if (= (remainder x d) 0)
(cons d (prime-decomp d (/ x d)))
(prime-decomp (+ d 1) x))))
(prime-decomp 2 1772521884131701942148)
また、手動で小さな数で割っていくということを繰り返して素因数を一つ一つ求める方法もある。
問題5
る。
𝑋𝑋を1から10までの整数の集合とし(すなわち、𝑋𝑋 = {1,2,3,4,5,6,7,8,9,10})、関数𝑓𝑓を次のように定義す
𝑓𝑓(𝑥𝑥, 𝑦𝑦, 𝑧𝑧) = −𝑥𝑥 2 𝑧𝑧 2 + 12𝑥𝑥 2 𝑧𝑧 − 37𝑥𝑥 2 + 14𝑥𝑥𝑧𝑧 2 − 167𝑥𝑥𝑥𝑥 + 516𝑥𝑥 − 𝑦𝑦 2 + 4𝑦𝑦 − 50𝑧𝑧 2 + 597𝑧𝑧
次の(a)~(b)に答えよ。
(a) 𝑓𝑓(𝑥𝑥, 𝑦𝑦, 𝑧𝑧)を計算する関数fをSchemeで記述せよ。 (2点)
(解答例)
(define (f x y z)
(+ (* -1 x x z z)
(* 12 x x z)
(* -37 x x)
(* 14 x z z)
(* -167 x z)
(* 516 x)
(* -1 y y)
(* 4 y)
(* -50 z z)
(* 597 z)))
3
(b) 𝑥𝑥, 𝑦𝑦, 𝑧𝑧 ∈ 𝑋𝑋に対し、𝑓𝑓(𝑥𝑥, 𝑦𝑦, 𝑧𝑧)を最大にする𝑥𝑥, 𝑦𝑦, 𝑧𝑧とその最大値を答えよ。ただし、プログラムや計算過程を
記述する必要はない。
※答えが完全な正解でなくても正解の最大値に近ければ部分点があるので注意。
(8点)
(解答例)
最大値 1869 (x=8, y=2, z=7)
[求め方]
例えば、次のようなプログラムを書けば良い。
(define m (f 1 1 1))
(define max-x 1)
(define max-y 1)
(define max-z 1)
(for (range 1 10)
(lambda (x)
(for (range 1 10)
(lambda (y)
(for (range 1 10)
(lambda (z)
(if (>= (f x y z) m)
(begin
(set! m (f x y z))
(set! max-x x)
(set! max-y y)
(set! max-z z))
'done)))))))
m
max-x
max-y
max-z
[別の求め方]
(define (make-xyz-list)
(define res '())
(for (range 1 10)
(lambda (x)
4
(for (range 1 10)
(lambda (y)
(for (range 1 10)
(lambda (z)
(set! res (cons (list x y z) res))))))))
res)
(reduce (lambda (x y) (if (> (car x) (car y))
x
y))
(list (f 1 1 1) 1 1 1)
(map (lambda (l) (let ((x (car l))
(y (car (cdr l)))
(z (car (cdr (cdr l)))))
(list (f x y z) x y z)))
(make-xyz-list)))
[別の求め方]
(f x y z)に対して、x=1,…,10, y=1,…,10, z=1,…,10の組み合わせ(1000個)をひたすら実行して試してみる、
という手もある。ほかにも上記のfor-eachの3重ループだけつかって、とりあえず、x,y,zとf(x,y,z)の値を
displayで表示させて目でみて一番大きい値を選ぶ、など、さまざまな方法が考えられる。
5