第14回 最終課題 (7月16;17日)

■ 最終課題について

以下の問題1〜6のうち1つを選択しよう。プログラムおよび実行結果を印刷し、コメントを手書きせよ。実行結果の説明の際、作成した全ての項目について、正しいことの確認できる箇所を明示せよ。

□ 問題1

Squeak を使用して、花火の絵を描こう。以下のとおり操作できるように作成 しよう。

  1. Fireworks クラスにメッセージ「new」を送ると、1つの花火のインスタンス fw が作られる。
  2. fw にメッセージ「launcher: p」を送ると、花火の発射台が p に設置される設定にする。p は Point のインスタンスであり、たとえば 300@300 である。
  3. fw にメッセージ「shoot: h size: s step: d」を送ると、大きさ s の火の玉が高さ h だけ打ち上げられる設定にする。火の玉は楕円体オブジェクトであり、その表示は、距離 d ずつ間隔をあける。h, s, d は数値である。
  4. fw にメッセージ「expand: n radius: r size: s step: d」を送ると、大きさ s の火の玉が n 方向に広がる設定にする。その距離はそれぞれ r とする。広がる火の玉は星オブジェクトであり、その表示は、距離 d ずつ間隔をあける。n, r, s, d は数値である。
  5. fw にメッセージ「openInWorld」を送ると、上記の設定値に従って図形オブジェクトが画面に表示される。
  6. fw にメッセージ「delete」を送ると、画面から消える。
  7. 火の玉の大きさ、色、表示の間隔が単調にならないようにするなど、オリジナリティのある追加機能を1つ実現せよ。

□ 問題2

Squeak を使用して、放物線の絵を描こう。以下のとおり操作できるように作成しよう。

  1. Cannonball クラスにメッセージ「new」を送ると、1つの砲丸のインスタンス cb が作られる。
  2. cb にメッセージ「screen: po scale: s」を送ると、物理座標の原点の対応する位置を、Sqeak の画面の座標上の po とし、物理座標系の1を、Squeak の画面の座標上のsに対応するものとする。po は Point のインスタンスとする。s は数値とする。物理座標系と画面の座標系は上下が反対である。
  3. cb にメッセージ「shoot: th velocity: v interval: tm to: te」を送ると、仰角 t、初速度 v で包含が発射される設定にする。ここで、th は度数、v, tm, te は数値である。砲丸は、時刻 0 に発射される。表示については、時刻 te までにおいて、時間間隔 tm ごとに弾道上に砲丸を描く設定にする。砲丸は楕円オブジェクトとする。
  4. cb にメッセージ「openInWorld」を送ると、上記の設定に従い、オブジェクトが画面に表示される。
  5. cg にメッセージ「delete」を送ると、楕円オブジェクトが画面から消える。
  6. 放物線以外の軌跡を少なくとも1つ考えて、それを表示する新しいクラスを作成しよう。

□ 問題3

Scheme において、オブジェクト指向的に行列を扱おう。以下のとおり操作できるように作成しよう。

  1. (define m1 (matrix i j)) とすると i 行 j 列の行列が返される。この例では、それを m1 と呼ぶことにする。以下では、この m1 を使用する。なお、m1 は関数である。
  2. ((m1 'zero)) とすると行列 m1 の全ての要素を 0 にする。
  3. ((m1 'show)) とすると行列 m1 を表示する。
  4. ((m1 'from-list) lst) とするとリスト lst の各要素を行列 m1 の各要素に入力する。
  5. ((m1 'to-list)) とすると行列 m1 の各要素をリストに出力する。
  6. ((m1 'set!) i j d) とすると行列 m1 の i 行 j 列目の要素を d とする。i, j, d は数値である。
  7. ((m1 'refer) i j) とすると行列 m1 の i 行 j 列目の要素を返す。i, j は数値である。
  8. ((m1 'identity)) とすると行列 m1 を単位行列にする。
  9. ((m1 'scalar) d) とすると、行列 m1 への d のスカラ積でできる新しい行列を返す。
  10. ((m1 'add) m2) とすると、行列 m1 と行列 m2 の足し算でできる新しい行列を返す。

□ 問題4

Scheme において、リストを用いて行列を扱おう。以下のとおり操作できるように作成しよう。

  1. (define m1 (matrix i j)) とすると i 行 j 列の行列を生成するものとする。この例では、それを m1 と呼ぶことにする。m1 はリストであり、最初の2つの要素は i と j である。残りの要素は 0 で埋められるものとする。
  2. (matrix-from-list m1 lst) とすると、リストの各要素を行列 m1 の各要素に入力し、その結果を新たな行列で表したものが返される。
  3. (matrix-to-list m1) とすると、行列 m1 の各要素をリストに出力する。
  4. (matrix-set m1 i j d) とすると、行列 m1 の i 行 j 列の要素を d とした新たな行列が返される。
  5. (matrix-refer m1 i j) とすると、行列 m1 の i 行 j 列の要素を返す。
  6. (matrix-indentity m1) とすると、行列 m1 を基に新たに作成した単位行列が返される。つまり、m1 と行数と列数の同じ単位行列が返される。
  7. (matrix-scalar m1 d) とすると、行列 m1 への d のスカラ積である新たな行列が返される。
  8. (matrix-add m1 m2) とすると、行列 m1 と行列 m2 の和を表す新たな行列が返される。
  9. (matrix-mult m1 m2) とすると、行列 m1 と行列 m2 の積(m1×m2)を表す新たな行列が返される。

□ 問題5

Prolog において、F1グランプリの得点を計算しよう。以下のとおり操作ができるように作成しよう。以前の演習で作成した gpx/2, person/2, team/2 を使用する。

  1. 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点である。
  2. ranking/2 は、ドライバーに対する順位リストを表す規則である。たとえば、「?- ranking(but,L).」と質問をすると、「L=[1,1,3,1,1,1,1,6]」が得られる。なお、完走しなかった場合は順位を0とする。
  3. race_state/2 は、開催国とレース状態の関係を表す事実である。第一引数は開催国、第二引数はレース状態である。第8戦までのところ、「race_state(malaysia,redflag)」であり、その他の国においては normal である。
  4. point/2 は、ドライバーに対する得点を表す規則である。第一引数は、ドライバーのニックネーム、第二引数は得点のリストである。たとえば、「?- point(but,L).」と質問すると、「L=[10,5,6,10,10,10,10,3]」が得られる。
  5. constructors/2 は、チームの得点を計算する規則である。第一引数はチーム名、第二引数は得点のリストである。各チームには2名のドライバーが存在するので、両者の合計得点がチームの得点となっている。たとえば、「?- point('ブラウンGP', L).」と質問すると、「L=[18,7,11,14,18,18,10,9]」が得られる。
  6. sum/2 は、数値のリストから合計値を計算する規則である。第一引数が、数値のリスト、第二引数が合計値である。
  7. 好みの規則を作成しよう。

□ 問題6

Squeak, Scheme, Prologから2つの言語、および, C言語の合計3つの言語において、以下の内容のプログラムを作成しよう。C言語の場合、表示するサブルーチンを適宜作成せよ。代入や並び替えの際、破壊的であってもと非破壊的であっても、どちらでも良い。サブルーチン名は、処理系に応じて書き方を変更して良い。

  1. 1つのレコードが、名前(abc文字列のみ、空白なし、長さは固定でも自由でも良い)と年齢(整数)で構成されるものとする。
  2. このレコードを複数個、順位付きに格納できるようにする。個数は上限を固定としても自由としてもよい。
  3. sort_by_age   格納されたものを、年齢で並び替えよう。C言語の場合できれば qsort 命令を使ってみよう。
  4. sort_by_name   格納されたものを、名前(アルファベット辞書順)で並び替えよう。C言語の場合できれば qsort 命令を使ってみよう。
  5. adult   格納されたものから、20歳以上の者のレコードのみを格納したものを作成しよう。
  6. aging   格納されたものの各レコードにおいて、年齢を1つ増やす処理をしよう。
  7. reverse   格納されたものを逆順に並び替えよう。

(c) 2009.7.15 by tokuhisa