Different combinations of an array (C#) - c#

how can we find out different combination of the elements of an array using c# code.
are there any inbuilt library function for this.?
for eg: suppose an array has elements {2,3,4,5,6,7}
then the possible combination would be 2,3,4,5,6,7,2 3,2 3 4,2 3 4 5, etc
so basically wat i need is a function which gives different combination based on its input for eg: comb(array,2) gives output 2 3,1 2,3 4 and comb(array,3) gives output 1 2 3,2 3 4,3 4 5 and so on
Eg: valid comnbination for array= {1, 2, 3} and length = 2 are 1 2,1 3,2 3 .....

static void Main()
{
var cnk = comb(new [] {1,2,3},2);
foreach ( var c in cnk)
{
}
}
public static IEnumerable<int[]> comb(int[] a, int k)
{
if (a == null || a.Length == 0 || k < 1 || k > a.Length)
yield break;
int n = a.Length;
// 1
if ( k == 1)
for ( int i = 0; i < n; i++)
{
yield return new int[] {a[i]};
}
else
{
// k
for ( int i = 0; i < n - k + 1; i++)
{
var res = new int[k];
for (int t = i, c = 0; t < i + k - 1; t++, c++)
res[c] = a[t];
for (int j = i + k - 1; j < n; j++)
{
res[k-1] = a[j];
yield return res;
}
}
}
}
You should take the algorithm from here, my answer doesn't solve your problem
Algorithm to return all combinations of k elements from n

Seemed logic is not absolutely correct as:
var cnk = comb(new[] { 1, 2, 3, 4 }, 3);
This gives 3 variants, but as a matter of fact it is 4:
1 2 3
1 2 4
1 3 4
2 3 4
I guess comb is better to be implemented in recursive way.

Related

How to find all combinations of 30 integers within 0-1000

I am looking for a way to find all combinations of a 30 numbers in numbersArray which has numbers between 0-1000.
For example 1st combination is: 0,1,2,3,4,5,6......29,30
For example 2nd combination is: 0,2,3,4,5,6,7......30,31
For example 2rd combination is: 0,3,4,5,6,7,8......31,32
Then continue to find all combinations. Any number must only appear once in the series of 30 numbers.
The very important detail here is if it is possible while create those combinations, then use them straight away. With other words, not storing the combinations first and then iterating through them again. Which would mean double amount of iterations?
Thank you!
void findcombinations()
{
//Declaring the array with 1000 indexes
//The number of indexes can be up to 100,000 indexes
int[] numbersArray = new int[1000];
for (int i = 0; i < numbersArray.Length; i++)
{
numbersArray[i] = i; //Assign number from 0-1000
}
//How to find all combinations of 30 numbers between: 0-1000?
//For example 1st combination is: 0,1,2,3,5,6,7......29,30
//For example 2nd combination is: 0,2,3,5,6,7,8......30,31
//For example 2rd combination is: 0,3,5,6,7,8,9......31,32
//How to dynamically find all combinations of a group of 30 numbers between 0-1000?
//Not perheps exactly use the below approach because that would mean that we already have filled the
//Array with the combinations.
//I am trying to see if there is a dynamic approach where the combinations are produced right away so
//They can be used straight away as they are produced?
int[,] allCombinations = new int[???,30]; ///??? How many combinations of 30 numbers
for (int i = 0; i < allCombinations.Length; i++)
{
for (int i2 = 0; i2 < allCombinations.GetLength(i); i2++)
{
//Do something with the combination of numbers here
}
}
}
Here you have the solution:
using System;
using System.Collections.Generic;
namespace combinatory
{
public class Combinations
{
private readonly int n;
private readonly int k;
private readonly int[] combination;
public Combinations(int n, int k)
{
if (n <= 0) throw new ArgumentException("n argument must be greater than 0", nameof(n));
if (k <= 0) throw new ArgumentException("k argument must be greater than 0", nameof(k));
if (n < k) throw new ArgumentException("k argument must be greater or equals to n", nameof(k));
this.n = n;
this.k = k;
combination = new int[k];
for (int i = 0; i < k; i++)
{
combination[i] = i;
}
}
public IEnumerable<int[]> Get()
{
yield return combination;
while (TrySetNextCombination())
{
yield return combination;
}
}
private bool TrySetNextCombination()
{
int incrementableIndex = findFirstIncrementableIndex();
if (incrementableIndex < 0) return false;
var value = combination[incrementableIndex];
for (int i = incrementableIndex; i < k; i++)
{
combination[i] = ++value;
}
return true;
}
private int findFirstIncrementableIndex()
{
int index = k - 1;
int threshold = n - 1;
while (index >= 0)
{
if (combination[index] < threshold) return index;
index--;
threshold--;
}
return index;
}
}
}
The class Combinations has a constructor that takes n and k arguments. n is the number of elements in the set, k is the number of elements in the subset. It has the Get method, it enumerates all combinations. It is very memory efficient because it just need an array of k integers. The key point is to initialize the first combination and then calculate the next one.
This is how you can use it:
using System;
namespace combinatory
{
class Program
{
static void Main(string[] args)
{
var combinations = new Combinations(6, 3);
foreach (var comb in combinations.Get())
{
foreach (var v in comb)
{
Console.Write(" ");
Console.Write(v);
}
Console.WriteLine();
}
}
}
}
This is the output:
0 1 2
0 1 3
0 1 4
0 1 5
0 2 3
0 2 4
0 2 5
0 3 4
0 3 5
0 4 5
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
In fact, if you want just the number of combinations, there's a mathematical compution for this:
n! / (p! . (n - p)!)
Where n is the total number count (1000), and p is de picked count (30).
Source: https://en.m.wikipedia.org/wiki/Combination

C++ vector vs C# List. Why are they producing different results?

I'm translating some code from C++ to C#. The code is simple enough and most of the syntax involved is almost the same, however the C++ version uses a vector<vector<int>> structure that doesn't exists in C#, so I replaced it with a List<List<int>> which I initialized with empty "rows" since I need it to represent a table with a fixed number of rows (See the code below).
The logic is exactly the same but somehow i'm not getting the same outputs. I suspect it has to do with the behaviour of List<List<int>> but I'm not sure. Any hints would be appreciated.
This is the original C++ code:
void LIS(int arr[], int n)
{
vector<vector<int>> L(n);
L[0].push_back(arr[0]);
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if ((arr[i] > arr[j]) && (L[i].size() < L[j].size() + 1)){
L[i] = L[j];
}
}
L[i].push_back(arr[i]);
}
vector<int> max = L[0];
for (vector<int> x : L)
if (x.size() > max.size())
max = x;
for(int e : max){
cout<<e<<endl;
}
}
This is my C# version:
public static void LIS(int[] arr, int n)
{
// Here I replace the vector<vector<int>> with a List<List<int>>
// and I fill it with n empty lists.
List<List<int>> L = new List<List<int>>();
for(int x = 0; x < n; x++)
{
L.Add(new List<int>());
}
L[0].Add(arr[0]);
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if ((arr[i] > arr[j]) && (L[i].Count < L[j].Count + 1))
{
L[i] = L[j];
}
}
L[i].Add(arr[i]);
}
List<int> max = L[0];
foreach (List<int> x in L)
{
if (x.Count > max.Count)
{
max = new List<int>(x);
}
}
foreach(int e in max){
Console.WriteLine(e);
}
I'm testing with this array:
int[] arr = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
int n = arr.Length;
In the C++ version I get:
0 2 6 9 11 15
and in the C# version I get:
0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
In the C++ code doesn't L[i] = L[j]; make a copy of the vector at L[j] and store it in L[i] (similar thing for the variable max)? To achieve a similar result in C#, you could do L[i] = L[j].ToList() to copy the list.

Find Maximum difference between two numbers in list using Bitwise AND

Hi all i am solving a problem that says :
Given a set S = {1, 2, 3, ... N}. Find two integers A and B where (A < B), from set S such that the value of A&B, where '&' is bitwise AND, is the maximum possible number less than a given integer K.
Sample Input1 : 5 2, (where n = 5, k = 2) => Output : 1,
Sample Input2 : 8 5, (where n = 8, k = 5) => Output : 4
I wrote the code and this seems to be working fine. But I am looking for more optimized solution. I am currently using two while loops, which I am not sure could be reduced to one single while or for loop. Below is my function :
static void Main(String[] args)
{
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
int i = 1, maxDiff = 0;
while (i < n)
{
int j = i + 1;
while (j <= n)
{
int diff = i & j;
if (diff < k)
{
if (diff > maxDiff)
{
maxDiff = diff;
}
}
j++;
}
i++;
}
Console.WriteLine(maxDiff);
}
I found a solution here but that problem seems to be about finding maximum difference in two arbitrary numbers in a list, whereas i need to loop for all the combinations to find the Bitwise AND value and then compare it.
int maxAnd = INT_MIN;
for(int i = 1; i < k; i++) {
for(int j = i + 1; j <= n; j++) {
int currentAnd = i & j;
if (currentAnd > maxAnd)
maxAnd = currentAnd;
}
}
cout << maxAnd << endl;
This might be not more optimized from efficiency perspective, but somewhat more readable.
var list = new[] {1, 2, 3, 4, 5};
var k = 2;
var combinations =
from item1 in list
from item2 in list
where
(item1 < item2) &&
(item1 & item2) < k
orderby item1 & item2 descending
select new {item1, item2};
Console
.WriteLine(combinations.First());
Turns out the solution can be drastically simplified (in terms of what we check, rather than readability). So, rather than providing ways to improve the code - I can offer a new solution to the original requirement
void Main()
{
var n = 2;
var k = 2;
//Best solution is for k - 1 (that is, B = k - 1, and then we check all possible As)
for (var i = k - 1; i > 0; i--)
{
int j;
int index = 1;
//The only possible A is when
//1. j <= n
//2. j contains all the same bits as i since we identify that `i` is the possible solution,
// and we are using bit-wise AND, we
//So, here were looping while the number is the same as i, continually flipping bits on
//Since we're shifting bits in, we can assume the first value != i is a solution, as we only care about j becoming too large
while ((j = (i | index)) == i && j <= n)
index = (index << 1) | 1;
// If j <= n, and it contains all the bits of i, and i <= k - 1, then we have a solution
if (j <= n)
{
Console.WriteLine($"i = {i}, j = {j}, Solution = {i & j}");
return;
}
}
if (n < 2 || k < 1)
Console.WriteLine("No solution");
else
Console.WriteLine($"i = 1, j = 2, Solution = 0");
}
This approach lets us solve inputs such as:
var n = 24827492;
var k = 2384972;
Almost as quickly as we can for low values.

Numbers cube, each row rotated to left by one

Basic C# question:
I need to have that result when entering some number (this case was entered 4):
4 3 2 1 0
3 2 1 0 4
2 1 0 4 3
1 0 4 3 2
I was trying that code, but cant figure out my mistake:
Console.WriteLine("Please write a Number: ");
Console.Write("Number: ");
int num = int.Parse(Console.ReadLine());
for (int i = 0; i <= num; i++)
{
for (int j = num - i; j >= 0; j--)
{
Console.Write(j);
}
for (int j = 1; j <= i; j++)
{
Console.Write(j);
}
Console.WriteLine();
}
Console.ReadLine();
This is the output I get:
4 3 2 1 0
3 2 1 0 1
2 1 0 1 2
1 0 1 2 3
0 1 2 3 4
Try this:
Console.WriteLine("Please write a Number: ");
Console.Write("Number: ");
int num = int.Parse(Console.ReadLine());
for (int i = 0; i <= num; i++)
{
for (int j = num - i; j >= 0; j--)
{
Console.Write(j);
}
for (int j = num; j > num - i; j--)
{
Console.Write(j);
}
Console.WriteLine();
}
Console.ReadLine();
The problem is that your second inner loop is starting at one and counting up rather than starting from num and counting down.
Change that loop to:
for (int j = num; j > num -i; j--)
{
Console.Write(j);
}
Also I'm not clear if you want the last line of 04321 or not. If you don't (as in the original example) then just change your loop check to i<num.
Try something like this
get a number(x) from user.
create a list of integer containing x to 0.
run a loop for x times.
every time print the list and pop the first number and push it at the end
var ints = new List<int> { 4, 3, 2, 1, 0 };
for (int i = 0; i < 4; i++)
{
ints.ForEach(n => Console.Write(n + " "));
Console.WriteLine("");
var a = ints[0];
ints.RemoveAt(0);
ints.Add(a);
}
As a hint I give you the main loop as a pseudo code:
for i from 0 to number_input-1 {
for j from number_input to 0 {
print((j-i)%(number_input+1) + " ")
}
print("\n")
}
Just for fun:
const int NUM = 4; // num from user
for (int start = NUM; start > 0; start--)
{
for (int i = 0; i <= NUM; i++)
{
int current = (start - i) >= 0 ? start - i : NUM + (start - i) + 1;
Console.Write(current + " ");
}
Console.WriteLine();
}
Honestly this is a classic sorting task. it's just hidden beyond "user types and bla bla bla" but I remember at school it was..
There is an array [4,3,2,1,0].. so
we swap 1 and 2 and get [3,4,2,1,0].
we swap 2 and 3 and get [3,2,4,1,0].
we swap 3 and 4 and get [3,2,1,4,0].
we swap 4 and 5 and get [3,2,1,0,4].
so just simple code
int[] numbers let say you have this array [4,3,2,1,0]
for(int i = 0; i < numbers.length - 2; i++){
for(int y = 0; y < numbers.length - 1; y++){
int buf = numbers[y];
numbers[y] = numbers[y + 1];
numbers[y + 1] = buf;
}
}

How can I calculate the number at a given row and column in Pascal's Triangle?

I'm trying to create a function that, given a row and column, will calculate the value at that position in Pascal's Triangle.
Example:
val = GetPasVal(3, 2); // returns 2
So here I'm specifying row 3, column 2, which as you can see:
1
1 1
1 2 1
...should be a 2.
The Pascal's triangle contains the Binomial Coefficients C(n,k);
There is a very convenient recursive formula
C(n, k) = C(n-1, k-1) + C(n-1, k)
You can use this formula to calculate the Binomial coefficients.
Using Armen's equation the recursive code for implementing pascals triangle will be like below:
using System;
using System.Collections.Generic;
public class Program
{
public void Main()
{
for(int i =0 ; i<5;i++)
{
int sum = 1;
Console.WriteLine();
for(int j =0 ; j<=i;j++)
{
Console.Write(pascal(i,j));
//Console.Write(sum); //print without recursion
sum= sum *(i-j) / (j + 1);
}
}
}
public int pascal(int x, int y)
{
if((x+1)==1 || (y+1)==1 || x==y)
{
return 1;
}
else
{
return pascal(x-1,y-1)+ pascal(x-1,y);
}
}
}
There is a formula from Combinations for working out the value at any place in Pascal's triangle:
It is commonly called n choose k and written like this:
n choose k = n! / k!(n-k)!
Notation: n choose k can also be written C(n,k), nCk.
static void Main(string[] args)
{
var x = GetPasVal(3, 2);
Console.WriteLine(x);
}
public static long GetPasVal(int row, int col)
{
int factOfRow = 1,i;
for(i = 1;i<=(row - 1);i++)
factOfRow *= i;
int factOfRowMinusCol = 1;
for(i = 1;i<=(row - 1)- (col - 1);i++)//check out below link to understand condition
factOfRowMinusCol *= i;
int factOfCol = 1;
for(i = 1;i<= (col - 1);i++)
factOfCol *=i;
int fact = factOfRow / (factOfCol * factOfRowMinusCol);
return fact;
}
https://www.mathsisfun.com/pascals-triangle.html
for row in range(10):
print('{: ^45}'.format(' '.join(str(pascal(row, col)) for col in range(row+1))))
Use the above code to print out your pascal triangle and thereby modify the code. The first 10 should look like:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
The GetPasVal method will calculate all the numbers in the Pascal's Triangle up to the point that you will give (height) and after that the method will return the value of the index on that row(width). This is something you can use. It's quite simple. You just have to use a jagged array.
static void Main(string[] args)
{
var x = GetPasVal(3, 2);
Console.WriteLine(x);
}
public static long GetPasVal(int height, int width)
{
long[][] triangle = new long[height][];
for (int i = 0; i < height; i++)
{
triangle[i] = new long[i + 1];
triangle[i][0] = 1;
triangle[i][i] = 1;
if (i >= 2)
{
for (int j = 1; j < i; j++)
{
triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j];
}
}
}
return triangle[height - 1][width - 1];
}

Categories