見出し画像

少ない枚数でお金をやり取りする方法

 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

いいなと思ったら応援しよう!