C# lottery 6 from 49 algorithm - c#

I need to display odds to win with ten decimals if I play with just one variant, for six five and four numbers. For example I need to have this 0.0000000715 but I have this 0.0027829314 if I introduce 49,6,I. What is the problem?How can I make it work? I am a beginner and I don't know how i can obtain this 0.0000000715.
class Program
{
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
int k = Convert.ToInt32(Console.ReadLine());
string category = Console.ReadLine();
switch (category)
{
case "I":
calculate(n,k);
break;
case "II":
calculate(n, k);
break;
case "III":
calculate(n, k);
break;
}
}
static void calculate(int n, int k)
{
int nk = n - k;
decimal count = prod(1, nk) / prod(k + 1, n);
decimal r = prod(1, k) / prod(n - k + 1, n);
decimal sum = count * r;
Console.WriteLine(Math.Round(r,10));
}
static decimal prod(int x, int y)
{
decimal prod = 0;
for(int i = x; i <= y; i++)
{
prod = x * y;
}
return prod;
}
}

The general solution would be bc(6,n)*bc(49-6,6-n)/bc(49, 6), where n is, 4, 5 or 6 and bc is the binomial coefficient.
Btw.: double should be enough for 10 decimal places, there is no need to use decimal.
using System;
public class Program
{
//bonomial coefficient
static double bc(double n, double k)
{
if (k == 0 || k == n)
return 1;
return bc(n - 1, k - 1) + bc(n - 1, k);
}
public static void Main()
{
for(int n = 4; n <=6; ++n){
Console.WriteLine(bc(6,n)*bc(49-6,6-n)/bc(49, 6));
}
}
}

I am not sur what function you were using.
The chances of winning all 6 numbers is 1 in 13,983,816
The actual calculation is this:
49C6 = 49!/(43! x 6!) = 13983816
So the probability to win is 1 / 13,983,816 = 0.0000000715

Your prod function should look like:
static decimal prod(int x, int y)
{
decimal prod = 1;
for(int i = x; i <= y; i++)
{
prod = prod * i;
}
return prod;
}

As jjj mentioned, you overwrite "prod" everytime, but you need to add it

Related

Winning lottery odds

I have another question about lottery. I have to make this problem: "You want to participate in the game of chance 6 out of 49 with only one variant and you want to know what chances you will win:category I (6 numbers),category II (5 numbers),category III (4 numbers). Write a application that receive as input data the total number of balls, the number of balls drawn and then prints the chances of winning with an accuracy of 10 decimals if played with a single variant". My question is: What is the formula to calculate this?I try to find that formula but i didn't find it. An example will be 40, 5 and II (5 numbers) and the result is 0.0002659542 or 45 , 15 and category III is 0.0000001324.I need to mention i am a beginner. My code is working but just for 6 from 49.
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
int k = Convert.ToInt32(Console.ReadLine());
string extract = Console.ReadLine();
int category1 = category(extract);
switch (category1)
{
case 6:
calculateTheOddsToWin(n, k, extract);
break;
case 5:
calculateTheOddsToWin(n, k, extract);
break;
case 4:
calculateTheOddsToWin(n, k, extract);
break;
}
}
static void calculateTheOddsToWin(int n , int k , string extract)
{
double comb = combination(n, k);
decimal solution =(decimal)( 1 / comb);
decimal round = Math.Round(solution,10);
Console.WriteLine(round);
}
static double combination(int n, int k)
{
double factN = factorialN(n);
double factK = factorialK(k);
double factNK = substractFactorialNK(n, k);
double combination = factN / (factNK * factK);
return combination;
}
static double factorialN(int n)
{
double factorialN = 1;
for(int i = 1; i <= n; i++)
{
factorialN *= i;
}
return factorialN;
}
static double factorialK( int k)
{
double factorialK = 1;
for (int i = 1; i <= k; i++)
{
factorialK *= i;
}
return factorialK;
}
static double substractFactorialNK(int n, int k)
{
double factorialNK = 1;
int substract = n - k;
for (int i = 1; i <= substract; i++)
{
factorialNK *= i;
}
return factorialNK;
}
static int category(string extract)
{
if(extract == "I")
{
return 6;
}else if(extract == "II")
{
return 5;
}else if(extract == "III")
{
return 4;
}
else
{
return -1;
}
}
You need to calculate three numbers:
T: The total number of combinations
W: The number of ways to draw the desired amount of winning numbers
L: The number of ways to draw the desired amount of losing numbers
Then, the answer is W * L / T
Example: 40 numbers, 5 draws, 4 correct:
W = choose(5,4) = 5 (4 winners from 5 possibilities)
L = choose(35,1) = 35 (1 loser from 35 possibilities)
T = choose(40, 5) = 658008 (5 numbers from 40 possibilities)
5 * 35 / 658008 = 0.00265954
Generically:
n = count of numbers
d = count of available winning numbers = draw size
k = count of winning numbers drawn (d, d-1, and d-2 for I, II, III).
W = choose(d, k) (k winners from d possibilities)
L = choose(n-d, d-k) (d-k losers from n-d possibilities)
T = choose(n, d) (d numbers from n possibilities)

Negative exponent of a number

I made this program to find the power of any number using recursion and it works, but also I need to find negative power of the number, for example, I have the base = 2 and the exponent = -3 so the result = 0.125,
what should I do?
public static int power(int x, int n )
{
if (n < 0)
{
Console.WriteLine("invalid");
return 0;
}
else if (n == 1)
{
return x;
}
else if (n == 0)
{
return 1;
}
else
{
return x * power(x, n - 1);
}
}
static void Main(string[] args)
{
Console.Write("enter the base: ");
int x = int.Parse(Console.ReadLine());
Console.Write("enter the power:");
int n = int.Parse(Console.ReadLine());
int z = power(x, n);
Console.WriteLine(z);
}
Since the result of raising a number to a negative power is just 1 divided by the number raised to the non-negative power, you can change you method like so (note that we also need to return a double type, since we're dealing with fractional values):
public static double power(int x, int n)
{
if (n < 0) return 1 / power(x, -n); // recursive call with '-n' for negative powers
if (n == 0) return 1;
if (n == 1) return x;
return x * power(x, n - 1);
}
Now it works with negative numbers:
public static void Main(string[] args)
{
Console.WriteLine(power(2, -3));
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output

BigInteger/BigRational problems with converting to double and back

Maybe I didn't understood how to use those two types: BigInteger/BigRational, but generally speaking I want to implement those two equations:
This is my data: n=235, K = 40 and this small p (which actually is called rho) is 5. In the beginning the problem was with the Power function: the results were very very very big - so that is why I used the BigInteger library. But then I realize that there will be a division made and the result will be a number of type double - so I changed to BigRational library.
Here is my code:
static void Main(string[] args)
{
var k = 40;
var n = 235;
var p = 5;
// the P(n) equation
BigRational pnNumerator = BigRational.Pow(p, n);
BigRational pnDenominator = BigRational.Pow(k, (n - k)) * Factorial(k);
// the P(0) equation
//---the right side of "+" sign in Denominator
BigRational pk = BigRational.Pow(p, k);
BigRational factorialK = Factorial(k);
BigRational lastPart = (BigRational.Subtract(1, (double)BigRational.Divide(p, k)));
BigRational factorialAndLastPart = BigRational.Multiply(factorialK, lastPart);
BigRational fullRightSide = BigRational.Divide(pk, factorialAndLastPart);
//---the left side of "+" sign in Denominator
BigRational series = Series(k, p, n);
BigRational p0Denominator = series + fullRightSide;
BigRational p0Result = BigRational.Divide(1, p0Denominator);
BigRational pNResult = BigRational.Divide((pnNumerator * p0Result), pnDenominator);
Console.WriteLine(pNResult);
Console.ReadKey();
}
static BigRational Series(int k, int p, int n)
{
BigRational series = new BigRational(0.0);
var fin = k - 1;
for (int i = 0; i < fin; i++)
{
var power = BigRational.Pow(p, i);
var factorialN = Factorial(n);
var sum = BigRational.Divide(power, factorialN);
series += sum;
}
return series;
}
static BigRational Factorial(int k)
{
if (k <= 1)
return 1;
else return BigRational.Multiply(k, Factorial(k - 1));
}
The main problem is that it does not return any "normal" value like for example 0.3 or 0.03. The result which is printed to the console is a very long number (like 1200 digits in it)...
Can someone please take a look at my code and help me fix the problem and be able to solve this equations by the code. Thank you
Console.WriteLine(pNResult); calls BigRational.ToString() under-the-hood, which prints the number in the form numerator/denominator.
It's easy to miss the / in the output given how large the numerator and denominator both are in this case.
BigRational supports conversions to decimal and to double. The result is too small to fit in a decimal in this case though. Converting to a double, gives the result 7.89682541396914E-177.
If you need better precision, you'll need a custom conversion to a decimal-format string, like the one in this Stackoverflow answer.
Using that custom conversion routine to get the result to 1000 decimal places -
Console.WriteLine(pNResult.ToDecimalString(1000));
- gives the result as:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078968254139691306770128897137459492828971170349380336740935269651539684650525033676003134593283361305530675112470528408219177025044254116462798561450442318290046626248451723040397770263675109107145461310779641705093156106311143727608208629473359566457461384474633112850335950017209558136575135801388668687571284492241030561019606955986265585636660304889792027894460104216176719717671500843399685686146432982358441225578366059001576682388503227237202077881334695352338638383337717103303153521108812750644260562351186866587629456292506971252525125976755540274041651740194108430555751648707933592643410475214924394223640168857340953563111097979394441303100701008120008166339365089771585037880235325673143152814510586536335380671360865230428857049658368242543653234599817430185879648427434216378356518036776477170130227628307039
To check that your calculation code is operating correctly, you can add unit-tests for the different functions (Factorial, Series and the computation of P itself).
An approach that is practical here is to calculate the results by hand for certain small values of k, n and p and check that your functions compute the same results.
If you're using Visual Studio, you can use this MSDN page as a starting point for creating a unit-test project. Note that the functions under test must be visible to the unit-test project, and your unit-test project will need to have a reference added to your existing project where you're doing the computation, as explained in the link.
Starting with Factorial, which is the easiest to check, you could add a test like this:
[TestClass]
public class UnitTestComputation
{
[TestMethod]
public void TestFactorial()
{
Assert.AreEqual(1, Program.Factorial(0));
Assert.AreEqual(1, Program.Factorial(1));
Assert.AreEqual(2, Program.Factorial(2));
Assert.AreEqual(6, Program.Factorial(3));
Assert.AreEqual(24, Program.Factorial(4));
}
}
The code in your question passes that test.
You can then add a test method for your Series function:
[TestMethod]
public void TestSeries()
{
int k = 1;
int p = 1;
BigRational expected = 1;
Assert.AreEqual(expected, Program.Series(k, p));
k = 2;
p = 1;
expected += 1;
Assert.AreEqual(expected, Program.Series(k, p));
k = 3;
p = 1;
expected += (BigRational)1 / (BigRational)2;
Assert.AreEqual(expected, Program.Series(k, p));
k = 1;
p = 2;
expected = 1;
Assert.AreEqual(expected, Program.Series(k, p));
k = 2;
p = 2;
expected += 2;
Assert.AreEqual(expected, Program.Series(k, p));
}
This showed up some problems in your code:
n shouldn't actually be a parameter to this function, because in this context n isn't the parameter to function P, but actually just the "index-of-summation". n's local value in this function is represented by your i variable.
This then means that your Factorial(n) call needs to change to Factorial(i)
The loop is also off-by-one, because the Sigma notation for the summation is inclusive of the number at the top of the Sigma, so you should have <= fin (or you could also have written this simply as < k).
This is the updated Series function:
// CHANGED: Removed n as parameter (n just the index of summation here)
public static BigRational Series(int k, int p)
{
BigRational series = new BigRational(0.0);
var fin = k - 1;
// CHANGED: Should be <= fin (i.e. <= k-1, or < k) because it's inclusive counting
for (int i = 0; i <= fin; i++)
{
var power = BigRational.Pow(p, i);
// CHANGED: was Factorial(n), should be factorial of n value in this part of the sequence being summed.
var factorialN = Factorial(i);
var sum = BigRational.Divide(power, factorialN);
series += sum;
}
return series;
}
To test the P(n) calculation you can move that out into its own function to test (I've called it ComputeP here):
[TestMethod]
public void TestP()
{
int n = 1;
int k = 2;
int p = 1;
// P(0) = 1 / (2 + 1/(2*(1 - 1/2))) = 1/3
// P(1) = (1/(1/2 * 2)) * P(0) = P(0) = 1/3
BigRational expected = 1;
expected /= 3;
Assert.AreEqual(expected, Program.ComputeP(k, n, p));
n = 2;
k = 2;
p = 1;
// P(2) = (1/(1*2)) * P(0) = 1/6
expected = 1;
expected /= 6;
Assert.AreEqual(expected, Program.ComputeP(k, n, p));
}
This showed up a problem with calculating P(n) - you had a cast to double in there which shouldn't have been present (the result is inaccurate then - you need to keep all the intermediate results in BigRational). There's no need for the cast, so just removing it fixes this problem.
Here is the updated ComputeP function:
public static BigRational ComputeP(int k, int n, int p)
{
// the P(n) equation
BigRational pnNumerator = BigRational.Pow(p, n);
BigRational pnDenominator = BigRational.Pow(k, (n - k)) * Factorial(k);
// the P(0) equation
//---the right side of "+" sign in Denominator
BigRational pk = BigRational.Pow(p, k);
BigRational factorialK = Factorial(k);
// CHANGED: Don't cast to double here (loses precision)
BigRational lastPart = (BigRational.Subtract(1, BigRational.Divide(p, k)));
BigRational factorialAndLastPart = BigRational.Multiply(factorialK, lastPart);
BigRational fullRightSide = BigRational.Divide(pk, factorialAndLastPart);
//---the left side of "+" sign in Denominator
BigRational series = Series(k, p);
BigRational p0Denominator = series + fullRightSide;
BigRational p0Result = BigRational.Divide(1, p0Denominator);
BigRational pNResult = BigRational.Divide((pnNumerator * p0Result), pnDenominator);
return pNResult;
}
For avoidance of confusion, here is the whole updated calculation program:
using System;
using System.Numerics;
using System.Text;
using Numerics;
public class Program
{
public static BigRational ComputeP(int k, int n, int p)
{
// the P(n) equation
BigRational pnNumerator = BigRational.Pow(p, n);
BigRational pnDenominator = BigRational.Pow(k, (n - k)) * Factorial(k);
// the P(0) equation
//---the right side of "+" sign in Denominator
BigRational pk = BigRational.Pow(p, k);
BigRational factorialK = Factorial(k);
// CHANGED: Don't cast to double here (loses precision)
BigRational lastPart = (BigRational.Subtract(1, BigRational.Divide(p, k)));
BigRational factorialAndLastPart = BigRational.Multiply(factorialK, lastPart);
BigRational fullRightSide = BigRational.Divide(pk, factorialAndLastPart);
//---the left side of "+" sign in Denominator
BigRational series = Series(k, p);
BigRational p0Denominator = series + fullRightSide;
BigRational p0Result = BigRational.Divide(1, p0Denominator);
BigRational pNResult = BigRational.Divide((pnNumerator * p0Result), pnDenominator);
return pNResult;
}
// CHANGED: Removed n as parameter (n just the index of summation here)
public static BigRational Series(int k, int p)
{
BigRational series = new BigRational(0.0);
var fin = k - 1;
// CHANGED: Should be <= fin (i.e. <= k-1, or < k) because it's inclusive counting
for (int i = 0; i <= fin; i++)
{
var power = BigRational.Pow(p, i);
// CHANGED: was Factorial(n), should be factorial of n value in this part of the sequence being summed.
var factorialN = Factorial(i);
var sum = BigRational.Divide(power, factorialN);
series += sum;
}
return series;
}
public static BigRational Factorial(int k)
{
if (k <= 1)
return 1;
else return BigRational.Multiply(k, Factorial(k - 1));
}
static void Main(string[] args)
{
var k = 40;
var n = 235;
var p = 5;
var result = ComputeP(k, n, p);
Console.WriteLine(result.ToDecimalString(1000));
Console.ReadKey();
}
}
// From https://stackoverflow.com/a/10359412/4486839
public static class BigRationalExtensions
{
public static string ToDecimalString(this BigRational r, int precision)
{
var fraction = r.GetFractionPart();
// Case where the rational number is a whole number
if (fraction.Numerator == 0 && fraction.Denominator == 1)
{
return r.GetWholePart() + ".0";
}
var adjustedNumerator = (fraction.Numerator
* BigInteger.Pow(10, precision));
var decimalPlaces = adjustedNumerator / fraction.Denominator;
// Case where precision wasn't large enough.
if (decimalPlaces == 0)
{
return "0.0";
}
// Give it the capacity for around what we should need for
// the whole part and total precision
// (this is kinda sloppy, but does the trick)
var sb = new StringBuilder(precision + r.ToString().Length);
bool noMoreTrailingZeros = false;
for (int i = precision; i > 0; i--)
{
if (!noMoreTrailingZeros)
{
if ((decimalPlaces % 10) == 0)
{
decimalPlaces = decimalPlaces / 10;
continue;
}
noMoreTrailingZeros = true;
}
// Add the right most decimal to the string
sb.Insert(0, decimalPlaces % 10);
decimalPlaces = decimalPlaces / 10;
}
// Insert the whole part and decimal
sb.Insert(0, ".");
sb.Insert(0, r.GetWholePart());
return sb.ToString();
}
}
And here is the whole unit-test program:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Numerics;
[TestClass]
public class UnitTestComputation
{
[TestMethod]
public void TestFactorial()
{
Assert.AreEqual(1, Program.Factorial(0));
Assert.AreEqual(1, Program.Factorial(1));
Assert.AreEqual(2, Program.Factorial(2));
Assert.AreEqual(6, Program.Factorial(3));
Assert.AreEqual(24, Program.Factorial(4));
}
[TestMethod]
public void TestSeries()
{
int k = 1;
int p = 1;
BigRational expected = 1;
Assert.AreEqual(expected, Program.Series(k, p));
k = 2;
p = 1;
expected += 1;
Assert.AreEqual(expected, Program.Series(k, p));
k = 3;
p = 1;
expected += (BigRational)1 / (BigRational)2;
Assert.AreEqual(expected, Program.Series(k, p));
k = 1;
p = 2;
expected = 1;
Assert.AreEqual(expected, Program.Series(k, p));
k = 2;
p = 2;
expected += 2;
Assert.AreEqual(expected, Program.Series(k, p));
}
[TestMethod]
public void TestP()
{
int n = 1;
int k = 2;
int p = 1;
// P(0) = 1 / (2 + 1/(2*(1 - 1/2))) = 1/3
// P(1) = (1/(1/2 * 2)) * P(0) = P(0) = 1/3
BigRational expected = 1;
expected /= 3;
Assert.AreEqual(expected, Program.ComputeP(k, n, p));
n = 2;
k = 2;
p = 1;
// P(2) = (1/(1*2)) * P(0) = 1/6
expected = 1;
expected /= 6;
Assert.AreEqual(expected, Program.ComputeP(k, n, p));
}
}
Incidentally, the P(n) result with the updated program for your input values for n, p and k is now:
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000593109980769066916025972569398424267669807629726200017375290861590898269902277869938365969961320969473356001666906480007119114830921839913623591124192047955091318951831902550404167336054683697071654765071519020060437129398945035521954738463786221029427589397688847246112810536958194364039693387170592425527136243952416704526069736811587380688876091926255908361275575249492845970903676492429684929779402600032481018886875698972533534890841796034626337674846620462046294537488580901129338625628349474358946962065227890599744775562637784553656488649841148591533557896418988044457914999854241038974478576578909626765823565817758792682480009619613438867365912697996527957775248350987801430141776875171808382272960426476953742528769626555642957093028553993908356226007570404005591174451216846471710162760343
NOTE: You should add to the unit-tests with more results you've checked by hand, and also check any of my working here in interpreting the algebra as code to ensure this is correct.

How to find the highest and the lowest number C#

I get three values from three variables. How can i check who is the highest number and who is the lowest number?
The numbers are represented like this:
private int _score1;
private int _score2;
private int _score2;
Code:
Public int Highest
{
return the highest number here;
}
public int Lowest
{
return the lowest number here;
}
Can i calculate the highest and the lowest number in my constructor?
The obligatory Linq answer:
Public int Highest(params int[] inputs)
{
return inputs.Max();
}
public int Lowest(params int[] inputs)
{
return inputs.Min();
}
The beauty of this one is that it can take any number of integer inputs. To make it fail-safe you should check for a null/empty inputs array (meaning nothing was passed into the method).
To do this without Linq, you basically just have to mimic the logic performed by the extension method:
Public int Lowest(params int[] inputs)
{
int lowest = inputs[0];
foreach(var input in inputs)
if(input < lowest) lowest = input;
return lowest;
}
Again, to make it foolproof you should check for an empty or null inputs array, because calling Lowest() will throw an ArrayIndexOutOfBoundsException.
This is one way to do it:
public int Highest
{
get { return Math.Max(_score1, Math.Max(_score2, _score3)); }
}
public int Lowest
{
get { return Math.Min(_score1, Math.Min(_score2, _score3)); }
}
int[] numbers = new[] { _score1, _score2, _score3 };
int min = numbers.Min();
int max = numbers.Max();
Highest
return (x > y) ? (x > z ? x : z) : (y > z ? y : z)
Lowest
return (x < y) ? (x < z ? x : z) : (y < z ? y : z)
Here's something you could do:
public class Numbers
{
private int _number1;
private int _number2;
private int _number3;
public readonly int Highest;
public readonly int Lowest;
public Numbers(int num1, int num2, int num3)
{
int high;
int low;
_number1 = num1;
_number2 = num2;
_number3 = num3;
high = num1 > num2 ? num1 : num2;
high = high > num3 ? high : num3;
low = num1 < num2 ? num1 : num2;
low = low < num3 ? low : num3;
Highest = high;
Lowest = low;
}
}
If you want to simply check which is the highest you can do this
private int _highest = _score1;
if (_score2 > _highest)
_highest = _score2
if (_score3 > _highest)
_highest = _score3
Similarly, you can find the lowest like so
private int _lowest = _score1;
if (_score2 < _lowest)
_lowest = _score2
if (_score3 < _lowest)
_lowest = _score3
Using LINQ-to-Objects, you could do something like this.
var numbers = new [] {_score1, _score2, _score3};
numbers.Sort();
var lowest = numbers.First();
var highest = numbers.Last();
For a reference: in some cases you'll be having more than three variables (possibly not knowing how many). If they are stored in an array, here's the way to do it:
int Highest(int[] numbers)
{
int highest = Int32.MinValue();
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] > highest)
highest = numbers[i];
}
return highest;
}
int Lowest(int[] numbers)
{
int lowest = Int32.MaxValue();
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] < lowest)
lowest = numbers[i];
}
return lowest;
}
This will work for any length of int array.
Find the Largest and smallest number
using System;
namespace LargeSmall;
{
class Program
{
public static void Main()
{
float large, small;
int[] a = new int[50];
Console.WriteLine("Enter the size of Array");
int max = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the array elements");
for (int i = 0; i < max; i++)
{
string s1 = Console.ReadLine();
a[i] = Int32.Parse(s1);
}
Console.Write("");
large = a[0];
small = a[0];
for (int i = 1; i < max; i++)
{
if (a[i] > large)
large = a[i];
else if (a[i] < small)
small = a[i];
}
Console.WriteLine("Largest element in the array is {0}", large);
Console.WriteLine("Smallest element in the array is {0}", small);
}
}
Here is simple logic for finding Smallest Number
Input : 11, 0 , 3, 33 Output : "0"
namespace PurushLogics
{
class Purush_SmallestNumber
{
static void Main()
{
int count = 0;
Console.WriteLine("Enter Total Number of Integers\n");
count = int.Parse(Console.ReadLine());
int[] numbers = new int[count];
Console.WriteLine("Enter the numbers"); // Input 44, 55, 111, 2 Output = "2"
for (int temp = 0; temp < count; temp++)
{
numbers[temp] = int.Parse(Console.ReadLine());
}
int smallest = numbers[0];
for (int small = 1; small < numbers.Length; small++)
{
if (smallest > numbers[small])
{
smallest = numbers[small];
}
}
Console.WriteLine("Smallest Number is : \"{0}\"",smallest);
Console.ReadKey();
}
}
}

Sum of digits in C#

What's the fastest and easiest to read implementation of calculating the sum of digits?
I.e. Given the number: 17463 = 1 + 7 + 4 + 6 + 3 = 21
You could do it arithmetically, without using a string:
sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}
I use
int result = 17463.ToString().Sum(c => c - '0');
It uses only 1 line of code.
For integer numbers, Greg Hewgill has most of the answer, but forgets to account for the n < 0. The sum of the digits of -1234 should still be 10, not -10.
n = Math.Abs(n);
sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}
It the number is a floating point number, a different approach should be taken, and chaowman's solution will completely fail when it hits the decimal point.
public static int SumDigits(int value)
{
int sum = 0;
while (value != 0)
{
int rem;
value = Math.DivRem(value, 10, out rem);
sum += rem;
}
return sum;
}
int num = 12346;
int sum = 0;
for (int n = num; n > 0; sum += n % 10, n /= 10) ;
I like the chaowman's response, but would do one change
int result = 17463.ToString().Sum(c => Convert.ToInt32(c));
I'm not even sure the c - '0', syntax would work? (substracting two characters should give a character as a result I think?)
I think it's the most readable version (using of the word sum in combination with the lambda expression showing that you'll do it for every char). But indeed, I don't think it will be the fastest.
I thought I'd just post this for completion's sake:
If you need a recursive sum of digits, e.g: 17463 -> 1 + 7 + 4 + 6 + 3 = 21 -> 2 + 1 = 3
then the best solution would be
int result = input % 9;
return (result == 0 && input > 0) ? 9 : result;
int n = 17463; int sum = 0;
for (int i = n; i > 0; i = i / 10)
{
sum = sum + i % 10;
}
Console.WriteLine(sum);
Console.ReadLine();
I would suggest that the easiest to read implementation would be something like:
public int sum(int number)
{
int ret = 0;
foreach (char c in Math.Abs(number).ToString())
ret += c - '0';
return ret;
}
This works, and is quite easy to read. BTW: Convert.ToInt32('3') gives 51, not 3. Convert.ToInt32('3' - '0') gives 3.
I would assume that the fastest implementation is Greg Hewgill's arithmetric solution.
private static int getDigitSum(int ds)
{
int dssum = 0;
while (ds > 0)
{
dssum += ds % 10;
ds /= 10;
if (dssum > 9)
{
dssum -= 9;
}
}
return dssum;
}
This is to provide the sum of digits between 0-9
public static int SumDigits1(int n)
{
int sum = 0;
int rem;
while (n != 0)
{
n = Math.DivRem(n, 10, out rem);
sum += rem;
}
return sum;
}
public static int SumDigits2(int n)
{
int sum = 0;
int rem;
for (sum = 0; n != 0; sum += rem)
n = Math.DivRem(n, 10, out rem);
return sum;
}
public static int SumDigits3(int n)
{
int sum = 0;
while (n != 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
Complete code in: https://dotnetfiddle.net/lwKHyA
int j, k = 1234;
for(j=0;j+=k%10,k/=10;);
A while back, I had to find the digit sum of something. I used Muhammad Hasan Khan's code, however it kept returning the right number as a recurring decimal, i.e. when the digit sum was 4, i'd get 4.44444444444444 etc.
Hence I edited it, getting the digit sum correct each time with this code:
double a, n, sumD;
for (n = a; n > 0; sumD += n % 10, n /= 10);
int sumI = (int)Math.Floor(sumD);
where a is the number whose digit sum you want, n is a double used for this process, sumD is the digit sum in double and sumI is the digit sum in integer, so the correct digit sum.
static int SumOfDigits(int num)
{
string stringNum = num.ToString();
int sum = 0;
for (int i = 0; i < stringNum.Length; i++)
{
sum+= int.Parse(Convert.ToString(stringNum[i]));
}
return sum;
}
If one wants to perform specific operations like add odd numbers/even numbers only, add numbers with odd index/even index only, then following code suits best. In this example, I have added odd numbers from the input number.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Please Input number");
Console.WriteLine(GetSum(Console.ReadLine()));
}
public static int GetSum(string num){
int summ = 0;
for(int i=0; i < num.Length; i++){
int currentNum;
if(int.TryParse(num[i].ToString(),out currentNum)){
if(currentNum % 2 == 1){
summ += currentNum;
}
}
}
return summ;
}
}
The simplest and easiest way would be using loops to find sum of digits.
int sum = 0;
int n = 1234;
while(n > 0)
{
sum += n%10;
n /= 10;
}
#include <stdio.h>
int main (void) {
int sum = 0;
int n;
printf("Enter ir num ");
scanf("%i", &n);
while (n > 0) {
sum += n % 10;
n /= 10;
}
printf("Sum of digits is %i\n", sum);
return 0;
}
Surprised nobody considered the Substring method. Don't know whether its more efficient or not. For anyone who knows how to use this method, its quite intuitive for cases like this.
string number = "17463";
int sum = 0;
String singleDigit = "";
for (int i = 0; i < number.Length; i++)
{
singleDigit = number.Substring(i, 1);
sum = sum + int.Parse(singleDigit);
}
Console.WriteLine(sum);
Console.ReadLine();

Categories