2019-05-09

所持する硬貨を最低限にする支払いアルゴリズム

 スーパー飲食店会計時に、所持する硬貨の枚数が最低限となるように私は支払いをしている。それは、所持する硬貨の枚数が15枚を超えないことも意味する。

1円玉4枚
5円玉1枚
10円玉4枚
50円玉1枚
100円玉4枚
500円玉1枚
合計15枚

※例えば、請求額が1円かつ硬貨を1枚も所持していない場合千円札などの紙幣で支払うと、所持硬貨上記の通り最大の15枚となる。

 私の支払い方法アルゴリズム表現してみた。アルゴリズムという言葉を見ると、プログラミングや高度な数学知識必要と思うかもしれないがそんなことはない。アルゴリズムというのは目的を達成するための計算手順を示したものであり、料理で例えるならレシピに相当する物であるレシピに従い料理を作ることができるなら、アルゴリズムに従い計算をすることもできるだろう。

 以下の支払いアルゴリズム必要数学能力は、1桁同士の足し算・足し算による繰上がり処理・数値比較が主である。2桁以上の足し算引き算を暗算する能力不要であるプログラミング言語で使用されるような演算記号は極力使わないようにしたので、アルゴリズムを知らない人にこそ読んでほしい。

アルゴリズム(下の実例と併せて読んでください)

(1) 初期値設定

請求額】 ← 請求額を設定する

【支払い桁】 ← 1 /*硬貨支払いは1桁目から3桁目に対応するので、1~3の値をとる*/

【支払い総額】 ← 0 /*硬貨を支払うたびに加算する。実際には、置いた硬貨を数えるだけ*/

請求額で見る数】 ← 0 /*下の桁から1桁ずつ見る。繰上がりもあるので、0~10の値をとる*/

【繰上がりフラグ】 ← 0 /*0:偽 1:真 とする*/

(2) 繰上がり処理と請求額で見る数の設定

請求額で見る数】 ← 【請求額】の【支払い桁】桁目の値+【繰上がりフラグ

【繰上がりフラグ】 ← 0

(3) その桁が0なら支払わない

請求額で見る数】=0 の場合

 (8)へ進む

(4) その桁が9かつ下の桁からの繰上りがあるなら、支払いは1桁上に繰上げ

請求額で見る数】=10 の場合

 【繰上がりフラグ】 ← 1

 (8)へ進む

(5) 1円玉 or 10円玉 or 100円玉の支払い

請求額で見る数】×10^(【支払い桁】-1) に必要10^(【支払い桁】-1) 円玉を支払えるなら支払う。

【支払い総額】に支払った金額を加える

/*10^0=1 10^1=10 10^2=100 である*/

(6) 5円玉 or 50円玉 or 500円玉の支払い

請求額で見る数】×10^(【支払い桁】-1) に必要5×10^(【支払い桁】-1)円玉を支払えるなら支払う。

【支払い総額】に支払った金額を加える

/*5×10^0=5 5×10^1=50 5×10^2=500 である*/

(7) 請求額で見る数の支払いができなければ、支払いは1桁上に繰上げ

 【請求額で見る数】 > 【支払い総額】の【支払い桁】桁目の値 の場合

 【繰上がりフラグ】 ← 1

(8) 硬貨支払いが完了するまで、上の桁へと繰り返す(3桁目まで)

 【請求額】 > 【支払い総額】 かつ 【支払い桁】 < 3 の場合

  【支払い桁】に1を加える

  (2)へ戻る

(9) 終了処理

 硬貨支払いの終了

  

実例(上のアルゴリズムと併せて読んでください)

請求額が876円の場合

条件1 1円玉10円玉100円玉をそれぞれ4枚ずつ所持している

条件2 5円玉50円玉500円玉を所持していない

(1)請求額に876を設定。

(2)請求額で見る数は1桁目の6である

(3)(4)該当せず。

(5)6に必要1円玉を1枚支払い、支払い総額は1円となる。

(6)6に必要5円玉を支払いたいが、所持してないので支払わない。

(7)1桁目に6円支払うべきところを1円しか支払っていないので、支払いは1桁上に繰上げ。

(8)支払い総額が請求額を満たしていないので、次は2桁目をみる → (2) へもどる。

(2)請求額で見る数は2桁目の7に繰上がりの1を加えて8である

(3)(4)該当せず。

(5)80に必要10円玉を3枚支払い、支払い総額は31円となる。

(6)80に必要50円玉を支払いたいが、所持してないので支払わない。

(7)2桁目に80円支払うべきところを30円しか支払っていないので、支払いは1桁上に繰上げ。

(8)支払い総額が請求額を満たしていないので、次は3桁目をみる → (2) へもどる。

(2)請求額で見る数は3桁目の8に繰上がりの1を加えて9である

(3)(4)該当せず。

(5)900に必要100円玉を4枚支払い、支払い総額は431円となる。

(6)900に必要500円玉を支払いたいが、所持してないので支払わない。

(7)3桁目に900円支払うべきところを400円しか支払っていないので、支払いは1桁上に繰上げ。

(8)支払い総額が請求額を満たしていないが、3桁目の支払いを終了したので該当せず。

(9)硬貨の支払いを終了する。

以上、硬貨の支払いは431円となる。ちなみに、876円の請求に1431円を支払うとお釣り555である。「876-1431=-555」の計算をせずとも支払いを最適化することができた。

支払いアルゴリズム解説

 人間機械と違って、日常動作は早く正確だが計算は遅くて間違いを起こすという特徴を持つ。どんなに計算が得意な人でもコンピュータより早く正確に計算をすることは不可能である例外ジョン・フォン・ノイマンくらいであろう)。よって、人間の支払いにおいては、硬貨を支払う動作よりも計算自体ボトルネックエラーの原因となると考えた。この問題解決のために、1桁単位毎に硬貨を支払うようにした。

 上記の支払いアルゴリズムに従えば、レジ店員ミスや釣銭不足の場合を除いて、硬貨の所持数を最低限にすることができる。しかし、緊急時に備えて硬貨を余分に所持しておきたいと考える人もいるだろう。その場合でも、支払いアルゴリズム採用しないのはもったいない。なぜなら、アルゴリズムをほんの少し修正するだけでよいからだ。例えば100円玉を常に3枚以上持ち歩きたいなら、アルゴリズム(5)に「支払いにより100円玉が2枚以下になるなら支払わない」という条件を追加すればよい。所持する100円玉は3~7枚の間を維持できる。他にも、各々の好みに合わせてアルゴリズム修正して活用してほしい。

他にも、支払いアルゴリズム導入のメリットはある
  • さな単位から支払うので、店員に支払いを中断されることがない。先に紙幣を支払うと、せっかちな店員硬貨の支払いを待たずに会計してしまう。
  • 財布と小銭入れの両方を使い分けている人は、持ち替えの手間を少なくできる。店員がお釣り紙幣から先に渡す場合(先に硬貨を渡すことはまずないだろう)、手持ちは次のようになる。
  1. 小銭入れ【硬貨支払い】
  2. 財布【紙幣支払い → 紙幣受け取り】
  3. 小銭入れ【硬貨受け取り】

先に紙幣を支払うと、手持ち回数が1手増えてしまう。

  1. 財布【紙幣支払い】
  2. 小銭入れ【硬貨支払い】
  3. 財布【紙幣受け取り】
  4. 小銭入れ【硬貨受け取り】

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん