---
# System prepended metadata

title: Untitled

---

## 問題

商品名と支払い金額を入力すると、お釣りの「小銭の枚数」を返す関数またはメソッドを実装せよ。商品名と価格は以下の通り。

 * お茶: 120円
 * コーラ: 150円
 * エナジードリンク: 280円

入力される通貨は日本円で、最大1000円までとする。
また、有効な貨幣は「1000円」「500円」「100円」「50円」「10円」とする。

たとえば、「1000円でお茶を購入」すると、返却すべき金額は880円だが、釣銭は「500円×1, 100円×3, 50円×1, 10円×3」となる。返り値は、任意の形式のクラス、連想配列、オブジェクト、構造体、リストなどで表現してよい。

PHPの擬似コードで書くと以下のようになる。

```php
function calcChange(string $item, int $paid_money): array {
    // ...
}

$expected = [500 => 1, 100 => 3, 50 => 1, 10 => 3];
assert($expected === calcChange("お茶", 1000));
```

---

## 回答

```python

item_list: dict = { 'お茶': 120, 'コーラ': 150, 'エナジードリンク': 280 }
money_list: list = [ 1000, 500, 100, 50, 10] ## descending order

def calc_change(item_name: str, money: int) -> dict:

    ## item_name validation section  (必要に応じて関数化して切り出す)
    if item_name not in item_list.keys():
        print("item_name is not found", file=sys.stderr)
        exit(1)        
    ## end: item_name validation section

    ## money validation section (必要に応じて関数化して切り出す)
    if money % 10 != 0:
    # if money % money_list[-1] != 0:
    # ※1: もし24円硬貨等が投入された場合には, 例えば最大公約数を用いて、取り得る最小の貨幣の単位を算出する必要がある
        print("not valid money", file=sys.stderr)
        exit(1)
    ## end: money validation section

        
    otsuri: int = money - item_list[item_name] #220
    
    # otrsuri validation section
    if otsuri < 0:
        print("moneyが足りません", file=sys.stderr)
        exit(1)
    # end: otrsuri validation section
    
    result: dict = {}
    ## ※1が成立すればここのロジックも怪しくなる
    ## money validation をここで行っても良いのでは? (どっちでも良い)
    for value in money_list:
        count = otsuri // value
        # if count > 0:
        dict[value] = count
        otsuri %= value
    assert(otrsuri == 0) # 必要?

    return result
    {
      100: 2, 10: 2
    }[500]
```