応用情報技術者過去問題 平成31年春期 午後問3
⇄問題文と設問を画面2分割で開く⇱問題PDF問3 プログラミング
券売機の注文の状態を判定するプログラムに関する次の記述を読んで,設問1~3に答えよ。
T社では,U社が経営する飲食店の店舗に設置する券売機のシステムを開発している。U社が店舗で提供する商品には,丼物や定食などのメイン商品のほか,みそ汁やサラダなどのサイドメニューがある。
U社では,特定の種類の商品を組み合わせたものをセットメニューとし,単品で注文した場合よりも安く提供している。
〔食券購入時の要件〕
食券購入時の主な要件を図1に示す。 商品と分類の具体例を表1に示す。表1中のNは分類番号,Sはセットメニューへの適用可否,Oはオプションの指定に関する情報である。Sは1のものがセットメニューへの適用可の商品である。分類番号1~3で,Oが0以外のものは,オプションの指定が必須であることを示し,Oの値は,分類番号4のOの値と対応している。オプションを指定する際には,Oの値が一致するオプションだけが選択できる。〔注文の状態の判定手順〕
券売機は,画面上で商品を選択するボタンが押されるたびに,商品の情報を蓄積する。そして,蓄積した商品の情報を用いて状態遷移を初期状態から評価し直し,注文の状態を判定する。状態の判定には図2の状態遷移図を用いる。初期状態は0である。表1のN,S,Oを左から順に並べた3桁の数をイベントコードと呼び,イベントコードの値によって状態の遷移先を制御する。 状態の判定処理では,商品の情報を入力された順に取得し,状態遷移図に基づいて状態遷移を評価する。例えば牛丼,大盛り,漬物を注文した場合,状態は0,1,2,4の順に遷移する。この場合,最後の状態が発券可の状態なので,発券ボタンを押すことができる。また,値引きのルールの条件を満たさないので,値引きはしない。
〔状態遷移表〕
状態遷移図をプログラムとして実装するためには,状態遷移図を状態遷移表にして取り扱う。注文の状態遷移表を表2に示す。表2は,状態番号とイベントコードの組合せの表であり,表の各マスには遷移先の状態番号と,遷移の際の値引きの金額が入る。
例えば,図2で状態が2のときに漬物の注文が入ると状態4に遷移し,値引きは発生しないので,表2では,状態番号が2でイベントコードが210のマスには4:0が入る。遷移後の状態が発券可の状態なので,発券ボタンを押すことができる。〔券売機の注文の状態を判定するプログラム〕
券売機の注文の状態を判定するプログラム(以下,判定プログラムという)を作成した。判定プログラムは,画面上で商品を選択するボタンが押されるたびに実行される。注文の状態を判定する手順を図3に示す。判定プログラム中で利用する主な変数,定数及び関数を表3に,作成した判定プログラムを図4に示す。
T社では,U社が経営する飲食店の店舗に設置する券売機のシステムを開発している。U社が店舗で提供する商品には,丼物や定食などのメイン商品のほか,みそ汁やサラダなどのサイドメニューがある。
U社では,特定の種類の商品を組み合わせたものをセットメニューとし,単品で注文した場合よりも安く提供している。
〔食券購入時の要件〕
食券購入時の主な要件を図1に示す。 商品と分類の具体例を表1に示す。表1中のNは分類番号,Sはセットメニューへの適用可否,Oはオプションの指定に関する情報である。Sは1のものがセットメニューへの適用可の商品である。分類番号1~3で,Oが0以外のものは,オプションの指定が必須であることを示し,Oの値は,分類番号4のOの値と対応している。オプションを指定する際には,Oの値が一致するオプションだけが選択できる。〔注文の状態の判定手順〕
券売機は,画面上で商品を選択するボタンが押されるたびに,商品の情報を蓄積する。そして,蓄積した商品の情報を用いて状態遷移を初期状態から評価し直し,注文の状態を判定する。状態の判定には図2の状態遷移図を用いる。初期状態は0である。表1のN,S,Oを左から順に並べた3桁の数をイベントコードと呼び,イベントコードの値によって状態の遷移先を制御する。 状態の判定処理では,商品の情報を入力された順に取得し,状態遷移図に基づいて状態遷移を評価する。例えば牛丼,大盛り,漬物を注文した場合,状態は0,1,2,4の順に遷移する。この場合,最後の状態が発券可の状態なので,発券ボタンを押すことができる。また,値引きのルールの条件を満たさないので,値引きはしない。
〔状態遷移表〕
状態遷移図をプログラムとして実装するためには,状態遷移図を状態遷移表にして取り扱う。注文の状態遷移表を表2に示す。表2は,状態番号とイベントコードの組合せの表であり,表の各マスには遷移先の状態番号と,遷移の際の値引きの金額が入る。
例えば,図2で状態が2のときに漬物の注文が入ると状態4に遷移し,値引きは発生しないので,表2では,状態番号が2でイベントコードが210のマスには4:0が入る。遷移後の状態が発券可の状態なので,発券ボタンを押すことができる。〔券売機の注文の状態を判定するプログラム〕
券売機の注文の状態を判定するプログラム(以下,判定プログラムという)を作成した。判定プログラムは,画面上で商品を選択するボタンが押されるたびに実行される。注文の状態を判定する手順を図3に示す。判定プログラム中で利用する主な変数,定数及び関数を表3に,作成した判定プログラムを図4に示す。
設問1
状態遷移について,(1),(2)に答えよ。
- 鮭定食,野菜サラダ,ゴマドレッシング,みそ汁の順番で注文が入った場合の状態遷移について,図2の状態番号を使って遷移する順を答えよ。
- 表2中のア,イに入れる適切な字句を答えよ。
解答入力欄
- ア:
- イ:
解答例・解答の要点
- 0,2,3,4,5
- ア:false
- イ:3:0
解説
- 表1「商品と分類の具体例」と図2「注文の状態遷移図」を参考にして、状態遷移を考えます。
まず、状態番号0の状態で鮭定食の注文が入ります。表1より鮭定食のイベントコードは"110"なので、図2から状態番号は2になることがわかります(①)。
次に、状態番号2の状態で野菜サラダの注文が入ります。表1より野菜サラダのイベントコードは"212"なので、図2から状態番号は3になることがわかります(②)。
そして、状態番号3の状態でゴマドレッシングの注文が入ります。表1よりゴマドレッシングのイベントコードは"402"なので、図2から状態番号は4になることがわかります(③)。
最後に、状態番号4の状態でみそ汁の注文が入ります。表1よりみそ汁のイベントコードは"310"なので、図2から状態番号は5になることがわかります(④)。
よって、遷移する順としては「0,2,3,4,5」が適切です。 - 〔アについて〕
図2「注文の状態遷移図」の"発券可"列には、trueまたはfalseが入ります。
アは状態番号3のときの発券可否を表します。図2「注文の状態遷移表」を見ると、状態番号3は一重丸で記述されていて凡例より発券不可な状態であることがわかります。
よって、アには発券不可を表す「false」が入ります。∴ア=false
〔イについて〕
状態遷移表内の各マスには、「遷移先の状態番号:値引額」という形式で値が格納されます。
イの値は、状態番号4のときにイベントコード"212"が入力されたときの、遷移先の状態番号及び遷移の際の値引きの金額が入ります。図2「注文の状態遷移図」より、状態番号4にイベントコード"212"が与えられたときの遷移先は、状態番号3であることがわかります。さらに、図1「食券購入時の主な要件」の〔セットメニューの値引きのルール〕に、「セットメニューに適用できるメイン商品,サイドメニュー1,サイドメニュー2を,それぞれ1品以上選んだ場合、50円値引きする」とあります。イの場合は、メイン+サイドメニュー1を注文した状態であり、サイドメニュー2が未注文なので値引きの対象にはなりません。
遷移先の状態番号が3、値引き額が0円ですので、イに入る値は「3:0」となります。
∴イ=3:0
設問2
図4中のウ~キに入れる適切な字句を答えよ。
解答入力欄
- ウ:
- エ:
- オ:
- カ:
- キ:
解答例・解答の要点
- ウ:order[i].A
- エ:order[i].N*100+order[i].S*10
- オ:status_table[status] [event_index].discount
- カ:status_table[status] [event_index].status
- キ:acceptedがtrueに等しい
解説
〔ウについて〕
変数 amount は注文金額を保持する変数です。注文金額 amount にウを加算しているので、この行は、図3「注文の状態を判定する手順」の「(2)注文された商品を先頭から順に一つ参照し、商品の金額を注文金額に加算する」に対応する処理とわかります。つまりウには、商品の価格を表す式が入ります。
表3「判定プログラム中で利用する主な変数、定数及び関数」を読むと、商品の情報は order[] に格納されており、「i番目の注文については,order[i].N,order[i].S,order[i].O,order[i].Aで,それぞれ表1の商品のN,S,O及び商品の金額を参照できる」とあります。i番目に注文された商品の価格を表す式は「order[i].A」です。
∴ウ=order[i].A
〔エについて〕
プログラムの7行目は、図3「注文の状態を判定する手順」の「(3)注文された商品のイベントコードを算出する」に対応する処理です。
また、〔注文の状態の判定手順〕には、「表1のN,S,Oを左から順に並べた3桁の数をイベントコードと呼び,…」とあります。単純に考えれば、1桁の数字を文字列として繋ぎ合わせて
「+order[i].O」の部分はプログラム内に記述済みですので、エには前半部分である
∴エ=order[i].N*100+order[i].S*10
〔オについて〕
プログラムの9行目は、図3「注文の状態を判定する手順」の「(4)状態遷移の際の値引きの金額を取得し、値引き金額に加算する」に対応する処理です。
表3の定義より、status_table[stat][ev].discount で遷移前の状態と与えられたイベントコードに対応する値引きの金額を取得できることがわかります。配列の添字の stat は遷移前の状態番号、ev はイベントコードです。現在の状態番号は変数 status に、イベントコードは前行の get_event_index により変数 event_code に格納済なので、status_table[status][event_index].discount を参照することで、加算すべき値引き額を取得できます。
∴オ=status_table[status][event_index].discount
〔カについて〕
プログラムの10行目は、図3「注文の状態を判定する手順」の「(5)状態遷移表を参照し、現在の状態番号とイベントコードから次の状態番号を取得して、状態番号を更新する」に対応する処理です。
表3の定義より、status_table[stat][ev].status で次の状態番号を取得できることがわかります。先程と同じく、現在の状態番号は変数 status に、イベントコードは変数 event_code に格納済なので、status_table[status][event_index].status を参照することで、遷移先の状態番号を取得できます。この値で status を更新することになります。
∴カ=status_table[status][event_index].status
〔キについて〕
プログラムの15行目は、status_table[status][ACCEPT_INDEX].accept で発券可の列の値を取得し、変数 accepted に代入しています。定数 ACCEPT_INDEX は、配列 status_table の発券可の列のインデックス番号です。status の値は10行目で遷移先の状態番号に更新されているため、次の遷移先が発券可能な状態であれば true が、そうでなければ false が変数 accepted に格納されることになります。
プログラムではキが真であれば、発券ボタンを押せるようにし、そうでなければ発券ボタンを押せないようになっています。発券ボタンを押せるようにするのは発券可(すなわち、accepted==true)のときですから、キには「accepted が true と等しい」という条件式が入ります。
∴キ=acceptedがtrueに等しい
変数 amount は注文金額を保持する変数です。注文金額 amount にウを加算しているので、この行は、図3「注文の状態を判定する手順」の「(2)注文された商品を先頭から順に一つ参照し、商品の金額を注文金額に加算する」に対応する処理とわかります。つまりウには、商品の価格を表す式が入ります。
表3「判定プログラム中で利用する主な変数、定数及び関数」を読むと、商品の情報は order[] に格納されており、「i番目の注文については,order[i].N,order[i].S,order[i].O,order[i].Aで,それぞれ表1の商品のN,S,O及び商品の金額を参照できる」とあります。i番目に注文された商品の価格を表す式は「order[i].A」です。
∴ウ=order[i].A
〔エについて〕
プログラムの7行目は、図3「注文の状態を判定する手順」の「(3)注文された商品のイベントコードを算出する」に対応する処理です。
また、〔注文の状態の判定手順〕には、「表1のN,S,Oを左から順に並べた3桁の数をイベントコードと呼び,…」とあります。単純に考えれば、1桁の数字を文字列として繋ぎ合わせて
order[i].N+order[i].S
と考えてしまいがちですが、event_code の値は次行の get_event_index に渡されており、表3で関数 get_event_index の引数は整数と定義されているため、event_code は整数値でなければいけません。N、S、Oを左から順に並べると、Nが百の位、Sが十の位、Oが一の位になるため、イベントコードは「N×100+S×10+O」で求めることができます。「+order[i].O」の部分はプログラム内に記述済みですので、エには前半部分である
order[i].N*100+order[i].S*10
が入ります。∴エ=order[i].N*100+order[i].S*10
〔オについて〕
プログラムの9行目は、図3「注文の状態を判定する手順」の「(4)状態遷移の際の値引きの金額を取得し、値引き金額に加算する」に対応する処理です。
表3の定義より、status_table[stat][ev].discount で遷移前の状態と与えられたイベントコードに対応する値引きの金額を取得できることがわかります。配列の添字の stat は遷移前の状態番号、ev はイベントコードです。現在の状態番号は変数 status に、イベントコードは前行の get_event_index により変数 event_code に格納済なので、status_table[status][event_index].discount を参照することで、加算すべき値引き額を取得できます。
∴オ=status_table[status][event_index].discount
〔カについて〕
プログラムの10行目は、図3「注文の状態を判定する手順」の「(5)状態遷移表を参照し、現在の状態番号とイベントコードから次の状態番号を取得して、状態番号を更新する」に対応する処理です。
表3の定義より、status_table[stat][ev].status で次の状態番号を取得できることがわかります。先程と同じく、現在の状態番号は変数 status に、イベントコードは変数 event_code に格納済なので、status_table[status][event_index].status を参照することで、遷移先の状態番号を取得できます。この値で status を更新することになります。
∴カ=status_table[status][event_index].status
〔キについて〕
プログラムの15行目は、status_table[status][ACCEPT_INDEX].accept で発券可の列の値を取得し、変数 accepted に代入しています。定数 ACCEPT_INDEX は、配列 status_table の発券可の列のインデックス番号です。status の値は10行目で遷移先の状態番号に更新されているため、次の遷移先が発券可能な状態であれば true が、そうでなければ false が変数 accepted に格納されることになります。
プログラムではキが真であれば、発券ボタンを押せるようにし、そうでなければ発券ボタンを押せないようになっています。発券ボタンを押せるようにするのは発券可(すなわち、accepted==true)のときですから、キには「accepted が true と等しい」という条件式が入ります。
∴キ=acceptedがtrueに等しい
設問3
図4の判定プログラムについて,プログラムに変更を加えず,表1,2の内容を変更するだけで対応できる要件を解答群の中から二つ選び,記号で答えよ。ここで,表1,2の内容について,業務運用中の変更は行わないものとする。
解答群
- 12:00~14:00の間はランチタイムとし,鮭定食を一時的に提供しないようにする。
- オプションの指定が必須なメイン商品について,並,大盛り,特盛りのオプションの指定の後に,ご飯にかけるつゆの量について,普通,多め,少なめの指定ができるようにする。
- サイドメニュー1とサイドメニュー2の商品で,セットメニューに組み込める商品を複数個ずつ注文したときに,値引きも複数回適用する。
- メイン商品にカレーを追加する。カレーには並,大盛りを指定できるが,特盛りは指定できない。
解答入力欄
解答例・解答の要点
- イ
- エ
解説
- 時間帯によって処理の内容を変更する必要があるため、プログラムの変更が必要であり、表1、2の内容を変更するだけでは実現できません。
- 実現可能です。
まず表1のオプションにつゆの量として、普通、多め、少なめをN=4、S=0、O=1として追加します。次に、新しく状態6を作成し、状態1から状態6を経て状態2に移るように表2を変更します。
これにより、オプション指定が必須なメイン商品の状態遷移を「1→6→2」とすることができ、2つのオプション項目を必須選択にできます。 - 「1回の注文でセットメニューに組み込めるサイドメニュー1+サイドメニュー2のセットが複数あった場合は、50円×セット数の値引きを行う」と解釈します。例えば、牛丼+野菜サラダ+漬物+みそ汁+スープの注文があった場合を考えます。
問題文の条件の場合は、図1の〔セットメニューの値引きのルール〕に「値引きは食券購入ごとに1回だけ適用される」とあるため、値引き金額は50円になります。それに対して、「ウ」の変更を加えた場合は、100円の値引きになります。
これを実現するには、セット対象のサイドメニューが注文された数をプログラム中で数える必要があるため、表1、2の内容を変更するだけでは実現できません。 - 実現可能です。
まず表1のメインメニューに名称=カレー、N=1、S=1、O=3を追加します。次にオプションに、「カレー(並)」と「カレー(大盛り)」をN=4、S=0、O=3で追加することで実現可能です。