第14回 最終課題 (7月16;17日)
■ 最終課題について
以下の問題1〜6のうち1つを選択しよう。プログラムおよび実行結果を印刷し、コメントを手書きせよ。実行結果の説明の際、作成した全ての項目について、正しいことの確認できる箇所を明示せよ。
□ 問題1
Squeak を使用して、花火の絵を描こう。以下のとおり操作できるように作成
しよう。
- Fireworks クラスにメッセージ「new」を送ると、1つの花火のインスタンス fw が作られる。
- fw にメッセージ「launcher: p」を送ると、花火の発射台が p に設置される設定にする。p は Point のインスタンスであり、たとえば 300@300 である。
- fw にメッセージ「shoot: h size: s step: d」を送ると、大きさ s の火の玉が高さ h だけ打ち上げられる設定にする。火の玉は楕円体オブジェクトであり、その表示は、距離 d ずつ間隔をあける。h, s, d は数値である。
- fw にメッセージ「expand: n radius: r size: s step: d」を送ると、大きさ s の火の玉が n 方向に広がる設定にする。その距離はそれぞれ r とする。広がる火の玉は星オブジェクトであり、その表示は、距離 d ずつ間隔をあける。n, r, s, d は数値である。
- fw にメッセージ「openInWorld」を送ると、上記の設定値に従って図形オブジェクトが画面に表示される。
- fw にメッセージ「delete」を送ると、画面から消える。
- 火の玉の大きさ、色、表示の間隔が単調にならないようにするなど、オリジナリティのある追加機能を1つ実現せよ。
□ 問題2
Squeak を使用して、放物線の絵を描こう。以下のとおり操作できるように作成しよう。
- Cannonball クラスにメッセージ「new」を送ると、1つの砲丸のインスタンス cb が作られる。
- cb にメッセージ「screen: po scale: s」を送ると、物理座標の原点の対応する位置を、Sqeak の画面の座標上の po とし、物理座標系の1を、Squeak の画面の座標上のsに対応するものとする。po は Point のインスタンスとする。s は数値とする。物理座標系と画面の座標系は上下が反対である。
- cb にメッセージ「shoot: th velocity: v interval: tm to: te」を送ると、仰角 t、初速度 v で包含が発射される設定にする。ここで、th は度数、v, tm, te は数値である。砲丸は、時刻 0 に発射される。表示については、時刻 te までにおいて、時間間隔 tm ごとに弾道上に砲丸を描く設定にする。砲丸は楕円オブジェクトとする。
- cb にメッセージ「openInWorld」を送ると、上記の設定に従い、オブジェクトが画面に表示される。
- cg にメッセージ「delete」を送ると、楕円オブジェクトが画面から消える。
- 放物線以外の軌跡を少なくとも1つ考えて、それを表示する新しいクラスを作成しよう。
□ 問題3
Scheme において、オブジェクト指向的に行列を扱おう。以下のとおり操作できるように作成しよう。
- (define m1 (matrix i j)) とすると i 行 j 列の行列が返される。この例では、それを m1 と呼ぶことにする。以下では、この m1 を使用する。なお、m1 は関数である。
- ((m1 'zero)) とすると行列 m1 の全ての要素を 0 にする。
- ((m1 'show)) とすると行列 m1 を表示する。
- ((m1 'from-list) lst) とするとリスト lst の各要素を行列 m1 の各要素に入力する。
- ((m1 'to-list)) とすると行列 m1 の各要素をリストに出力する。
- ((m1 'set!) i j d) とすると行列 m1 の i 行 j 列目の要素を d とする。i, j, d は数値である。
- ((m1 'refer) i j) とすると行列 m1 の i 行 j 列目の要素を返す。i, j は数値である。
- ((m1 'identity)) とすると行列 m1 を単位行列にする。
- ((m1 'scalar) d) とすると、行列 m1 への d のスカラ積でできる新しい行列を返す。
- ((m1 'add) m2) とすると、行列 m1 と行列 m2 の足し算でできる新しい行列を返す。
□ 問題4
Scheme において、リストを用いて行列を扱おう。以下のとおり操作できるように作成しよう。
- (define m1 (matrix i j)) とすると i 行 j 列の行列を生成するものとする。この例では、それを m1 と呼ぶことにする。m1 はリストであり、最初の2つの要素は i と j である。残りの要素は 0 で埋められるものとする。
- (matrix-from-list m1 lst) とすると、リストの各要素を行列 m1 の各要素に入力し、その結果を新たな行列で表したものが返される。
- (matrix-to-list m1) とすると、行列 m1 の各要素をリストに出力する。
- (matrix-set m1 i j d) とすると、行列 m1 の i 行 j 列の要素を d とした新たな行列が返される。
- (matrix-refer m1 i j) とすると、行列 m1 の i 行 j 列の要素を返す。
- (matrix-indentity m1) とすると、行列 m1 を基に新たに作成した単位行列が返される。つまり、m1 と行数と列数の同じ単位行列が返される。
- (matrix-scalar m1 d) とすると、行列 m1 への d のスカラ積である新たな行列が返される。
- (matrix-add m1 m2) とすると、行列 m1 と行列 m2 の和を表す新たな行列が返される。
- (matrix-mult m1 m2) とすると、行列 m1 と行列 m2 の積(m1×m2)を表す新たな行列が返される。
□ 問題5
Prolog において、F1グランプリの得点を計算しよう。以下のとおり操作ができるように作成しよう。以前の演習で作成した gpx/2, person/2, team/2 を使用する。
- point_table/3 はレース状態と順位と得点の関係を表す事実である。第一引数のレース状態には、normal と redflag がある。順位は1から8までがある。得点は、1位のとき10点、2位のとき8点、3位のとき6点、4位のとき5点、5位のとき4点、6位のとき3点、7位のとき2点、8位のとき1点である。redflag(赤旗でレース中断)のときは得点が半分(小数点あり)となる。上記以外の順位のときは0点である。
- ranking/2 は、ドライバーに対する順位リストを表す規則である。たとえば、「?- ranking(but,L).」と質問をすると、「L=[1,1,3,1,1,1,1,6]」が得られる。なお、完走しなかった場合は順位を0とする。
- race_state/2 は、開催国とレース状態の関係を表す事実である。第一引数は開催国、第二引数はレース状態である。第8戦までのところ、「race_state(malaysia,redflag)」であり、その他の国においては normal である。
- point/2 は、ドライバーに対する得点を表す規則である。第一引数は、ドライバーのニックネーム、第二引数は得点のリストである。たとえば、「?- point(but,L).」と質問すると、「L=[10,5,6,10,10,10,10,3]」が得られる。
- constructors/2 は、チームの得点を計算する規則である。第一引数はチーム名、第二引数は得点のリストである。各チームには2名のドライバーが存在するので、両者の合計得点がチームの得点となっている。たとえば、「?- point('ブラウンGP', L).」と質問すると、「L=[18,7,11,14,18,18,10,9]」が得られる。
- sum/2 は、数値のリストから合計値を計算する規則である。第一引数が、数値のリスト、第二引数が合計値である。
- 好みの規則を作成しよう。
- shinji は、最も得点の高いドライバーを好む。
- satoshi は、最も入賞回数の多いドライバーを好む。
- takeshi は、得点が最も高いチームに所属するドライバーを好む。
□ 問題6
Squeak, Scheme, Prologから2つの言語、および, C言語の合計3つの言語において、以下の内容のプログラムを作成しよう。C言語の場合、表示するサブルーチンを適宜作成せよ。代入や並び替えの際、破壊的であってもと非破壊的であっても、どちらでも良い。サブルーチン名は、処理系に応じて書き方を変更して良い。
- 1つのレコードが、名前(abc文字列のみ、空白なし、長さは固定でも自由でも良い)と年齢(整数)で構成されるものとする。
- このレコードを複数個、順位付きに格納できるようにする。個数は上限を固定としても自由としてもよい。
- sort_by_age 格納されたものを、年齢で並び替えよう。C言語の場合できれば qsort 命令を使ってみよう。
- sort_by_name 格納されたものを、名前(アルファベット辞書順)で並び替えよう。C言語の場合できれば qsort 命令を使ってみよう。
- adult 格納されたものから、20歳以上の者のレコードのみを格納したものを作成しよう。
- aging 格納されたものの各レコードにおいて、年齢を1つ増やす処理をしよう。
- reverse 格納されたものを逆順に並び替えよう。
(c) 2009.7.15 by tokuhisa