Breaking down currency in c# - c#

i'm trying to get this program to break down a user defined amount of dollars into the fewest possible bills. i don't think my for loops are running because if i put a writeline line in them it doesn't show up when i run it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication13
{
class Program
{
static void Main(string[] args)
{
Console.Write("Enter the amount of money: $");
int totalAmount = Convert.ToInt32(Console.ReadLine());
calculateNumberOfBills(totalAmount);
}
static void calculateNumberOfBills(int totalAmount)
{
int[] denominations = { 20, 10, 5, 1 };
int[] numberOfBills = new int[4];
for (numberOfBills[0] = 0; totalAmount < 20; numberOfBills[0]++)
{
totalAmount = totalAmount - 20;
}
for (numberOfBills[1] = 0; totalAmount < 10; numberOfBills[1]++)
{
totalAmount = totalAmount - 10;
}
for (numberOfBills[2] = 0; totalAmount < 5; numberOfBills[2]++)
{
totalAmount = totalAmount - 5;
}
for (numberOfBills[3] = 0; totalAmount <= 0; numberOfBills[3]++)
{
totalAmount = totalAmount - 1;
}
Console.WriteLine("Number of twenties" + numberOfBills[0]);
Console.WriteLine("Number of tens" + numberOfBills[1]);
Console.WriteLine("Number of fives" + numberOfBills[2]);
Console.WriteLine("Number of ones" + numberOfBills[3]);
}
}
}

Take a look at this:
for (numberOfBills[0] = 0; totalAmount >= 20; numberOfBills[0]++)
{
totalAmount = totalAmount - 20;
}
for (numberOfBills[1] = 0; totalAmount >= 10; numberOfBills[1]++)
{
totalAmount = totalAmount - 10;
}
for (numberOfBills[2] = 0; totalAmount >= 5; numberOfBills[2]++)
{
totalAmount = totalAmount - 5;
}
for (numberOfBills[3] = 0; totalAmount > 0; numberOfBills[3]++)
{
totalAmount = totalAmount - 1;
}

This is a homework question, right?
for (numberOfBills[0] = 0; totalAmount < 20; numberOfBills[0]++)
make it
for (numberOfBills[0] = 0; totalAmount >= 20; numberOfBills[0]++)
and try again :)
The center piece is the condition where the loop should run.

Sorry, at this point this is "not a real question" and should most probably be tagged as homework.
Your "smaller than" comparisons should be changed to "greater than" comparisons and you're good to go with your solution. What's happening now is an integer overflow, eventually causing your first for-loop , which was infinitely looping until then to break.
There are easier ways to solve your problem, try it with a single loop and the modulo operator).

in your "for" loops you have inverse condition => totalAmount < 20 means that it executes loop while totalAmount is less than 20 - that is the opposite of what you want.
Change it to
for(...;totalAmount > 20; ...)

Try this, a bit of less code
int amt = 73;
Dictionary<int, int> dic = new Dictionary<int, int>() {{20,0},{10,0},{5,0},{1,0}};
int[] keys =new int[dic.Count];
dic.Keys.CopyTo(keys, 0);
foreach (int i in keys)
{
if (amt >= i)
{
dic[i] = amt / i;
amt = amt % i;
}
}

Related

Calculate datagridview rows

I have made a shop app for a school project
it adds goods from goods tab to factor tab
everything is working fine but I don't know how to calculate all - total price rows to make a variable that holds the price you have to pay
EDIT: now I'm getting the error in the picture
int n = dgvfactor.Rows.Count - 1;
dgvfactor.Rows.Add();
dgvfactor.Rows[n].Cells[0].Value = txtFGoodsCode.Text;
dgvfactor.Rows[n].Cells[1].Value = lblgoodsname.Text;
dgvfactor.Rows[n].Cells[2].Value = txtFAmount.Text;
dgvfactor.Rows[n].Cells[3].Value = lblprice.Text;
int amount = int.Parse(txtFAmount.Text);
int price = int.Parse(lblprice.Text);
int total = (amount * price);
lbltotal.Text = total.ToString();
dgvfactor.Rows[n].Cells[4].Value = lbltotal.Text;
var totalPrice = 0;
int rowPrice;
for (int i = 0; i < dgvfactor.Rows.Count; i++)
{
if (int.TryParse(dgvfactor.Rows[i].Cells[4].Value.ToString(), out rowPrice))
{
totalPrice += rowPrice;
}
}
lblpricetopay.Text = totalPrice.ToString();
Sorry If im mistaken here, but can't you just simply use a for-loop ?
var totalPrice = 0;
int rowPrice;
for (int i = 0; i < dgvfactor.Rows.Count; i++) {
// Note the NOT (!) new row...
if (!dgvfactor.Rows[i].IsNewRow) {
if (int.TryParse(dgvfactor.Rows[i].Cells[4].Value.ToString(), out rowPrice))
{
totalPrice += rowPrice;
}
}
}

How can I add the value of an item in a list box to a local variable in C#?

So I'm doing a practical that involves asking the user to input a score between 0 and 100. The program will keep track of the number of scores that have been entered, the total score (sum of all scores) and the average score.
To calculate the total score, I've come up of the idea of using a for loop that will cycle through my listbox and add each score to a variable (below).
int sTotal = 0;
for(int i = 0; i < lstScores.Items.Count; i++)
{
//Calculation occurs here
}
txtScoreTotal.Text = Convert.ToString(sTotal);
Thing is, I don't exactly know how to do it. I've tried searching to no avail. Any help would be greatly appreciated.
int sTotal = 0;
int Average = 0;
for(int i = 0; i < lstScores.Items.Count; i++)
{
bool result = Int16.TryParse(lstScores.Items[i],out int res);
if (result)
{
sTotale += res;
}
}
Average = sTotal / lstScores.Items.Count;
txtScoreTotal.Text = Convert.ToString(sTotal);
See this
int i = 0, result = 0;
while (i < lstScores.Items.Count)
{
result += Convert.ToInt32(lstScores.Items[i++]);
}
txtScoreTotal.Text = Convert.ToString(result);
I havent tried following, but you can try 1 line solution too
var sum = lstScores.Items.OfType<object>().Sum(x => Convert.ToInt32(x));
You need to handle exception if sum exceedes int.Max
Easiest is it to do with a foreach loop like this:
int sTotal = 0;
foreach (string item in lstScores.Items)
{
sTotal += Int32.Parse(item);
}
txtScoreTotal.Text = Convert.ToString(sTotal);

ATM program, can't figure out how to break down withdraw amount

First off yes, This is a homework assignment, I've been struggling with it for 3 days, and I can't figure it out.
Basically the problem is to take a decimal amount entered by the user in a text box, I then need to take that number and break it down into currency denominations, $50, $20, $10, $5, $1 and if the amount has a decimal then into
$.25, $.10, $.05, $.01.
And I need to break this down in the lowest amount of denominations possible, for example $100 would be broken down into 2 $50 bills.
Here is what I have so far.
private void btnDispense_Click(object sender, EventArgs e)
{
decimal i;
i = decimal.Parse(txtAmountReq.Text);
decimal totalAmount = Convert.ToDecimal(txtAmountReq);
int[] denomBills = { 50, 20, 10, 5, 1 };
int[] numberOfBills = new int[5];
decimal[] denomCoins = { .25m, .10m, .05m, .01m };
int[] numberOfCoins = new int[4];
//For loop for amount of bills
for (numberOfBills[0] = 0; totalAmount >= 50; numberOfBills[0]++)
{
totalAmount = totalAmount - 50;
}
for (numberOfBills[1] = 0; totalAmount < 20; numberOfBills[1]++)
{
totalAmount = totalAmount - 20;
}
for (numberOfBills[2] = 0; totalAmount < 10; numberOfBills[2]++)
{
totalAmount = totalAmount - 10;
}
for (numberOfBills[3] = 0; totalAmount < 5; numberOfBills[3]++)
{
totalAmount = totalAmount - 5;
}
for (numberOfBills[4] = 0; totalAmount <= 0; numberOfBills[4]++)
{
totalAmount = totalAmount - 1;
}
//For loop for the amount of coins
for (numberOfCoins[0] = 0; totalAmount >= .25m; numberOfBills[0]++)
{
totalAmount = totalAmount - .25m;
}
for (numberOfBills[1] = 0; totalAmount < .10m; numberOfBills[1]++)
{
totalAmount = totalAmount - .10m;
}
for (numberOfBills[2] = 0; totalAmount < .05m; numberOfBills[2]++)
{
totalAmount = totalAmount - .05m;
}
for (numberOfBills[3] = 0; totalAmount < .01m; numberOfBills[3]++)
{
totalAmount = totalAmount - .01m;
}
txt50.Text = Convert.ToString(numberOfBills[0]);
txt20.Text = Convert.ToString(numberOfBills[1]);
txt10.Text = Convert.ToString(numberOfBills[2]);
txt5.Text = Convert.ToString(numberOfBills[3]);
txt1.Text = Convert.ToString(numberOfBills[4]);
txtQuarter.Text = Convert.ToString(numberOfCoins[0]);
txtDime.Text = Convert.ToString(numberOfCoins[1]);
txtNickel.Text = Convert.ToString(numberOfCoins[2]);
txtPenny.Text = Convert.ToString(numberOfCoins[3]);
}
Any help would be greatly appreciated.
This is very famous knapsack type problem.You might want to start exploring from here : https://en.wikipedia.org/wiki/Change-making_problem
The best way to address this problem is to find all possible combinations of change and then find the optimal solution.
Below is the code by karamana I found on codeproject.com :
//find all the combinations
private void findAllCombinationsRecursive(String tsoln,
int startIx,
int remainingTarget,
CoinChangeAnswer answer) {
for(int i=startIx; i<answer.denoms.length ;i++) {
int temp = remainingTarget - answer.denoms[i];
String tempSoln = tsoln + "" + answer.denoms[i]+ ",";
if(temp < 0) {
break;
}
if(temp == 0) {
// reached the answer hence quit from the loop
answer.allPossibleChanges.add(tempSoln);
break;
}
else {
// target not reached, try the solution recursively with the
// current denomination as the start point.
findAllCombinationsRecursive(tempSoln, i, temp, answer);
}
}
}
in order to find optimum solution :
public CoinChangeAnswer findOptimalChange(int target, int[] denoms) {
CoinChangeAnswer soln = new CoinChangeAnswer(target,denoms);
StringBuilder sb = new StringBuilder();
// initialize the solution structure
for(int i=0; i<soln.OPT[0].length ; i++) {
soln.OPT[0][i] = i;
soln.optimalChange[0][i] = sb.toString();
sb.append(denoms[0]+" ");
}
// Read through the following for more details on the explanation
// of the algorithm.
// http://condor.depaul.edu/~rjohnson/algorithm/coins.pdf
for(int i=1 ; i<denoms.length ; i++) {
for(int j=0; j<target+1 ; j++) {
int value = j;
int targetWithPrevDenomiation = soln.OPT[i-1][j];
int ix = (value) - denoms[i];
if( ix>=0 && (denoms[i] <= value )) {
int x2 = denoms[i] + soln.OPT[i][ix];
if(x2 <= target && (1+soln.OPT[i][ix] < targetWithPrevDenomiation)) {
String temp = soln.optimalChange[i][ix] + denoms[i] + " ";
soln.optimalChange[i][j] = temp;
soln.OPT[i][j] = 1 + soln.OPT[i][ix];
} else {
soln.optimalChange[i][j] = soln.optimalChange[i-1][j]+ " ";
soln.OPT[i][j] = targetWithPrevDenomiation;
}
} else {
soln.optimalChange[i][j] = soln.optimalChange[i-1][j];
soln.OPT[i][j] = targetWithPrevDenomiation;
}
}
}
return soln;
}
Link to the original code here

Can I find the number of digits of a BigInteger in C#?

I am solving this problem, in which they ask for the index of the first Fibonacci number of 1000 digits, and my first idea was something similar to:
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.NoOfDigits < 1000)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
However, as far as I can tell, there is no method for counting the number of digits of a BigInteger. Is this true? One way of circumventing it is to use the .ToString().Length method of a BigInteger, but I'm told that string processing is slow.
A BigInteger also has a .ToByteArray(), and I thought of converting a BigInteger to a byte array and checking the length of that array - but I don't think that this uniquely determines the number of digits in the BigInteger.
For what it's worth, I implemented another way of solving it, which is manually storing the Fibonacci numbers in array, and which stops as soon as the array is full, and I compared this to the .ToString-based method, which is about 2.5 times slower, but the first method takes 0.1 second, which also seems like a long time.
Edit: I've tested the two suggestions in the answers below (the one with BigInteger.Log and the one with MaxLimitMethod). I get the following run times:
Original method: 00:00:00.0961957
StringMethod: 00:00:00.1535350
BigIntegerLogMethod: 00:00:00.0387479
MaxLimitMethod: 00:00:00.0019509
Program
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
Stopwatch clock = new Stopwatch();
clock.Start();
int index1 = Algorithms.IndexOfNDigits(1000);
clock.Stop();
var elapsedTime1 = clock.Elapsed;
Console.WriteLine(index1);
Console.WriteLine("Original method: {0}",elapsedTime1);
Console.ReadKey();
clock.Reset();
clock.Start();
int index2 = Algorithms.StringMethod(1000);
clock.Stop();
var elapsedTime2 = clock.Elapsed;
Console.WriteLine(index2);
Console.WriteLine("StringMethod: {0}", elapsedTime2);
Console.ReadKey();
clock.Reset();
clock.Start();
int index3 = Algorithms.BigIntegerLogMethod(1000);
clock.Stop();
var elapsedTime3 = clock.Elapsed;
Console.WriteLine(index3);
Console.WriteLine("BigIntegerLogMethod: {0}", elapsedTime3);
Console.ReadKey();
clock.Reset();
clock.Start();
int index4 = Algorithms.MaxLimitMethod(1000);
clock.Stop();
var elapsedTime4 = clock.Elapsed;
Console.WriteLine(index4);
Console.WriteLine("MaxLimitMethod: {0}", elapsedTime4);
Console.ReadKey();
}
}
static class Algorithms
{
//Find the index of the first Fibonacci number of n digits
public static int IndexOfNDigits(int n)
{
if (n == 1) return 1;
int[] firstNumber = new int[n];
int[] secondNumber = new int[n];
firstNumber[0] = 1;
secondNumber[0] = 1;
int currentIndex = 2;
while (firstNumber[n-1] == 0)
{
int carry = 0, singleSum = 0;
int[] tmp = new int[n]; //Placeholder for the sum
for (int i = 0; i<n; i++)
{
singleSum = firstNumber[i] + secondNumber[i];
if (singleSum >= 10) carry = 1;
else carry = 0;
tmp[i] += singleSum % 10;
if (tmp[i] >= 10)
{
tmp[i] = 0;
carry = 1;
}
int countCarries = 0;
while (carry == 1)
{
countCarries++;
if (tmp[i + countCarries] == 9)
{
tmp[i + countCarries] = 0;
tmp[i + countCarries + 1] += 1;
carry = 1;
}
else
{
tmp[i + countCarries] += 1;
carry = 0;
}
}
}
for (int i = 0; i < n; i++ )
{
secondNumber[i] = firstNumber[i];
firstNumber[i] = tmp[i];
}
currentIndex++;
}
return currentIndex;
}
public static int StringMethod(int n)
{
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.ToString().Length < n)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
public static int BigIntegerLogMethod(int n)
{
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (Math.Floor(BigInteger.Log10(x) + 1) < n)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
public static int MaxLimitMethod(int n)
{
BigInteger maxLimit = BigInteger.Pow(10, n - 1);
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.CompareTo(maxLimit) < 0)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
}
Provided that x > 0
int digits = (int)Math.Floor(BigInteger.Log10(x) + 1);
will get the number of digits.
Out of curiosity, I tested the
int digits = x.ToString().Length;
approach. For 100 000 000 iterations, it's 3 times slower than the Log10 solution.
Expanding on my comment--instead of testing based on number of digits, test based on exceeding a constant that has the upper limit of the problem:
public static int MaxLimitMethod(int n)
{
BigInteger maxLimit = BigInteger.Pow(10, n);
BigInteger x = 1;
BigInteger y = 1;
BigInteger tmp = 0;
int currentIndex = 2;
while (x.CompareTo(maxLimit) < 0)
{
tmp = x + y;
y = x;
x = tmp;
currentIndex++;
}
return currentIndex;
}
This should result in a significant performance increase.
UPDATE:
This is an even quicker method on .NET 5 (since GetBitLength() is required):
private static readonly double exponentConvert = Math.Log10(2);
private static readonly BigInteger _ten = 10;
public static int CountDigits(BigInteger value)
{
if (value.IsZero)
return 1;
value = BigInteger.Abs(value);
if (value.IsOne)
return 1;
long numBits = value.GetBitLength();
int base10Digits = (int)(numBits * exponentConvert).Dump();
var reference = BigInteger.Pow(_ten, base10Digits);
if (value >= reference)
base10Digits++;
return base10Digits;
}
The slowest part of this algorithm for large values is the BigInteger.Pow() operation. I have optimized the CountDigits() method in Singulink.Numerics.BigIntegerExtensions with a cache that holds powers of 10, so check that out if you are interested in the fastest possible implementation. It caches powers up to exponents of 1023 by default but if you want to trade memory usage for faster performance on even larger values you can increase the max cached exponent by calling BigIntegerPowCache.GetCache(10, maxSize) where maxSize = maxExponent + 1.
On an i7-3770 CPU, this library takes 350ms to get the digit count for 10 million BigInteger values (single-threaded) when the digit count <= the max cached exponent.
ORIGINAL ANSWER:
The accepted answer is unreliable, as indicated in the comments. This method works for all numbers:
private static int CountDigits(BigInteger value)
{
if (value.IsZero)
return 1;
value = BigInteger.Abs(value);
if (value.IsOne)
return 1;
int exp = (int)Math.Ceiling(BigInteger.Log10(value));
var test = BigInteger.Pow(10, exp);
return value >= test ? exp + 1 : exp;
}

maximum and minimum finding in c# listbox

private void tbimput_KeyPress(object sender, KeyPressEventArgs e)
{
if(e.KeyChar==(char)13)
{
if(tbimput.Text!="")
{
lbprices.Items.Add(tbunos.Text);
tbprices.Text="";
}
}
}
private void btracunaj_Click(object sender, EventArgs e)
{
int i,n,l,j;
double x,y,max,min;
n = lbprices.Items.Count;
l = lbprices.Items.Count;
x = Convert.ToDouble(lbprices.Items[0]);
y = Convert.ToDouble(lbprices.Items[0]);
max = n;
for(i = 1; i < n; i++)
{
x=Convert.ToDouble(lbprices.Items[i]);
if (x > max)
{
max = x;
}
}
min = l;
for(j=1;j<l;j++)
{
y = Convert.ToDouble(lbprices.Items[j]);
if (y < min)
{
min = y;
}
}
tbmax.Text = Convert.ToString(max);
tbmin.Text = Convert.ToString(min);
}
}
How is it possible to find the maximum and minimum values in a ListBox using cycle counting. I tried but it doesn't give me the minimum, only the maximum.For the minimum it gives me just a number of prices in ListBox. I have been trying for a very long time but have not been able to succeed.
One pass is going to be the most efficient
double max = Convert.ToDouble(lbprices.Items[0]);
double min = max;
for(i = 1; i < lbprices.Items.count; i++)
{
x = Convert.ToDouble(lbprices.Items[i]);
if (x > max)
max = x;
else if (x < min)
min = x;
}
This code:
for(j=1;j<l;j++)
y = Convert.ToDouble(lbprices.Items[j]);
if (y < min)
min = y;
Should be:
min = max;
for(j=1;j<l;j++)
{
y = Convert.ToDouble(lbprices.Items[j]);
if (y < min)
min = y;
}
PS.
You should pay careful attention to indentation to make your code readable. It will help you avoid errors like this.
Assuming you have a list of strings - or any IEnumerable<string> type:
var x = new List<string> { "1", "2", "3","7389" };
Minimum: var min = x.Min(y => Int32.Parse(y));
Maximum: var max = x.Max(y => Int32.Parse(y)))
If you don't have a IEnumerable<string> but the type is castable to string, you can first var z = x.Cast<string>(); and then perform the operation on the new list.
If you want to use your loops more or less the way you have them now, you should do:
max = Int32.MinValue;
for(i = 1; i < n; i++)
{
x=Convert.ToDouble(lbprices.Items[i]);
if (x > max)
{
max = x;
}
}
min = Int32.MaxValue;
for(j=1;j<l;j++)
{
y = Convert.ToDouble(lbprices.Items[j]);
if (y < min)
{
min = y;
}
}
If you want to do something cleaner with Linq, you could do:
var orderedItems = lbprices.Items.Select(x => Convert.ToDouble(x)).OrderBy(x => x);
var min = orderedItems.First();
var max = orderedItems.Last();
Or, even cleaner, #Andrej's use of .Min() and .Max():
var items = lbprices.Items.Select(x => Convert.ToDouble(x));
var min = items.Min();
var max = items.Max();

Categories

Resources