I'm trying to calculate the number of possible combinations so I'm using some maths here (to be precise factorials). For example, if I have 50 numbers and I want to organize them into groups of 5, how many groups (combinations) are possible to make. I'm using this formula: allNumbers! / (allNumbers - PerGroup)!, but it comes up with an error for this particular example. It says that dividing by zero is forbidden. How can I manage this to work?
This is my code:
int b = 1;
int n = 1;
if (allNumbers - PerGroup == 0)
{
return 1;
}
else if (allNumbers - PerGroup == 1)
{
return allNumbers;
}
else
{
for (int i = 1; i <= allNumbers; i++)
{
b *= i;
}
for (int i = 1; i <= allNumbers - PerGroup; i++)
{
n *= i;
}
if (Enumerable.Range(1,int.MaxValue).Contains(b/n)) //line with ERROR!
{
return b/n;
}
else
{
return int.MaxValue;
}
}
Enumerable.Range(1,int.MaxValue).Contains(b/n) check doesn't check if the value is valid, because b/n is already computed and stored as int by this time.
You get division by zero because variable n is overflowed and becomes zero. In the following code you can see how overflow occurs.
using System;
public class Test
{
public static void Main()
{
int n = 1;
for (int i = 1; i <= 50; i++) {
n *= i;
Console.WriteLine("i = {0}, n = {1}", i, n);
}
}
}
Output:
i = 1, n = 1
i = 2, n = 2
i = 3, n = 6
i = 4, n = 24
i = 5, n = 120
i = 6, n = 720
i = 7, n = 5040
i = 8, n = 40320
i = 9, n = 362880
i = 10, n = 3628800
i = 11, n = 39916800
i = 12, n = 479001600
i = 13, n = 1932053504
i = 14, n = 1278945280
i = 15, n = 2004310016
i = 16, n = 2004189184
i = 17, n = -288522240
i = 18, n = -898433024
i = 19, n = 109641728
i = 20, n = -2102132736
i = 21, n = -1195114496
i = 22, n = -522715136
i = 23, n = 862453760
i = 24, n = -775946240
i = 25, n = 2076180480
i = 26, n = -1853882368
i = 27, n = 1484783616
i = 28, n = -1375731712
i = 29, n = -1241513984
i = 30, n = 1409286144
i = 31, n = 738197504
i = 32, n = -2147483648
i = 33, n = -2147483648
i = 34, n = 0
i = 35, n = 0
i = 36, n = 0
i = 37, n = 0
i = 38, n = 0
i = 39, n = 0
i = 40, n = 0
i = 41, n = 0
i = 42, n = 0
i = 43, n = 0
i = 44, n = 0
i = 45, n = 0
i = 46, n = 0
i = 47, n = 0
i = 48, n = 0
i = 49, n = 0
i = 50, n = 0
since allNumbers! always contains (allNumbers - PerGroup)!, why don't you exclude them from start.
int b = 1;
if (allNumbers - PerGroup == 0)
{
return 1;
}
else if (allNumbers - PerGroup == 1)
{
return allNumbers;
}
else
{
for (int i = (allNumbers - PerGroup + 1); i <= allNumbers; i++)
{
b *= i;
}
return b;
}
I guess the error is OutOfMemoryException because you are creating a huge amount of unnecessary integers. (Enumerable.Range(1,int.MaxValue)) note that each int takes 4 bytes from your memory.
Im not sure what you are trying to do there but you can use double type so if the number becomes very large it will just give you PositiveInfinity.
Or you can use checked to control integer overflow with try and catch.
Another way is to pre calculate the number when integer overflow happens. for example factorial of 14 will overflow for int and factorial of 22 will overflow for long.
Also you dont have to write for loop twice. you can use method for this purpose.
You dont need to check for allNumbers - PerGroup == 0 to prevent zero division. that wont happen because factorial of 0 is 1 and our factorial implementation returns 1 by its nature when the input is 0! (because the for loop never iterates in that case and the counter starts from 1.)
private static int Cominations(int allNumbers, int perGroup)
{
if(allNumbers > 13)
{
Console.WriteLine("Too big number!");
return -1;
}
return Factorial(allNumbers)/Factorial(allNumbers - perGroup);
}
private static int Factorial(int number)
{
int n = 1;
for (int i = 1; i < number; i++)
{
n *= i;
}
return n; // returns 1 when number is 0
}
If you want to calculate factorial of bigger numbers use BigInteger type from System.Numberics namespace.
using System.Numerics;
//...
private static BigInteger Factorial(int number)
{
BigInteger n = 1;
for (int i = 1; i < number; i++)
{
n *= i;
}
return n;
}
Related
the input is like this
100 5
0 10
0 5
75 95
12 17
13 14
and the output is 65
so i want the program to count which numbers from 0-100 are not in the array.
this is how i started
static void Main(string[] args)
{
string input1 = Console.ReadLine();
int roadlength = Convert.ToInt32(input1.Split(" ")[0]);
int stagecnt = Convert.ToInt32(input1.Split(" ")[1]);
int[] startpoint = new int[stagecnt];
int[] endpoint = new int[stagecnt];
int km = 0;
for (int i = 0; i < stagecnt; i++)
{
string input2 = Console.ReadLine();
startpoint[i] = Convert.ToInt32(input2.Split(' ')[0]);
endpoint[i] = Convert.ToInt32(input2.Split(' ')[1]);
}
for (int i = 0; i < stagecnt; i++)
{
Let's count distinct numbers that are in 0..100 range and then subtract from total number in 0..100 range:
using System.Linq;
...
int[] data = new int[] {
100, 5, 0, 10, 0, 5, 75, 95, 12, 17, 13, 14,
};
...
int min = 0;
int max = 100;
int result = max - min + 1 - data
.Where(item => item >= min && item <= max)
.Distinct()
.Count();
you are complicating the problem, it's very simple.
Initialize an array/list with the given range.
and check all your input items one by one whether they are present in the first carry. and if not present then just increment the count.
though complexity is high but its simplest solution.
int[] items = ;
int start = 1;
int end = 100;
int[] arr = Enumerable.Range(start, end - start).ToArray();
int count = 0;
for(int i = 0; i < arr.Length; i++)
{
if (!items.Contains(arr[i]))
{
count++;
}
}
If you want to count missing integers in your array, compared to all between 1 and 100:
int[] array = {1,2,3,4,5};
HashSet<int> allBetween1And100 = Enumerable.Range(1, 100).ToHashSet();
allBetween1And100.ExceptWith(array); // removes all from the set which are not in array
int countMissing = allBetween1And100.Count; // 95
The advantage of this approach is that you even have a collection with the missing. Of course this needs some memory, so if you don't need them, prefer a simple loop.
I want to display prime numbers through a button from a LISTBOX to a textbox . The Interface displays properly prime numbers but only from 1 to 10 , after that the algorithm changes and shows non prime values as prime values such as 44 .
private void primnr()
{
int n = listBox1.Items.Count;
bool prim = true;
for (int i = 2; i < n; i++)
{
for (int j = 2; j <n; j++)
{
if (i!=j && i%j==0)
{
prim = false;
break;
}
}
if (prim)
{
textBox2.Text = textBox2.Text + "Numar prim: " + listBox1.Items[i].ToString() + Environment.NewLine;
}
prim = true;
}
}
Your algorithm is good, despite it's not necessary for j to go further than half the value of i. https://dotnetfiddle.net/ZafFsb prints:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
So I would say your issue are the values stored in listBox1.Items[i], make sure Items[43] = 43? Attach a breakpoint and inspect the values.
Let's split the problem in two: generating prime numbers (logics), and displaying them to TextBox (UI):
private static IEnumerable<int> Primes() {
yield return 2;
yield return 3;
List<int> primes = new List<int>() {3};
for (int value = 5; ; value += 2) {
int n = (int) (Math.Sqrt(value) + 0.5); // round errors for perfect squares
foreach (int divisor in primes) {
if (divisor > n) {
primes.Add(value);
yield return value;
break;
}
else if (value % divisor == 0)
break;
}
}
}
Now, it seems you want to get items of the list with prime indexes, i.e.
listBox1.Items[2], listBox1.Items[3], listBox1.Items[5],..., listBox1.Items[101], ...
You can query Primes() with a help of Linq
using System.Linq;
...
var results = Primes()
.Take(index => index < listBox1.Count)
.Select(index => $"Numar prim: {listBox1.Ites[index]}");
// Time to Join results into a single string
textBox2.Text = string.Join(Environment.NewLine, results);
I know that's easy, but I don't understand how I should do it.
1 23 29 18 43 20 5
to
5 1 23 29 18 43 20
I think we should use for-loop:
for (int i = 0; i < numbers.Count - 1; i++)
{
}
but I don't know what to do in it. Something like numbers[i] = numbers[i - 1] but it isn't working. I think there are some if checks which I miss.
The most straightforward way that comes to mind is a reverse loop.
int[] numbers = { 1, 23, 29, 18, 43, 20, 5};
int lastVal = numbers[numbers.Length - 1];
for (int i = numbers.Length -1; i > 0; i--)
numbers[i] = numbers[i-1];
numbers[0] = lastVal;
Just looping from the end (after saving the last value) and moving "up" the values, finally replacing the first value with the last
Here's a oneliner:
var numbers = new[] {1, 23, 29, 18, 43, 20, 5};
numbers = new[] {numbers.Last()}.Concat(numbers.Take(numbers.Length - 1)).ToArray();
This creates a new array containing the last element, then concatenates it with the original array excluding the last element.
What you want to do is make another array of the same size as the original one, then assign the last element and loop through the array up to the previous to last element.
Something like this:
int[] original = {1, 23, 29, 18, 43, 20, 5};
int[] altered = new int[original.length];
altered[0] = original[original.length - 1];
for (int i = 1; i < original.length - 1; i++)
{
altered[i] = original[i - 1];
}
You can perform a left rotation to the table by six positions on your case and create the requested new table
int[] myArray = new int[] { 1, 23, 29, 18, 43, 20, 5 };
var newArray = LeftRotationByD(myArray, 6);
and your function for the rotation would be:
private static int[] LeftRotationByD(int[] a, int k)
{
int[] b = new int[a.Length];
int index;
int length = a.Length;
int place;
for (int i = 0; i < length; i++)
{
index = i - k;
place = length + index;
if (index >= 0) b[index] = a[i];
else b[place] = a[i];
}
return b;
}
You can use this method to shift right:
void ShiftRight(int[] array, int count)
{
var clone = (int[])array.Clone();
for (var i = 0; i < array.Length; i++)
array[(i + count) % array.Length] = clone[i];
}
And use it this way:
var a = new int[] { 1, 2, 3, 4 };
ShiftRight(a, 1);
I want to find the total number of digits divisible by 5 between 1 - 100, in C# windows form, how to proceed from here?
int sum;
private void button2_Click(object sender, EventArgs e)
{
int[] intarray = new int[100];
for (int i = 0; i < 99; i++)
{
intarray[i] = i + 1;
}
foreach (int a in intarray)
{
if (a / 5 == 0)
{
}
}
}
Note than a / 5 == 0 is wrong. For example 10 is divisible by 2, the result is 10/5 = 2, not equal to 0.
if (a % 5 == 0)
{
//then a is divisible by 5. print or store it
}
The modulus operator, also known as Remainder, returns the remainder of the integer division.
Therefore, the full answer:
int nInRange = 0;
foreach (int a in intarray)
if (a % 5 == 0)
nInRange++;
Maybe this is what you want.
public static IEnumerable<int> GetIntsDivisible(int start, int finish, int divisor)
{
for (var i = start; i <= finish; i++)
if (i % divisor == 0)
yield return i;
}
public static void Main()
{
Console.WriteLine(string.Join(", ", GetIntsDivisible(1, 100, 5)));
}
or if you don't want to yield
public static List<int> GetIntsDivisible(int start, int finish, int divisor)
{
var result = new List<int>();
for (var i = start; i <= finish; i++)
if (i % divisor == 0)
result.Add(i);
return result;
}
Output
5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100
Full demo here
Initialize a variable as 0
for e.g. Count = 0;
then add statement Count++ in your if block as follows:
if (a % 5 == 0)
{
Count++;
}
Since question is a bit vague in exact requirement, I will write the basic logic that can find the numbers exactly divisible by other number.
There is something called modulus (%) operator. It gives you the remainder of division.e.g. 11%5 will be 1, 13%5 will be 3, whereas 15%5 will be 0
so logic goes like,
for(int i=0;i<=100;i++)
{
if((i%5)==0)
{
\\this is ur number
}
}
Every one has address your question but no one talk about this weird attempt.
I really think you should take 5 minute and read your code because you are just running everywhere.
You should take the pen and paper before going head first into coding.
Here is a simple reading of your code so you understand what you were doing.
Line 1:
int[] intarray = new int[100];
So you start win an array, I guess it's for the result, right ? You will not be storing the number from 1 to 100 for no reason?
Line 2:
for (int i = 0; i < 99; i++)
Now we count from 0 to 98, I though it was form 1 to 100 .. Yes 98 as you are using < instead of <=
Line 3:
intarray[i] = i + 1;
Why ? 3rd line and you are already lost! You are filling the array with number you just iterate. It's like filling a bottle with water, then use it to fill an other bottle because you needed water.
If you iterate from 1 to 100 you could have check if it was divisible.
for (int i = 1; i <= 100; i++)
Line 4:
foreach (int a in intarray)
Again ? We are back counting from 1 to 100..
Line 5:
if (a / 5 == 0)
If this is suppose to tell you if it divisible thats wrong. The correct math operator is the Modulo. The division symbole won't give you the result you expect.
{1,2,3,4} will give you True. Anything else will be false.
int count = 0;
for (int i = 1; i <= 100; i++)
{
if ((i % 5) == 0)
{
count++;
textBox1.Text = count.ToString();
}
}
Alternatively,
int num = (100 + 5) / 5 - (1 + 5 - 1) / 5;
//Show result here
I have 2 one dimensional arrays, containing the exact same values:
public int[] start = new int[21] { 0, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14 };
public int[] end = new int[21] { 0, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14 };
Below is the code I use to generate a random index, and grab the element from the array with said index, and stick it in a 2D array, with randomly generated X and Y index.
for (int i = 0; i < 21; i++)
{
Random ranNum = new Random();
int genX = 0;
int genY = 5;
int indx = 1;
while (gameBoard[genX, genY].rank > -1)
{
genX = ranNum.Next(0, 9);
genY = ranNum.Next(5, 8);
}
while (start[indx] == -1)
{
indx = ranNum.Next(0, 21);
}
if (gameBoard[genX, genY].rank == -1)
{
gameBoard[genX, genY].rank = start[indx];
start[indx] = -1;
}
while (gameBoard[genX, genY].rank > -1)
{
genX = ranNum.Next(0, 9);
genY = ranNum.Next(0, 3);
}
while (end[indx] == -1)
{
indx = ranNum.Next(0, 21);
}
if (gameBoard[genX, genY].rank == -1)
{
gameBoard[genX, genY].rank = end[indx];
end[indx] = -1;
}
}
Basically, it takes a value from the "start" and "end" arrays, replaces them with a '-1' (so they don't get picked again), scans the 2D array for '-1s' (so it doesn't place the number in a location that already has one), and places it there.
Notice that the min and max value for the random are different for the "start" and "end" arrays. This is to ensure that they end up far away from each other, on the other side of the 2D array.
This code works. Now, I have a code that resets all the variables back to their previous state. A reset function which also works. See, if the user is not content with the random placement, they can reset the arrays, and randomize again.
At which point the program simply hangs / locks up. No error, no messages, it just stops working. Please, could you share any ideas on how / why this happens?
Note: If I remove the entire while loop concerning the "end" array, the program can randomize and reset all it wants.
Anyway, the code for the reset:
int resVal = 0;
for (int i = 0; i < 21; i++)
{
startBoard[i] = resVal;
enemyBoard[i] = resVal;
if (i == 0)
resVal++;
else if (i >= 6 && i < 19)
resVal++;
}
for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 9; x++)
{
gameBoard[x, y] = new classPiece();
gameBoard[x, y].rank = -1;
}
}
Move Random ranNum = new Random(); out of the cycle.