Q社のRさんは,チケット販売システムの開発で使用する関数のプログラミングとテストを実施しようとしている。この関数は,大人と子供のチケットの購入希望枚数を基に,合計金額の計算を行う。大人のチケットは3,000円,子供のチケットは1,000円である。一度に購入できる大人と子供のチケットの最高枚数は,それぞれ20枚までであり,関数はこの購入条件を満たしているかどうかをチェックする。また,合計で20枚以上購入する場合,割引処理を行う。関数の仕様と処理内容は次のとおりである。 〔関数の仕様〕 関数に渡される引数 J:大人のチケットの購入希望枚数,K:子供のチケットの購入希望枚数 (J,Kは0以上の整数) 関数の戻り値 L:合計金額 (Lは整数) 〔処理内容〕 (1) 購入希望枚数を基に,購入条件を満たしているかどうかを判定する。購入条件を満たしていない場合,合計金額に−1を代入する。 (2) 購入条件を満たしている場合,引数を基に次のとおりに合計金額の計算を行う。 合計金額 = 大人のチケットの購入希望枚数×3,000+子供のチケットの購入希望枚数×1,000 (3) チケットを合計で20枚以上購入した場合は,合計金額から1割を割り引く。 1日券,2日券といった日数の異なる種類のチケットの金額計算に対応できるように,〔処理内容〕の(2)及び関数の仕様を変更し,引数にチケットの日数を表すMを追加した。Mには使用できる日数が入る。種類別のチケット金額を設定する配列をTP(M, N)とする。Nは大人の場合は1,子供の場合は2とする。配列の値は次のとおりである。引数がJ=10, K=20, M=2のときの合計金額は何円か。 なお,関数は,引数に応じてこの配列を参照し,チケット金額を決定する。 〔配列の値〕 TP(1, 1) = 3,000, TP(1, 2) = 1,000, TP(2, 1) = 4,000, TP(2, 2) = 1,500, TP(3, 1) = 5,000, TP(3, 2) = 2,000
平成23年度 特別試験 ITパスポート試験 問96
この問題の解説と、これまでの解答の記録です。
問 96
※ この問題は、解説作成時の検算で公表解答を確認しきれませんでした。判定は IPA 公表の解答どおりです。
不正解ア
M=2(2日券)を無視して1日券の料金 TP(1, 1)=3,000円 と TP(1, 2)=1,000円 で計算し、そこに1割引を掛けた値。(3,000×10 + 1,000×20)×0.9 = 50,000×0.9 = 45,000円 となる。(3) の割引処理は正しく適用できているが、引数 M の意味、すなわち M は使用できる日数であり配列 TP(M, N) の第1引数(どの行を引くか)を決めるという点を読み落とし、TP(1, N) の行を引いてしまっている。M=2 なので使うのは TP(2, N) の行である。
不正解イ
配列の行選択と割引の両方を落とした値。1日券の料金で 3,000×10 + 1,000×20 = 50,000円 と計算し、そのまま答えにしたものである。M=2 が指定されている以上 TP(2, 1)=4,000円 と TP(2, 2)=1,500円 を使わなければならず、さらに J+K = 30枚 なので (3) の1割引も適用されなければならない。二重に処理が抜けているため誤り。
- ウ
正解 正解は ウ の 63,000円。この問題は中問B(問93〜96)の共通前提の上に立つ。共通の〔処理内容〕は、(1) 購入条件(大人・子供とも0〜20枚)を満たさなければ合計金額に −1 を代入する、(2) 満たしていれば 合計金額 = 大人の枚数×大人料金 + 子供の枚数×子供料金 を計算する、(3) チケットを合計で20枚以上購入した場合は合計金額から1割を割り引く、という3段構えである。本問が変更したのは (2) だけで、料金を固定値(大人3,000円・子供1,000円)ではなく配列 TP(M, N) から引く形にした。つまり (1) の購入条件チェックと (3) の1割引はそのまま生きている。ここに J=10(大人の枚数)、K=20(子供の枚数)、M=2(2日券)を当てはめる。まず (1): J=10 も K=20 も 0以上20以下なので購入条件を満たし、−1 にはならない。次に (2): 参照するのは M=2 の行、すなわち TP(2, 1)=4,000円(2日券・大人)と TP(2, 2)=1,500円(2日券・子供)。割引前の合計金額は 10×4,000 + 20×1,500 = 40,000 + 30,000 = 70,000円。最後に (3): 購入枚数の合計は J+K = 10+20 = 30枚で20枚以上だから1割引が適用され、70,000×0.9 = 63,000円 となる。配列参照で M=2 の行を選ぶことと、変更されていない1割引処理を最後に必ず通すこと、この2段階を両方こなせるかがポイントである。
不正解エ
配列の参照は正しく、M=2 の行から TP(2, 1)=4,000円、TP(2, 2)=1,500円 を引けている。しかし 10×4,000 + 20×1,500 = 70,000円 は割引前の金額であり、〔処理内容〕(3) の1割引を適用し忘れている。本問で変更されたのは (2) の金額計算だけで (3) の割引処理は生きたままなので、J+K = 30枚(20枚以上)である以上、1割引は必ず掛かる。70,000×0.9 = 63,000円 が答えであり、最も引っ掛かりやすい誤答である。
- 仕様変更型の設問では「どこを変えて、どこを変えていないか」を切り分けるのが鉄則。本問で変わったのは〔処理内容〕(2) の金額計算(固定料金→配列 TP の参照)だけであり、(1) の購入条件チェックと (3) の 合計20枚以上で1割引 はそのまま生きている。変更されていない処理を落とすと計算が合わなくなる。
- 二次元配列 TP(M, N) の参照は、第1引数 M がチケットの日数(行)、第2引数 N が大人=1・子供=2(列)という対応を正確に読み取る。M=2 なら TP(2, 1) と TP(2, 2) の組だけを使い、TP(1, *) や TP(3, *) は引かない。引数の順序と意味を取り違えると全く別の料金を拾ってしまう。