Files
2026-10-05 11:23:25 +09:00

228 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Question22 - 処理そのものを値として扱う
本資料の練習問題は、複数のプログラミング言語(Java / C# / PHP / Python)で共通して利用できるよう記述されています。静的型付け・動的型付けの違いや文字列の連結ルールなど、言語固有の文法仕様に基づき、問題文の表現をご使用の言語の仕様に適宜読み替えて進めてください。
## この問題のねらい
- 「一連の処理のかたまり」を、データと同じように変数に代入したり、変数を経由して呼び出したりできること
- 既に名前が付いている処理(既存のメソッド)を、その名前を通じてではなく、変数に代入した「値」として扱えること
- その場限りの、名前を持たない処理のかたまりをその場で定義し、変数に代入して使えること
- 引数の型を特定の1種類に固定せず、様々な種類のデータに対応できる、汎用的な「処理の型(受け取る値の数・型、戻り値の型の組み合わせ)」を定義できること(これは主に、処理を値として扱う際に変数の型を明示的に指定する必要がある言語で意味を持つ達成目標です。型を指定しなくても処理をそのまま値として扱える言語では、この項目を特に意識する必要はありません)
- 一覧(コレクション)に対して、条件による絞り込みなどの一括処理を行えること
以下の設問はそれぞれ独立したプログラムとして実装してください。
## 共通で使用するデータ定義
複数の設問で、以下のデータ定義・補助処理を共有します。各設問の実装言語に合わせて、同等の意味を持つ形で用意してください。
### Userデータ(設問1・設問4で使用)
利用者1件分の情報を保持するデータで、以下の項目を持ちます。
- 名前
- メールアドレス
- パスワード
保持している内容を、次の形式の1行の文字列に変換する処理を持ちます(項目の間はタブ区切り)。
```
名前:<名前> メールアドレス:<メールアドレス> パスワード:<パスワード>
```
### CarデータとDriverデータ(設問2で使用)
**Car(車)データ**は、以下の項目を持ちます。
- 色
- 残りのガソリン量(整数)
- 紐づく運転手データ(Driverデータへの参照)
Carデータは「走行処理」を持ちます。呼び出されるたびに次の動作を行います。
1. 残りのガソリン量を1減らす
2. 減らした結果が0未満になった場合、-1を返して終了する(それ以上走行できないことを表す)
3. 上記に該当しない場合、1〜15の範囲でランダムに決めた距離(整数)を返す
**Driver(運転手)データ**は、以下の項目を持ちます。
- 名前
- 免許番号(桁数の大きい整数を扱える型)
- 年齢
- 住所
Driverデータは、車の色を引数として受け取る「表示処理」を持ちます。呼び出されると、次の2行を画面に出力します(項目名と値の間は全角コロン、住所の項目名の後ろだけ区切り記号を入れない点に注意してください)。
```
<車の色>色の車に乗っています
名前:<名前> 免許番号:<免許番号> 年齢:<年齢> 住所<住所>
```
### 3つの値を合計する処理(設問3・設問5で使用)
3つの整数を受け取り、その合計(整数)を返す処理(`Calc.addition` に相当するもの)を作成してください。この処理は設問3・設問5で共通して使用し、内容は変更しないものとします。
### Player一覧の取得(設問6・設問7で使用)
サッカー選手1件分の情報を表す**Playerデータ**は、以下の項目を持ちます。
- ポジション
- 名前
- 国
- 所属チーム
保持している内容を、次の形式の1行の文字列に変換する処理を持ちます(各項目をカンマ区切りで連結)。
```
<ポジション>,<名前>,<国>,<所属チーム>
```
Player一覧を取得する補助処理(`PlayerUtill.getPlayerList` に相当)を作成してください。この処理は、以下の形式のファイル(`file/BestElevenCandidate.csv`)を1行ずつ読み込み、各行をカンマ区切りで分割して、ポジション・名前・国・所属チームの順にPlayerデータへ変換し、一覧(リスト)として返すものとします。ファイルが見つからない場合は「ファイルが見つかりません」と画面に表示し、空の一覧を返すものとします。
### Food一覧の取得(設問8で使用)
料理1件分の情報を表す**Foodデータ**は、以下の項目を持ちます。
- 料理名
- 値段(整数)
Food一覧を取得する補助処理(`FoodUtill.getFoodList` に相当)を作成してください。この処理は、以下の形式のファイル(`file/FoodMenu.csv`)を1行ずつ読み込み、各行をカンマ区切りで分割して、料理名・値段の順にFoodデータへ変換し、一覧(リスト)として返すものとします。ファイルが見つからない場合は「ファイルが見つかりません」と画面に表示し、空の一覧を返すものとします。
---
## 設問1
3件のUserデータのインスタンスを、この順番で用意してください。
| 名前 | メールアドレス | パスワード |
| --- | --- | --- |
| 田中太郎 | tanaka@hoge,.com | tanaka@0000 |
| 鈴木一郎 | suzuki@hoge,.com | suzuki@1111 |
| 山田二郎 | yamada@hoge,.com | yamada@2222 |
(メールアドレスの表記中に読点のようなカンマが含まれていますが、誤記ではなくそのままの値として扱ってください)
上記3件を保持する一覧を作成したうえで、次の処理を実装してください。
1. 「Userの一覧を受け取り、各Userを前述の文字列表現に変換した文字列の一覧(リスト)を作って返す」という、名前の付いた処理(`createUsersInfo` に相当するもの)をあらかじめ用意する
2. 用意したその処理を、直接名前で呼び出すのではなく、いったん変数に代入する(=処理そのものを値として変数に格納する)
3. その変数を経由して、手順1の処理を実行する(引数として、用意した3件のUser一覧を渡す)
4. 実行結果として得られた文字列の一覧を出力する
- 期待される実行結果: 3件分のUserの文字列表現(前述の形式)が、何らかの形で読み取れるように出力されること(1件ずつ出力しても、一覧としてまとめて出力してもよい)
---
## 設問2
3台のCarデータのインスタンスと、それぞれに対応するDriverデータのインスタンスを、以下の内容で用意してください。
| | 色 | ガソリン量 | 運転手名 | 免許番号 | 年齢 | 住所 |
| --- | --- | --- | --- | --- | --- | --- |
| 1台目 | 赤 | 50 | 田中太郎 | 123456789101 | 28 | 東京都中央区日本橋1-2-3 |
| 2台目 | 黄 | 60 | 佐藤二朗 | 109876543210 | 45 | 東京都豊島区北池袋1-2-3 |
| 3台目 | 青 | 70 | 鈴木三郎 | 101010101010 | 39 | 埼玉県さいたま市大宮区錦町1-2-3 |
目的地までの距離を300と定め、3台のCarを1台ずつ順番に処理してください。各Carについて、以下を実装してください。
1. そのCarの「走行処理」と、対応するDriverの「表示処理」を、それぞれいったん変数に代入する(=処理そのものを値として変数に格納する)
2. 「運転手の情報です。」と出力する
3. 手順1で変数に代入しておいた表示処理を、その変数経由で実行する(引数としてCarの色を渡す)
4. 進んだ距離の合計と、走行処理を実行した回数を、それぞれ0で初期化する(この初期化はCar1台ごとに行うこと)
5. 次の繰り返しを行う
1. 手順1で変数に代入しておいた走行処理を、その変数経由で実行し、戻り値を受け取る
2. 戻り値が-1であれば、「目的地に到達できませんでした」と出力し、この車についての繰り返しを終了する
3. 戻り値が-1でなければ、進んだ距離の合計に戻り値を加算し、実行回数を1増やす
4. 進んだ距離の合計が目的地までの距離(300)以上になっていれば、「目的地にまで<実行回数>時間かかりました。残りのガソリンは、<残りのガソリン量>リットルです」と出力し(末尾に空行を1行入れる)、この車についての繰り返しを終了する
5. 上記のいずれにも該当しなければ、5.のはじめに戻る
- 補足: 走行処理の結果はランダムに決まるため、実際に出力される走行回数・残りガソリン量は実行のたびに変わってよい。ただし上記の手順・条件どおりに処理されていること
- 補足: 3台それぞれについて、上記1〜5を独立して(前の車の状態を引き継がずに)実行すること
---
## 設問3
1から9までの整数を順に並べた一覧を用意してください。まず「計算元の値です」と出力し、続けてこの一覧の値をタブ区切りで出力してください。
次に、0から8までの範囲でランダムな整数を3つ選んでください(3つとも独立に選んでよく、同じ値が選ばれてもよい)。改行してから「ランダムに数値を3つ選び足し算します(選ばれた順に足し算します)」と出力してください。
続けて、以下を実装してください。
1. 「同じ種類の値を3つ受け取り、整数の戻り値を返す」という処理の型(受け取る値の型は特定の1種類に固定せず、後から様々な型に対応できる汎用的なもの)を定義する
2. 手順1で定義した処理の型を使って、共通データ定義に記載した3つの値を合計する処理(`Calc.addition` に相当するもの)を扱えるようにする
3. 手順1・2で用意した処理を使い、先ほど選んだ3つのランダムな整数を、それぞれ一覧の中の何番目の値か(0番目から数えて)を表すインデックスとして扱い、一覧から該当する3つの値を取り出す
4. 取り出した3つの値を、選ばれた順のまま手順1・2の処理に渡して合計を求める
5. 求めた合計値を出力する
- 補足: 手順1は、使用する言語によっては意味を持たない場合があります。このような汎用的な処理の型が標準で用意されている言語では、新たに定義せずその標準の型をそのまま使ってください。型を指定しなくても処理を値として扱える言語では、そもそも処理の型を定義する必要がないため、手順1は省略し、手順2以降の内容から進めてください。
---
## 設問4
設問1と同じ3件のUserデータのインスタンス(表・値は設問1を参照)を用意してください。
設問1の「Userの一覧を受け取り、各Userを文字列表現に変換した一覧を返す」処理と同じ内容の処理を、今回はあらかじめ名前を付けて定義しておくのではなく、その場で(名前を付けずに)処理内容を書き、直接変数に代入してください。
その変数を経由してこの処理を実行し(引数として3件のUser一覧を渡す)、実行結果として得られた文字列の一覧を出力してください。
- 期待される実行結果: 設問1と同じく、3件分のUserの文字列表現が読み取れるように出力されること
---
## 設問5
設問3と同じ準備を行ってください。
1. 1から9までの整数を順に並べた一覧を用意し、「計算元の値です」と出力してから、一覧の値をタブ区切りで出力する
2. 0から8までの範囲でランダムな整数を3つ選ぶ
3. 改行してから「ランダムに数値を3つ選び足し算します(選ばれた順に足し算します)」と出力する
続けて、以下を実装してください。
1. 「3つの値を受け取り、その合計を返す」処理を、名前を付けずにその場で定義し、変数に代入する。既存の`Calc.addition`のような名前付きの処理を呼び出すのではなく、合計を求める処理そのものを、できるだけ簡潔な書き方でその場に書くこと
2. 手順2で選んだ3つのランダムな整数を、一覧の中の何番目の値かを表すインデックス(0番目から数える)として扱い、一覧から該当する3つの値を取り出す
3. 取り出した3つの値を、選ばれた順のまま手順1の処理に渡して合計を求める
4. 求めた合計値を出力する
---
## 設問6
共通データ定義に記載したPlayer一覧の取得処理を使って、選手の一覧を取得してください。
取得した一覧の中から、ポジションが「FW」である選手だけを抽出し、抽出した選手を1件ずつ、前述のPlayerの文字列表現(カンマ区切り)で出力してください。
- 抽出には、一覧に対する条件による絞り込みなど、コレクションへの一括処理の仕組みを使うこと
- 期待される実行結果: `file/BestElevenCandidate.csv` の中でポジションが「FW」である全ての選手(15名)が出力される
---
## 設問7
共通データ定義に記載したPlayer一覧の取得処理を使って、選手の一覧を取得してください。
取得した一覧の中から、次の条件をすべて満たす選手だけを抽出し、抽出した選手を1件ずつ、Playerの文字列表現(カンマ区切り)で出力してください。
- 所属チームが「レアル・マドリード」ではない
- 所属チームが「バルセロナ」ではない
- ポジションが「MF」である
- 抽出には、一覧に対する条件による絞り込みなど、コレクションへの一括処理の仕組みを使うこと
---
## 設問8
共通データ定義に記載したFood一覧の取得処理を使って、料理の一覧を取得してください。
取得した料理一覧の並び順をランダムに入れ替えたうえで、以下を実装してください。
1. 並び替え後の一覧から、重複せずに3品を選ぶ
2. 選んだ3品の料理名と、選んだ3品の値段の合計(消費税8%を加算し、小数点以下は切り捨てたもの)を求める
3. 選んだ3品の料理名と、手順2で求めた合計金額が読み取れる形で出力する
- 抽出・集計には、一覧に対する一括処理の仕組みを使うこと
- 補足: 選ぶ料理はランダムに決まるため、実際に出力される料理名・合計金額は実行のたびに変わってよい。ただし「重複しない3品を選ぶこと」「消費税8%を加算し小数点以下切り捨てで合計金額を求めること」は満たすこと