More efficiënt way for reoccuring modulo? - c#

I originally tried this with modulo but it did not work as expected
It keps giving me back the value(my teacher and I both couldn't figure it out)
Example:
Uw krijgt 200 x 2 euro terug
Uw Krijgt 100 x 1 euro terug
Uw krijgt 50 x 50 cent terug
Etc...
What it's supposed to do
I need to make a program that calculates howmuch change you get back.
Input 5
Cost: 2
Output: 1x 2 euro, 1x 1 euro, 0 x 50 cents, ...
My code
int Prijs, Ingegooid;
int Cent1, Cent2, Cent5, Cent10, Cent20, Cent50, Euro, Euro2, Wisselgeld;
private void btnCola_Click(object sender, RoutedEventArgs e)
{
Cent10 = 10;
Cent20 = 20;
Cent50 = 50;
Euro = 100;
Euro2 = 200;
Ingegooid = Convert.ToInt32(txbIngegooid.Text);
Prijs = 190;
Wisselgeld = (Ingegooid * 100 - Prijs);
Euro2 = Wisselgeld / Euro2;
MessageBox.Show("Uw krijgt " + Euro2 + " aantal 2 euro stukken terug.");
Euro = (Wisselgeld-Euro2*200) / Euro;
MessageBox.Show("Uw krijgt " + Euro + " aantal 1 euro stukken terug.");
Cent50 = (Wisselgeld-Euro2*200-Euro*100) / Cent50;
MessageBox.Show("Uw krijgt " + Cent50 + " aantal 50 cent stukken terug.");
Cent20 = (Wisselgeld-Euro2*200-Euro*100-Cent50*50) / Cent20;
MessageBox.Show("Uw krijgt " + Cent20 + " aantal 20 cent stukken terug.");
Cent10 = (Wisselgeld-Euro2*200-Euro*100-Cent50*50-Cent20*20) / Cent10;
}

You do not necessarily need modulo for this.
In this case it could actually be misleading.
Example: 90 Cents:
1 possible way to solve this:
1*50c + 2*20c.
Another way would be:
4*20c + 1*10c.
If you want to use the biggest coin whenever possible you could do it this way if you really want to:
10centAmmount = (change % 50) % 20;
In this case
10centAmmount = (90 % 50) % 20;
(90 % 50 = 40; 40 % 20 = 0 -> You do not need any 10 cent coins)
Working from the biggest coins to the smallest makes a lot more sense here.
I also recommend substracting the coins you already used from the change. Since the code gets "less crowded"
Euro2 = change/200;
change -= Euro2 * 200
Euro1 = change/100
change -= Euro1 * 100
...
A use case for modulo would be to figure out whether a number is dividable by any other number.
Example:
if (a % 4 == 0) {
print "a can be devided by 4";
Also the code is sort of confusing. You used Euro2 for the amount of cents a Euro coin has, but later you used it to count the number of 2 Euro coins. It would be a little less confusing if you used different variables for this. You could also use constants for values you never need to change, like the cent ammount of 2 euro coins.
Hope this sort of helps.

Related

Obtain the interval of the thousandth of a number c#

I'm trying to get from a number the interval where this number is.
For example my number is 10:
By tens: [1-100]
My number is 110:
By tens [101-200]
Thank #Juharr !
double n = 150;
double test = Math.Floor(n / 100) * 100 + 1;
double test2 = Math.Floor(n / 100) * 100 + 100;

Convert money input into coins

ive just started some classes on c# and have been given an assignment with the following rules:
Prompt the user to enter an amount of dollars and cents. For example 1.18
- Display the number of quarters, dimes, nickels, and pennies to make that amount
Example If they entered 2.16 it should say:
8 quarters, 1 dimes, 1 nickels, 1 pennies
the problem that i run into is that this only seems to work if they type the money value as a whole. so if they wanted to type $1.18 they would type 118 and it would work just fine, but as soon as they type 1.18 it crashes. another example would be if they were to type 765 for $7.65 it would work fine, however if they type it correctly as 7.65 it would fail. sorry for the lame question, im super new, thanks for the help!
int totalCash;
Console.WriteLine("input money");
string moneyString = Console.ReadLine();
totalCash = int.Parse(moneyString);
int quarter = totalCash / 25;
totalCash %= 25;
int dime = totalCash / 10;
totalCash %= 10;
int nickel = totalCash / 5;
totalCash %= 5;
int penny = totalCash / 1;
totalCash %= 1;
Console.WriteLine("{0} quarters, {1} dimes, {2} nickels, {3} pennies", quarter, dime, nickel, penny);
```
There are lots of ways get the result but this the best approach I ever tried :
public static string ConvertMoneyIntoCoins(double money)
{
int cents = (int)(Math.Round(money, 2) * 100);
var coins = new[] {
new { Name = "Quarters", Value = 25 }, new { Name = "Dimes", Value = 10 },
new { Name = "Nickels", Value = 5 }, new { Name = "Pennies", Value = 1 }
};
var changes = coins.Select(coin => new { Amt = Math.DivRem(cents, coin.Value, out cents), Coin = coin }).Where(x => x.Amt != 0).ToList();
var strBld = new StringBuilder();
foreach (var change in changes)
{
strBld.Append(change.Amt + " " + change.Coin.Name + ", ");
}
return strBld.ToString();
}
It's working when you enter whole number should be the clue you pay attention to. If you assume the whole number is dollars, you can not mod by a whole number. All of your divisors are a factor of 100 too big. When you do that, you'll notice that you have the wrong data type as well. Note that i disagree with using tryparse when debugging as it eats errors. You should be running it in debug mode and then you would get an actual stack trace and a line it crashes at.

How do I show cents when I am writing a code to count total money, the code below is only showing a whole number (such as $1)

I am trying to write a code in C# that prints out the total of dollars and cents I have. I have the first part done, but the end of the code won't show how much cents there is when I run the whole code, it only shows a whole number (such as $1), when I need the code to show something like $1.56. What am I missing in the program in order to show this?
Console.WriteLine("Enter number of quarters: ");
int quarters = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter number of dimes: ");
int dimes = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter number of nickels: ");
int nickels = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter number of pennies: ");
int pennies = Convert.ToInt32(Console.ReadLine());
double dollars = (int)(((quarters * 0.25) + (dimes * 0.10) + (nickels * 0.05) + (pennies * 0.01)) % 1 * 100);
Console.WriteLine("Your total is $" + dollars);
When I typed in 4 quarters, 0 dimes, 0 nickels, and 1 penny, it shows the result as $1 not $1.01
You are forcing the result as int, so the decimals are cut
double dollars = (int)(((quarters * 0.25) + (dimes * 0.10) + (nickels * 0.05) + (pennies * 0.01)) % 1 * 100);
Do not force to int, on the contrary, force to double
double dollars = ((quarters * 0.25) + (dimes * 0.10) + (nickels * 0.05) + (pennies * 0.01)) % 1 * 100;
But, since you are handling money, I would recommend to handle everything with decimal
decimal dollars = ((quarters * 0.25) + (dimes * 0.10) + (nickels * 0.05) + (pennies * 0.01)) % 1 * 100;
Better explained in dotnet perls
Decimal accurately stores numeric data. The .NET Framework offers this
type for programs where rounding errors are harmful. Decimal stores
large and small numbers with many digits after the decimal place.
EDIT
When I put in decimal dollars instead of double dollars, I then get
the error, "Cannot implicitly convert type 'double' to 'decimal'. An
explicit conversion exists (are you missing a cast?)
It is becuse you need all the operation of the same type, you can do
int quarters =1;
int dimes = 1;
int nickels = 1;
int pennies = 1;
decimal dollars = ((quarters * 0.25m) + (dimes * 0.10m) + (nickels * 0.05m) + (pennies * 0.01m)) % 1 * 100;
Console.WriteLine("Your total is $" + dollars);
Note the use of a m after the number, this is to tell the compiler that the type is decimal or Money, not double.

C# Triangle numbers optimization

The task is to find a triangle number which has at least 500 divisors.
For example 28 has 6 divisors: 1,2,4,7,14,28
My code works for up to 200 divisors, but for 500 it runs forever...
Is there any way to optimize the code. For instance I thought of dynamic optimization and memoization, but couldn't find a way to do it?
int sum = 0;
int counter = 0;
int count = 1;
bool isTrue = true;
while (isTrue)
{
counter = 0;
sum += count;
for (int j = 1; j <= sum; j++)
{
if (sum % j == 0)
{
counter++;
if (counter == 500)
{
isTrue = false;
Console.WriteLine("Triangle number: {0}", sum);
break;
}
}
}
count++;
}
Console.WriteLine("Number of divisors: {0}", counter);
Ignore the fact that the number is a triangle number. If you can solve this problem quickly:
given any number n, determine the number of divisors it has
then obviously you can solve Euler #12 quickly. Just list the triangle numbers, which are easy to calculate, determine the number of divisors of each, and stop when you get a result 500 or larger.
So how do you determine the number of divisors quickly? As you've discovered, when the numbers get big, it's a lot of work.
Here's a hint. Suppose you already have the prime factorization. Let's pick a number, say, 196. Factorize that into prime numbers:
196 = 2 x 2 x 7 x 7
I can tell you just by glancing at the factorization that 196 has nine divisors. How?
Because any divisor of 196 is of the form:
(1, 2 or 2x2) x (1, 7 or 7x7)
So obviously there are nine possible combinations:
1 x 1
1 x 7
1 x 7 x 7
2 x 1
2 x 7
2 x 7 x 7
2 x 2 x 1
2 x 2 x 7
2 x 2 x 7 x 7
Pick another number. 200, lets say. Thats 2 x 2 x 2 x 5 x 5. So there are twelve possibilities:
1 x 1
1 x 5
1 x 5 x 5
2 x 1
2 x 5
...
2 x 2 x 2 x 5 x 5
See the pattern? You take the prime factorization, group them by prime, and count how many are in each group. Then you add one to each of those numbers and multiply them together. Again, in 200 there are three twos and two fives in the prime factorization. Add one to each: four and three. Multiply them together: twelve. That's how many divisors there are.
So you can find the number of divisors very quickly if you know the prime factorization. We have reduced the divisor problem to a much easier problem: Can you figure out how to produce a prime factorization quickly?
here are some optimizations I'll just throw out there for you.
the easiest thing is to change
for (int j = 1; j <= sum; j++)
{
if (sum % j == 0)
{
counter++;
if (counter == 500)
{
isTrue = false;
Console.WriteLine("Triangle number: {0}", sum);
break;
}
}
}
if you've found 1 divisor, you've found 2 divisors, so change it to
for (int j = 1; j <= sum; j++)
{
if (sum % j == 0)
{
if(sum/j < j)
break;
else if(sum/j == j)
counter++;
else
counter +=2;
if (counter == 500)
{
isTrue = false;
Console.WriteLine("Triangle number: {0}", sum);
break;
}
}
}
this will reduce the runtime a lot, but it will still take a long time.
another optimization you can do is to not start checking form sum but calculate the smallest number that has 500 divisors.
and then you can find the largest triangle number after that, and start from there.
If you can figure something else special about the nature of this problem, than it is possible for you to reduce the runtime by a whole lot.
The number of divisors of a number is the product of the powers of the prime factors plus one. For example: 28 = 2^2*7^1, so the # of divisors is (2+1)*(1+1) = 6.
This means that, if you want many divisors compared to the size of the number, you don't want any one prime to occur too often. Put another way: it is likely that the smallest triangular number with at least 500 divisors is the product of small powers of small primes.
So, instead of checking every number to see if it divides the triangular number, go through a list of the smallest primes, and see how often each one occurs in the prime factorization. Then use the formula above to compute the number of divisors.
Take these steps:
1.) Calculate the first log(2, 499) prime numbers (not 500, as 1 is counted as a divisor if I am nit mistaken despite the fact that it is not prime, as it has only one divisor). There are many solutions out there, but you catch my drift.
2.) A triangle number is of the form of n * (n + 1) / 2, because
1 + 2 + ... + 100 = (1 + 100) + (2 + 99) + ... + (50 + 51) = 101 * 50 = 101 * 100 / 2 = 5050 (as Cauchy solved it when he was an eight-year boy and the teacher punished him with this task).
1 + ... + n = (1 + n) + (2 + n - 1) + ... = n * (n + 1) / 2.
3.) S = prod(first log(2, 499) prime numbers)
4.) Solve the equation of n * (n + 1) / 2 = S and calculate its ceiling. You will have an integer, let's call it m.
5.)
while (not(found))
found = isCorrect(m)
if (not(found)) then
m = m + 1
end if
end while
return m
and there you go. Let me know if I was able to help you.
As #EricLippert nad #LajosArpad mentioned, the key idea is to iterate over triangle numbers only. You can calculate them using the following formula:
T(n) = n * (n + 1) / 2
Here is JSFiddle which you may find helpful.
function generateTriangleNumber(n) {
return (n * (n + 1)) / 2;
}
function findTriangleNumberWithOver500Divisors() {
var nextTriangleNum;
var sqrt;
for (i = 2;; i++) {
var factors = [];
factors[0] = 1;
nextTriangleNum = generateTriangleNumber(i);
sqrt = Math.pow(nextTriangleNum, 0.5);
sqrt = Math.floor(sqrt);
var j;
for (j = 2; j <= sqrt; j++) {
if (nextTriangleNum % j == 0) {
var quotient = nextTriangleNum / j;
factors[factors.length] = j;
factors[factors.length] = quotient;
}
}
factors[factors.length] = nextTriangleNum;
if (factors.length > 500) {
break;
}
}
console.log(nextTriangleNum);
}
Incidentally, the first Google result for divisors of triangular number search query gives this :)
Project Euler 12: Triangle Number with 500 Divisors
See if it helps.
EDIT: Text from that article:
The first triangle number with over 500 digits is: 76576500 Solution
took 1 ms

Order of growth of specific recursive function

What is the order of growth of the following function?
static int counter = 0;
static void Example(int n)
{
if (n == 1) return;
for (int i = 0; i < n; i++)
{
counter++;
}
Example(n / 2);
}
In order to solve it I have done the following:
I first got rid of the inner for loop in order to end up with:
static void Example(int n)
{
if (n == 1) return;
counter++;
Example(n / 2);
}
By analyzing that I was able to tell that the order of growth of that method was log base 2 of n .
so I am thinking that the final answer will be log base 2 times something else. How can I figure it out?
Let's look at both the original and the modified function. In the original function, you have the following amount of work done:
A constant amount of work for the base case check.
O(n) work to count up the number.
The work required for a recursive call to something half the size.
We can express this as a recurrence relation:
T(1) = 1
T(n) = n + T(n / 2)
Let's see what this looks like. We can start expanding this out by noting that
T(n) = n + T(n / 2)
= n + (n / 2 + T(n / 4)
= n + n/2 + T(n / 4)
= n + n/2 + (n / 4 + T(n / 8))
= n + n/2 + n/4 + T(n / 8)
We can start to see a pattern here. If we expand out the T(n / 2) bit k times, we get
T(n) = n + n/2 + n/4 + ... + n/2k + T(n/2k)
Eventually, this stops when n / 2k = 1. When this happens, we have
T(n) = n + n/2 + n/4 + n/8 + ... + 1
What does this evaluate to? Interestingly, this sum is equal to 2n + 1, because the sum n + n/2 + n/4 + n/8 + ... = 2n. Consequently, this first function is O(n). We could have also arrived at this conclusion by using the Master Theorem, but it's interesting to see this approach as well.
So now let's look at the new function. This one does
A constant amount of work for the base case check.
The work required for a recursive call to something half the size.
We can write this recurrence as
T(1) = 1
T(n) = 1 + T(n / 2)
Using the same trick as before, let's expand out T(n):
T(n) = 1 + T(n / 2)
= 1 + 1 + T(n / 4)
= 1 + 1 + 1 + T(n / 8)
More generally, after expanding out k times, we get
T(n) = k + T(n / 2k)
This stops when n / 2k = 1, which happens when k = log2 n (that is, lg n). In this case, we get that
T(n) = lg n + T(1) = lg n + 1
So T(n) = O(lg n) in this case.
Hope this helps!
Let's see now.. this will add 1 to the counter n times.
each call n is reduced by half until it reaches one.
You can get rid of the loop and use
counter+=n;
instead, because basically the loop adds n to counter, 1 by one.
This means that n will be added to the counter each time it runs, and then become smaller by 2 until it reaches one.
so say n = 40.
counter:
40 -> 60 -> 70 -> 75 -> 77 -> 77.
n:
40 -> 20 -> 10 -> 5 -> 2 -> 1.
Just a push in the right direction (counter+=n; being the important part)

Categories