基本情報技術者 2013年 秋期 午後 問10
次のCOBOLプログラムの説明及びプログラムを読んで、設問1,2に答えよ。
〔プログラムの説明〕
X社では、自社の事業所内にある4面のテニスコートについて、従業員が予約やキャンセル、空き状況の確認ができるシステムを開発することになった。このプログラムは、テニスコートの予約を受け付けるサブプログラムであり、利用希望者からの予約情報をパラメタで受け取り、予約管理ファイルで管理している予約状況と照らし合わせて、予約結果をパラメタで呼出し元に返却する。
(1) プログラムには二つのパラメタがある。各パラメタの様式は、図1のとおりである。

① 予約番号には、予約希望に対して一意に割り振られる000001~999999の番号が格納されている。
② 希望面数には、希望するコートの面数が格納されている。
③ 希望日には、年、月、日が、それぞれ4桁、2桁、2桁の西暦で格納されている。
④ 希望時刻には、希望する利用開始時刻の“時”が、24時間表記で格納されている。利用可能な時間帯は8時から17時までであり、1時間単位で予約できる。
⑤ 希望時間には、希望する利用時間数が格納されている。
⑥ 結果には、希望どおりに予約できた場合は0を、予約できなかった場合は9を設定する。
⑦ 予約コートには、予約できたコートのコート番号を設定する。例えば3番コートを予約できた場合は3000を設定し、1番コートと2番コートを予約できた場合は1200を設定する。予約ができなかった場合は、0000を設定する。
⑧ コートは1番~4番の順に検索し、番号の小さいコートから確保する。
⑨ 予約情報の各項目の値は呼出し側プログラムで検査するので、①~⑤で示した範囲以外の値が設定されることはない。
(2) 予約管理ファイルは、日付を主キーとする図2に示すレコード様式の索引ファイルで、予約状況を管理するために使用する。

① 日付には、年、月、日が、それぞれ4桁、2桁、2桁の西暦で格納される。
② 予約状況の各要素には、予約済の場合は予約番号が、予約が入ってない場合は0が格納される。
③ 予約が入っていない日付をキーとするレコードは存在しない。

設問1:
問題文を見る プログラム中のに入れる正しい答えを、解答群の中から選べ。
a〜cに関する解答群
ア:COMPUTE TIME-START = PRM-TIME - 7
イ:MOVE BKUP-AREA TO RSV-COURT(COURT-CNT)
ウ:MOVE COURT-CNT TO KEEP-COURT
エ:MOVE PRM-TIME TO TIME-CNT
オ:MOVE RSV-RNO(COURT-CNT TIME-CNT) TO PRM-RNO
カ:MOVE TIME-CNT TO COURT-CNT
キ:SET CHK-NG TO TRUE
ク:SET CHK-OK TO TRUE
dに関する解答群
ア:CHK-NG
イ:CHK-OK
ウ:KEEP-COURT NOT = ZERO
エ:PRM-NUM NOT = KEEP-COURT
オ:PRM-NUM = KEEP-COURT
模範解答
a:ア、b:ク、c:イ、d:エ
解説
解答の導き方
この問題では、予約時刻を予約管理ファイルの位置に変換し、希望した面数のコートを確保できるかを調べます。COBOL(Common Business-Oriented Language:事務処理向けのプログラミング言語)の配列は、同じ形式の値を複数並べた領域です。配列の位置を表す番号を添字といいます。
-
予約時刻を配列の位置に変換します。図2の予約状況には、各コートについて「8時台」から「16時台」までの9個の時間枠があります。一方、PRM-TIMEには実際の時刻が入っています。そのため、実際の時刻を配列の添字に変換する必要があります。a に入る「COMPUTE TIME-START = PRM-TIME - 7」なら、8時は添字1、9時は添字2となり、16時は添字9となります。つまり、予約状況の時間枠に対応する添字を求めています。さらに、TIME-ENDは「TIME-START + PRM-HOURS」で計算されます。例えば、10時から2時間予約する場合はTIME-STARTが3、TIME-ENDが5です。ループはTIME-CNTが5になるまで添字3、4を調べるので、10時台と11時台が予約対象になります。終了時刻に当たる添字は含まれません。
-
コートごとに、予約できるかを調べます。図2では、RSV-COURTは4個、各RSV-COURTの中にRSV-RNOが9個あります。つまり、コート番号と時間枠の位置を使って、予約状況を調べます。まず、あるコートの時間枠を調べ始める前に、判定を「予約可能」に戻す必要があります。CHK-OKは予約可能、CHK-NGは予約不可を表す条件名(値に読みやすい名前を付けたもの)です。したがって、b には「SET CHK-OK TO TRUE」が入ります。その後、希望する時間枠を順に確認します。RSV-RNO(COURT-CNT TIME-CNT)が0なら空いているので、予約番号を設定します。0以外ならすでに予約済みなので、CHK-NGになります。
-
予約済みの枠が見つかった場合は、そのコートへの仮の変更を戻します。あるコートの時間枠を順に調べると、途中までは空いていて、後から予約済みの枠に出会うことがあります。その場合、見つかる前に空き枠へ設定した予約番号を残すと、予約できないコートに一部だけ予約が入った状態になってしまいます。そこで、調べる前に「MOVE RSV-COURT(COURT-CNT) TO BKUP-AREA」で、そのコートの時間枠全体を退避しています。1コート分は9枠、それぞれ6桁なので、合計54文字です。予約済みの枠が見つかったときは、c に「MOVE BKUP-AREA TO RSV-COURT(COURT-CNT)」を入れて、調べる前の状態に戻します。
-
希望面数を確保できたかを判定します。確保したコートの数はKEEP-COURTに記録されます。コート番号の小さい順に調べ、空いているコートが見つかると、確保数を1増やして、予約結果にコート番号を設定します。最後に比べるのは、希望面数PRM-NUMと、実際に確保できた数KEEP-COURTです。両者が異なる場合は希望を満たせていないので、d は「PRM-NUM NOT = KEEP-COURT」です。このとき予約不可を示す9を設定し、予約コートを初期化します。
誤りやすいポイント
- 時刻そのものと配列の添字を混同しないことです。 8時を表す値は8ですが、予約状況の8時台は配列の添字1です。
- CHK-OKはコートごとに設定します。 前のコートを調べたときの判定を引き継がないよう、各コートの確認前に予約可能な状態へ戻します。
- 予約済みの枠が見つかったら、該当する時間枠だけでなく、そのコート全体を元に戻します。 それまでに空き枠へ設定した予約番号も取り消す必要があるためです。
- 最終的な判定は、空いている時間枠があったかどうかではありません。 希望面数と確保したコート数が一致するかどうかで判断します。
FAQ
Q: TIME-ENDに当たる時間枠を調べないのはなぜですか?
A: 予約時間は開始時刻から利用時間数分までです。10時から2時間なら、利用するのは10時台と11時台で、終了時刻の12時は含まれません。
A: 予約時間は開始時刻から利用時間数分までです。10時から2時間なら、利用するのは10時台と11時台で、終了時刻の12時は含まれません。
Q: CHK-NGだけで予約全体の成功・失敗を判定できませんか?
A: CHK-NGは、調べている1面のコートに希望時間の空きがなかったことを示す値です。希望した面数を確保できたかどうかは、PRM-NUMとKEEP-COURTを比べて判断します。
A: CHK-NGは、調べている1面のコートに希望時間の空きがなかったことを示す値です。希望した面数を確保できたかどうかは、PRM-NUMとKEEP-COURTを比べて判断します。
Q: BKUP-AREAには何を保存していますか?
A: 調べているコートの9個の時間枠に入った予約番号を保存しています。途中でそのコートの予約を取り消す必要が生じたとき、元の状態へ戻すために使います。
A: 調べているコートの9個の時間枠に入った予約番号を保存しています。途中でそのコートの予約を取り消す必要が生じたとき、元の状態へ戻すために使います。
関連キーワード: 配列、添字、索引ファイル、条件名、ロールバック
設問2:
問題文を見る システムの運用を開始したところ、“隣り合わせのコートを希望する機能が欲しい”との要望が挙がった。コートは図3に示すとおりに配置されていて、2面を予約した利用者にフェンスを挟んだコート、例えば1番コートと3番コートが割り当てられたことがあったためである。
パラメタにデータ項目PRM-NEXTを追加し、1が設定されている場合、確保できたコートがフェンスを挟んでいたら予約はせずに、結果に4を設定して返却するようにプログラムを変更する。ただし、3面以上の予約だった場合は、フェンスを挟んでいても予約する。表1中のに入れる正しい答えを、解答群の中から選べ。


e〜gに関する解答群
ア:((COURT-NO(1) = 1 OR 2) AND (COURT-NO(2) = 3 OR 4))
イ:(COURT-CNT = 3 OR 4)
ウ:(COURT-NO(1) = 1 OR 3)
エ:NEXT-OFF
オ:NEXT-ON
カ:PRM-NUM = 2
キ:RSV-OK
模範解答
e:ア、f:オ、g:カ(順不同)
解説
解答の導き方
この問題では、予約したコートがフェンスを挟んだ配置になっている場合に、どの条件で予約結果を「4」にするかを考えます。
-
どのコートがフェンスのどちら側か確認します。図3では、1番コートと2番コートがフェンスの左側、3番コートと4番コートが右側にあります。したがって、2面を予約したとき、1面目が1番コートまたは2番コートで、2面目が3番コートまたは4番コートなら、2面はフェンスを挟んでいます。プログラムはコート番号の小さい順に空きを探し、確保したコート番号をCOURT-NOに順番に格納します。そのため、2面を確保した場合、COURT-NO(1)が先に確保したコート、COURT-NO(2)が次に確保したコートです。フェンスを挟んでいるかを調べる条件は、次の形になります。((COURT-NO(1) = 1 OR 2) AND (COURT-NO(2) = 3 OR 4))これは解答群のアです。COURT-NO(1)とCOURT-NO(2)の両方が、フェンスの左右に分かれていることを確認しています。
-
この判定を、2面の予約だけに適用します。問題文には、「3面以上の予約だった場合は、フェンスを挟んでいても予約する」とあります。つまり、フェンスを挟むことを理由に予約を断るのは、希望面数が2面の場合だけです。希望面数はPRM-NUMに入るので、条件はPRM-NUM = 2です。これは解答群のカです。
-
利用者が隣り合わせを希望した場合だけ判定します。追加されたPRM-NEXTは、1が設定されているときに隣り合わせを希望する項目です。PRM-NEXTが1であることを表す条件名はNEXT-ONです。したがって、解答群から選ぶのはオです。NEXT-OFFは、隣り合わせを希望していない場合を表すため、条件に合いません。
-
3つの条件をすべて満たしたときに、予約結果を変更します。変更箇所は、元の予約処理で予約できなかった場合の処理の後にあるELSE側です。つまり、基本の予約処理では予約できた場合に、追加条件を調べます。追加条件は、「隣り合わせを希望している」「希望面数が2面」「確保した2面がフェンスを挟んでいる」の3つです。すべて満たした場合にRSV-NOTEを設定し、RET-COURTを初期化します。RSV-NOTEには値4が定義されています。RET-COURTの初期化によって、返却するコート番号もすべて0になります。予約ができたかどうかを表す結果を4にし、確保したコート番号を返さない処理です。
誤りやすいポイント
-
隣り合わせの条件を、単にコート番号が連番かどうかで考えないことです。
問題で判断するのは番号の連続ではなく、フェンスの左右に分かれているかどうかです。図3では、1番コートと2番コートは左側、3番コートと4番コートは右側です。 -
COURT-CNTとCOURT-NOを混同しないことです。
COURT-CNTは空きコートを調べるための番号です。一方、COURT-NOには実際に確保したコート番号が入ります。フェンスを挟んだかどうかは、確保結果を記録するCOURT-NOで判定します。 -
PRM-NEXTが設定されているだけで、すべての面数を断るわけではありません。
問題文では、3面以上ならフェンスを挟んでいても予約するとしています。そのため、PRM-NUM = 2も条件に加える必要があります。 -
NEXT-OFFではなくNEXT-ONを選ぶことです。
フェンスを挟む予約を断る対象は、隣り合わせを希望した利用者です。希望していない利用者にも同じ判定を行うわけではありません。
FAQ
Q: COURT-NO(1)とCOURT-NO(2)を調べるのはなぜですか?
A: 予約結果のコート番号は、確保した順にCOURT-NOへ格納されるからです。2面予約なら、1面目と2面目の番号から左右の配置を判定できます。
A: 予約結果のコート番号は、確保した順にCOURT-NOへ格納されるからです。2面予約なら、1面目と2面目の番号から左右の配置を判定できます。
Q: 予約面数が3面以上なら、フェンスを挟むかどうかは調べなくてよいのですか?
A: はい。問題文で、3面以上の場合はフェンスを挟んでいても予約すると定めています。そのため、フェンスを挟んでいるかどうかの判定を行う条件にPRM-NUM = 2を加えます。
A: はい。問題文で、3面以上の場合はフェンスを挟んでいても予約すると定めています。そのため、フェンスを挟んでいるかどうかの判定を行う条件にPRM-NUM = 2を加えます。
Q: RSV-OKを条件に選ばないのはなぜですか?
A: 追加処理は、元の予約処理で予約できた場合に進むELSE側に置かれています。そこでさらに必要なのは、隣り合わせの希望、2面予約、フェンスを挟む配置の3点です。
A: 追加処理は、元の予約処理で予約できた場合に進むELSE側に置かれています。そこでさらに必要なのは、隣り合わせの希望、2面予約、フェンスを挟む配置の3点です。
関連キーワード: COBOL、配列、条件分岐、添字、予約管理ファイル



