質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

2789閲覧

C# if文やfor文を使わずにお釣りの硬貨の枚数を計算したい。

knkotaro1220

総合スコア21

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

1クリップ

投稿2021/11/18 01:40

編集2021/11/18 01:58

前提・実現したいこと

自動販売機のお釣り計算の機能を作成しています。

返却ボタンが押された際にメソッドが動く仕様にしています。

ここまで2通り(if文・for文)ほど書いてきたが、
演算子のみの使用でfor文やif文は使用せずに記述できるそうです。
お釣りの硬貨の種類は500円、100円、50円、10円。
各硬貨の上限枚数は99枚。
自動販売機に投入することが可能な金額もそれぞれの硬貨を99枚投下した際の和となっております。

少しひらめきのような問題とのことですが、上記2つの書き方以外に見つかりません。
お教えいただけますと幸いです。

該当のソースコード

***********_Miasuu = 各硬貨の枚数を入れる変数
MAISUUJOUGEN = 99 (硬貨の最大投入枚数)
Tounyukingaku  =投入金額の現在数値
***********KOUKA = 各硬貨の値段

①for文使用 for (Fivehundred_Miasuu = 0; Fivehundred_Miasuu < MAISUUJOUGEN && Tounyukingaku >= FIVEHKOUKA; Fivehundred_Miasuu ++) {Tounyukingaku = Tounyukingaku - FIVEHKOUKA;} for (Onehundred_Miasuu = 0; Onehundred_Miasuu < MAISUUJOUGEN && Tounyukingaku >= ONEHKOUKA; Onehundred_Miasuu++) {Tounyukingaku = Tounyukingaku - ONEHKOUKA; } for (Fifty_Miasuu = 0; Fifty_Miasuu < MAISUUJOUGEN && Tounyukingaku >= FIFTYKOUKA; Fifty_Miasuu ++) {Tounyukingaku = Tounyukingaku - FIFTYKOUKA;} for (Ten_Miasuu = 0; Ten_Miasuu < MAISUUJOUGEN && Tounyukingaku >= TENKOUKA; Ten_Miasuu++) {Tounyukingaku = Tounyukingaku - TENKOUKA;}
②if文使用 AmariKingaku = 各硬貨で割って余った金額を借り代入しておく変数 // 投入金額が硬貨の値以上 if (tounyuukinngaku >= FIVEHKOUKA) { // 500円硬貨の枚数 Fivehundred_Miasuu = tounyuukinngaku / FIVEHKOUKA; // 500円硬貨の枚数が枚数上限より大きい場合 if (Fivehundred_Miasuu > MAISUUJOUGEN) { // 余剰金の計算 AmariKingaku = (Fivehundred_Miasuu - MAISUUJOUGEN) * FIVEHKOUKA; // 500円硬貨の枚数 = 上限枚数 Fivehundred_Miasuu = MAISUUJOUGEN; // 投入金額の更新 tounyuukinngaku = tounyuukinngaku - (FIVEHKOUKA * MAISUUJOUGEN); // 投入金額 = 投入金額 + 余剰金 tounyuukinngaku = tounyuukinngaku + AmariKingaku; } else { tounyuukinngaku = tounyuukinngaku - (FIVEHKOUKA * Fivehundred_Miasuu); } } ・ ・ ・ ・ ・ ・ ・ ・ //これを各硬貨行い、最後に各硬貨の枚数を取得しました。
C#

補足情報(FW/ツールのバージョンなど)

Visual Studio 2019を使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/11/18 01:44

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
退会済みユーザー

退会済みユーザー

2021/11/18 01:49

[推奨していない質問] https://teratail.com/help/avoid-asking > コードをください・デバッグしてください等の丸投げの質問 > 何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。
fana

2021/11/18 01:56

> 演算子のみの使用でfor文やif文は使用せずに記述 「if を 三項演算子 に置き換えてみました^^」みたいなくだらない話なのか否か,という点を明確にしてください.
guest

回答2

0

ベストアンサー

お釣りの硬貨の種類は500円、100円、50円、10円。
各硬貨の上限枚数は99枚。
自動販売機に投入することが可能な金額もそれぞれの硬貨を99枚投下した際の和となっております。

この条件であれば,あり得るお釣りの最大額は 500*99 + 100*99 + 50*99 + 10*99 円ということですね.
(何も買わない場合は「お釣り」ではなく「返金」と呼ぶ気がするが,とりあえずそれはそれとして)

この条件下であれば
【高額な側の硬貨から枚数を決定していくならば,金額を硬貨の額で単純に除した値は 200 には達しない】
と思うので,以下でいける(n/100 という除算を,100を境にして0と1が切り替わるステップ関数として用いてよい)のではないでしょうか.

CSharp

1class Program 2{ 3 //(※この問題の前提条件の範疇でしか妥当ではないが) 4 //0~99に対してはそのまま,100以上に対しては99を返す. 5 static int SaturateTo99( int n ) 6 { //引数が0~199ならこれでいけるんちゃう? 7 int mod = n%100; 8 return mod + (99-mod)*(n/100); 9 } 10 11 static int Work( int Rest, int CoinValue ) 12 { 13 int nCoin = SaturateTo99( Rest/CoinValue ); //※ここの引数は200には達しないハズ 14 Console.WriteLine( CoinValue.ToString() + " * " + nCoin.ToString() ); 15 return Rest - nCoin * CoinValue; 16 } 17 18 //テスト 19 static void Main () 20 { 21 int Value = 500 * 98 + 100 * 10 + 50 * 2 + 10 * 52; //適当な値 22 Console.WriteLine( "Value = " + Value.ToString() ); 23 24 Value = Work( Value, 500 ); //500円硬貨の枚数を表示 25 Value = Work( Value, 100 ); //100円〃 26 Value = Work( Value, 50 ); //50円〃 27 Value = Work( Value, 10 ); //10円〃 28 29 Console.Read(); 30 } 31}

投稿2021/11/18 04:31

編集2021/11/18 05:01
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/11/18 04:38

四則演算と剰余 のみを用いた. 三項演算子を「使用して良い演算子」と見なすとか, Math.Min を使って良いとか, Convert.ToInt32 とかで bool から整数を作って良いとか…… そういう話ならば SaturateTo99 メソッドの中身はもっと素直にできるけども.
fana

2021/11/18 04:55

> 各硬貨の上限枚数は99枚 という制約への対処には,整数nに対して ( n>99 ? 1 : 0 ) 相当の関数が欲しいところ. これに関して,最初は「ロジスティック曲線みたいなのをステップ関数として用いれば良い」と思ったけども, 「小数点以下を丸める」みたいな操作を行って良いのか? という点がひっかかったのでやめた.
knkotaro1220

2021/11/18 05:59

Math.Minを使うとどのような考え方で構成していかれますか?? ステップ関数については使ったことないので、この機会にどのように使っているのか見てみたいです。
fana

2021/11/18 06:10

Math.Min を使うなら,実装は自明ではないでしょうか. 500円硬貨で払えるだけ払おうと考えたら 12 枚になるようなら 12 枚でOKですが, 500円硬貨で払えるだけ払おうと考えたら 105 枚になってしまうなら実際には上限の 99 枚にしなければなりません. すなわち, 500円硬貨で払えるだけ払おうと考えたら X 枚になるとき,実際には「Xと99のうち小さい側」にしなければなりません. で,2つの引数のうち小さい側の値を得る手段が Math.Min なのですから,Math.Min( X,99 ) とか素直に書けばそれで終わりでしょう.
fana

2021/11/18 06:13 編集

「ステップ関数」というのは,数学用語(?)です.(プログラミング言語的な「関数」ではなく) 整数xに対して f(x) = { xが99より大きいなら1, そうでないなら0 } となるような関数が存在するなら,上記の Math.Min(X,99) 相当の処理を,このf(x)を用いて実装できるよね,って話です.
fana

2021/11/18 06:15

99 * f(x) は,{ xが99より大きいなら99, そうでないなら0 }になります. x * ( 1-f(x) ) はどうでしょうか? { xが99より大きいなら0, そうでないならx }になります. なので,この2つの式を足せば, { xが99より大きいなら99, そうでないならx }という結果を得ることができますね.
fana

2021/11/18 06:37 編集

で,この回答内では, f(x) = x/100 という形の式を用いています. この f(x) は,「xが0以上200未満の範囲であれば」という条件においては, f(x) = { xが99より大きいなら1, そうでないなら0 } となります. 回答内のコードでは f(x) の使い方が1個上のコメントとは多少違ってはいますが. --- > 「xが0以上200未満の範囲であれば」という条件においては っていうところが,どうにも美しくない(?)というか,微妙感というかだなぁ……
guest

0

条件を見落としていたので取り消します。

日本の硬貨の場合、「20円玉」のような中途半端なものがなく、大きい硬貨は小さい硬貨の倍数という状況ですので、単に割り算だけで割り出せるかと思います。

投稿2021/11/18 02:11

編集2021/11/18 06:11
maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/11/18 04:58 編集

> 各硬貨の上限枚数は99枚 っていうところをどうするか? という話だと見えますが,そこはどうするのでしょうか? (→ちょっと待ってみたけど,現状,修正が入らない様子なので低評価を投じておく)
maisumakun

2021/11/18 06:12

> そこはどうするのでしょうか? てっきり「与えられる数」にかかるだけの条件(回答生成には影響がない)だと思いこんでいました。ご指摘ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問