少ない枚数でお金をやり取りする方法
2025年度から始まる新しい大学入学共通テストで新たに情報1が出題されます。大学入試センターが公表した試作問題(2021年3月)を、このたび初めてやってみました。そのうちの1問を、手直しして紹介しましょう。仮タイトル「なるべく少ない枚数でお金をやり取りする方法」です。
… 次の生徒(S)と先生(T)の会話文を読み,…(中略)…
S:この前,お客さんが460円の商品を買うのに,510円を払って,釣り銭を50円受け取っていたのを見て,授業で勉強したプログラミングで,そんな「上手な払い方」を計算するプログラムを作ってみたいと思いました。
T:いいですね。まず,「上手な払い方」とは何かを考える必要がありますね。 …
プログラミングの問題ですが、問題文の出だしの自然な問いかけがとても良い。でも、この後うんざりするような長くて考えにくい問題文が続きます。
どうしてそうなるかというと、プログラム言語が特定されておらず、いろんな言語に対応するような作りになっているからです。逆に言うと、特定のプログラム言語が多少とも使えるなら、その言語に対応した問題文であれば、だいぶやりやすいでしょう。
では、ここでプログラム言語 Python で問題を作り直してみましょう。元の問題はB5用紙6ページに渡る長文ですが、なるべくコンパクトに書いてみます。
S:まず「金額を入力して、その金額ちょうどになる硬貨枚数の最小値を求めるプログラム」を作ってみます。例えば46円は「10円玉が4枚,5円玉が1 枚,1円玉が1枚」の組合せで枚数が最小になるので,その値は6になります。
T:ある額の硬貨が何枚まで使えて,残金がいくらになるかを計算するには,整数値の商を求める演算『 / / 』と余りを求める演算『%』が使えるでしょう。
こんなヒント(逆に読み難くなるのかもしれないが)を織り交ぜながら問題文が進んで、いったん次のようなプログラム(最終的な完成品ではなく、いわばパーツと言えるもの)が出来上がります。
ここでは100円以下の商品を買うものとしています。使うコインは 1 円,5 円, 10 円, 50 円, 100 円の5種類です。
price = int(input()) # 整数値を入力して、変数priceに代入
count = 0 # コイン枚数の初期値を0とする
money = price # 変数priceと同じ値を変数moneyに代入する
coin = [100,50,10,5,1] # 5種類のコインを配列形式で定義
for i in range (5) : # 金種の大きいものから小さいものへ順に処理する
count = count + _____ア_____ # コイン枚数を増やす
money = _____イ_____ # 残りの金額を求める
print (count) # コイン枚数を表示する[ ア ],[ イ ]の解答群
(0) money // coin[i] (1) money % coin[i]
(2) count // coin[i] (3) count % coin[i]
次に、次のステップに進むための準備として、下のように関数 coins を定義して、プログラムを書き換えました。関数 coins は「変数 money とちょうど同じ金額になるコイン枚数の最小値」を返す関数です。
def coins(money): # ここから関数定義
count = 0 # 関数名は coins、変数は money
coin = [100,50,10,5,1]
for i in range (5) :
count = count + _____ア_____
money = _____イ_____
return ___ウ___ # 返り値が(ウ)
price = int(input()) # ここからプログラム本体
print (coins (price)) # ここで関数 coins を呼び出して、返り値を表示[ ウ ]の解答群
(0) price (1) money (2) count
このとき coins (46) は 値 6 となります。
ところで、同じ46円を支払うのに,51円を支払って釣り銭5円を受け取る払い方では,支払いに2枚,釣り銭に1枚で,合計3枚の硬貨のやり取りになります。
S:これが上手な払い方ですね。
T:そうです。このように,客と店が交換する硬貨の合計が最小となる枚数,すなわち「最小交換硬貨枚数」の計算を考えましょう。例えば,46 円支払うのに,51 円払って 5 円の釣り銭を受け取る払い方をした場合,客と店の間で交換される硬貨枚数の合計は,この関数を使うと,どのように計算できますか?
S: [ _エ_ ]で求められます。ところで、手渡す金額とお釣りの金額は何通りもありますね。どうしたら良いでしょうか?
T:一般に,商品の価格に対して釣り銭を0,1,2,...と変化させて, それぞれの場合に必要な硬貨の枚数の合計を計算して,一番小さな値を最小交換硬貨枚数とすればよいでしょう。
S:なるほど。今回は100 円以下の商品を買うとすると,釣り銭は 99 円まで調べれば十分ですね。
[ エ ]の解答群
(0) coins( 51 ) + coins( 5 ) (1) coins( 46 ) + coins( 5 )
(2) coins( 51 ) − coins( 5 ) (3) coins( 46 ) − coins( 5 )
def coins(money): # ここから関数定義
count = 0 # 関数名は coins、変数は money
coin = [100,50,10,5,1]
for i in range (5) :
count = count + _____ア_____
money = _____イ_____
return ___ウ___
price = int(input()) # ここからプログラム本体
min_coins = 100 # 変数 min_coins の初期値を 100 とした
for back in range(100): # 釣り back を0円から100円まで変えてみる
give = price + back # 価格 price と釣り back の和 give を渡す
maisu = ____オ____ + ____カ____
if ____キ____ < min_coins:
____ク____ = ____キ____
print (min_coins) # 最後に「最小交換硬貨枚数」を表示する[ オ ],[ カ ]の解答群
(0) coins(give) (1) coins(price) (2) coins(back)
(3) give (4) price (5) back
ただし,空欄[ オ ],[ カ ]は解答の順序は問わない。
[ キ ],[ ク ]の解答群
(0) maisu (1) min_coins (2) give (3) back
お疲れ様でした。答えはこちら(↓)です。
〈答〉 ア 0 イ 1
ウ 2 エ 0
オ 0 カ 2 または オ 2 カ 0
キ 0 ク 1
