i have two numbers 1,2 in one array.Now i want to generate all the possible combinations of arrays(of size=5) like
1,2,0,0,0 ||
2,1,0,0,0 ||
1,0,2,0,0
.
.
.
.
.
I tried to write a recursive function but its not working
Now I want to solve this using LINQ because the code will be considerably small.
Please help me
LINQ is excellent for searching; it's much worse at generating, so it is a wrong tool for the job. So is recursion (although it is a better choice than LINQ). What you need is two nested loops, like this:
var elements = new [] {1, 2};
for (var i = 0 ; i != 5 ; i++) {
for (int j = 0 ; j != 5 ; j++) {
if (i == j) continue;
var data = new int[5];
data[i] = elements[0];
data[j] = elements[1];
ProcessCombination(data);
}
}
Here is what the code does: at each iteration of the inner loop it places the first and the second element from the elements array at distinct positions i and j. Nested loops go from 0 to 5, making sure all position combinations are covered.
You could use something like this:
public static IEnumerable<IEnumerable<T>> Permute<T>(IEnumerable<T> list)
{
if (list.Count() == 1)
return new List<IEnumerable<T>> { list };
return list.Select((a, i1) => Permute(
list.Where((b, i2) => i2 != i1)).Select(
b => (new List<T> { a }).Union(b))
).SelectMany(c => c);
};
.....
var result = Permute(new int[]{1,2,0,0,0});
Related
I have a list with four double values in it
var numbers2 = new List<double>() { 2, 3, 9, 7 };
I need to get lower value between the first 2 indexes (2 and 3).
Similarly I need to get lower value between index 3 and 4 (9 and 7)
Is there a way in C sharp to determine this using LINQ?
Once I have the lower value from above list i.e 2 and 7; I need to pass these values in the below loop
for (int i = 0; i < 1; i++)
{
dac[i] = SetValue(lowerValue[j]);
}
if i == 0, I want lowerValue[j] = 2. If i == 1, I want lowerValue[j] = 7
Well as others have pointed out, it doesn't seem like there's any reason to use linq. But if you absolutely had to find some way to do it, then it's possible. I'll throw 3 options out, the last one being linq.
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var numbers2 = new List<double>() { 2, 3, 9, 7 };
// you stated it's always 4 values. There's no reason to use linq. The optimal solution would
// be a variation of this (with some constant values instead of magic numbers)..
var first = Math.Min(numbers2[0],numbers2[1]);
var second = Math.Min(numbers2[2],numbers2[3]);
Console.WriteLine($"Lower values: {first},{second}");
// if it was an arbitry sized list (but always even count) you could use a iterator method
var listOfLowerValues = ToPairs(numbers2);
var values = string.Join(",", listOfLowerValues.Select(x => x.ToString()));
Console.WriteLine($"Lower values: {values}");
// finally if you absolutely had too, you can make it even more inefficient
// by using linq.
var indexes = Enumerable.Range(0, numbers2.Count);
var indexed = numbers2.Zip(indexes, (n,i) => (index: i, num: n));
var odd = indexed.Where(x => x.index%2 == 0).Select(x => x.num).ToArray();
var even = indexed.Where(x => x.index%2 > 0).Select(x => x.num).ToArray();
var lower = even.Zip(odd,(v1,v2)=> v1 < v2 ? v1 : v2);
var valuesByLinq = string.Join(",",lower.Select(x => x.ToString()));
Console.WriteLine($"Lower values: {valuesByLinq}");
}
static IEnumerable<double> ToPairs(IEnumerable<double> source)
{
int index = 0;
double previous = 0;
foreach(var n in source)
{
if(index++%2 > 0)
{
yield return (previous < n) ? previous : n;
}
else
{
previous = n;
}
}
}
}
Assume that I have a list of items from 1 - 3.
I could order them by 1,1,2,2,3,3.
But instead, I would like to order them by 1,2,3,1,2,3....
Is there an already exist function to achieve that?
This approach separates each number into groups, then iterates through the groups in order while conditionally adding them to a result list. There's probably ways to make this safer and more efficient, but this should give you a start. (It assumes that if there aren't equal counts of each number in the source array, it will skip those numbers as it runs out of them during the iteration phase.)
int[] arr = new[] { 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5 };
var orderList = arr.OrderBy(x => x).Distinct().ToArray();
var refList = arr.GroupBy(x => x).ToDictionary(k => k.Key, v => v.Count());
var result = new List<int>();
int i = 0;
while (result.Count < arr.Length)
{
if (refList.Values.Sum() == 0)
break;
if (refList[orderList[i]] > 0)
{
result.Add(orderList[i]);
refList[orderList[i]]--;
}
i++;
if (i >= orderList.Length)
i = 0;
}
// Result: [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
How to determine a range in a list of integer follow specific pattern.
For example, we have a list like this:
List<int> ints = new List<int>(){4,5,2,6,8,4,5,6,5,6,8,9,9};
Exists and Any could check if an element satisfies specific condition.
But what if I want to know if there is any three items in row that incremental values(plus 1): here they are {4, 5, 6}.
Patrick already answered your question with a good solution, but if you're really looking for a LINQ-only way, you could use Aggregate:
var inputs = new List<IEnumerable<int>>
{
new List<int>{ 4,5,2,6,8,4,5,6,5,6,8,9,9 },
new List<int>{ 1,2,3 },
new List<int>{ 1,2,4 },
};
foreach(var input in inputs)
{
var result = input.Aggregate(Enumerable.Empty<int>(),
(agg, cur) => agg.Count() == 3 ? agg
: agg.Any() && cur == agg.Last() + 1
? agg.Concat(new []{cur})
: new []{cur});
Console.WriteLine(result.Count() >= 3 ? String.Join(", ", result) : "not found");
}
Another way is to take all of the groups of 3 and then see which group(s) meet your n, n+1 and n+2 rule
var results = Enumerable.Range(0, ints.Count - 3)
.Select(n => ints.Skip(n).Take(3).ToArray())
.Where(three => three[0]+1 == three[1] && three[0]+2 == three[2])
.ToArray();
I would drop the LINQ requirement. It is very hard, maybe even impossible. A regular foreach statement is better suited for this:
List<int> sequence = new List<int>();
List<int> longestSequence = null;
int previous = 0;
foreach (int i in ints)
{
if (i != previous + 1 && sequence.Count > 0)
{
if (longestSequence == null || longestSequence.Count < sequence.Count)
{
longestSequence = sequence;
}
sequence = new List<int>();
}
sequence.Add(i);
previous = i;
}
I'm new to C# and have searched for this everywhere but could not find answer so excuse if already asked. I am trying to use a for loop to compare 2 Lists:
IList<string> List1 = new List<string> { usr.User1, usr.User2, usr.User3, usr.User4 };
IList<string> List2 = new List<string>{ "Tim", "Bob", "Brian", "Paul" };
Basically I would like there to only be 4 possible matches, so only these possible matches should count:
usr.User1 == "Tim", // e.g. User1 has to be Tim etc.
usr.User2 == "Bob",
usr.User3 == "Brian",
usr.User4 == "Paul"
I would ideally like it to return an int with a value from 0-4, so if all of the matches above were successful then it would return 4, if no matches successful then returns 0 etc.
I have tried:
int score = 0;
for (int i = 0; i <= List2.Count; i++)
{
if (List1[i] == List2[i])
{
score++;
}
}
But currently getting IndexOutOfRangeException. Many thanks.
Drop the =, you want to stop short of the upper bound.
for (int i = 0; i < List2.Count; i++)
The other option is to use zip linq:
int score = List1.Zip(List2, (a,b) => a == b ? 1 : 0).Sum();
Lose the = it should be for (int i = 0; i < List2.Count; i++).
There are probably better ways of doing this though.
Since List2 has 4 elements, List2.Count would be eqal to 4.
When you make the i <= List2.Count statement in the for loop, your are allowing the loop to indexes 0-4 because Lists are 0 index base and when the loop gets to index 4, an IndexOutOfRangeException exception would be thrown.
The solution would be to change the <= statement in the for loop to <.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Combination of List<List<int>>
I have multiple Lists, could be 2 or 3 up to 10 lists, with multiple
values in them. Now what I need to do is to get a combination of all
of them.
For example, if I have 3 lists with the following values:
List 1: 3, 5, 7
List 2: 3, 5, 6
List 3: 2, 9
I would get these combinations
3,3,2
3,3,9
3,5,2
Etc..
Now the problem is I cannot do this easily because I do not know how many lists I have, therefore determine how many loops I need.
You could probably make that a lot easier, but this is what I had in mind just now:
List<List<int>> lists = new List<List<int>>();
lists.Add(new List<int>(new int[] { 3, 5, 7 }));
lists.Add(new List<int>(new int[] { 3, 5, 6 }));
lists.Add(new List<int>(new int[] { 2, 9 }));
int listCount = lists.Count;
List<int> indexes = new List<int>();
for (int i = 0; i < listCount; i++)
indexes.Add(0);
while (true)
{
// construct values
int[] values = new int[listCount];
for (int i = 0; i < listCount; i++)
values[i] = lists[i][indexes[i]];
Console.WriteLine(string.Join(" ", values));
// increment indexes
int incrementIndex = listCount - 1;
while (incrementIndex >= 0 && ++indexes[incrementIndex] >= lists[incrementIndex].Count)
{
indexes[incrementIndex] = 0;
incrementIndex--;
}
// break condition
if (incrementIndex < 0)
break;
}
If I’m not completely wrong, this should be O(Nm) with m being the number of lists and N the number of permutations (product of the lengths of all m lists).
you could make a List<List<yourValueType> mainlist in which you put all your lists.
then with a simple
int numberOfIterations = 1;
foreach(var item in mainlist)
{
numberOfIterations *= item.Count;
}
this would get the amount of iterations you would have to execute in total.
Non-recursive solution, works on any IEnumerables (not just lists) without solidifying them:
public static IEnumerable<IEnumerable<T>> Permutations<T>(
this IEnumerable<IEnumerable<T>> source)
{
// Check source non-null, non-empty?
var enumerables = source.ToArray();
Stack<IEnumerator<T>> fe = new Stack<IEnumerator<T>>();
fe.Push(enumerables[0].GetEnumerator());
while (fe.Count > 0)
{
if (fe.Peek().MoveNext())
{
if (fe.Count == enumerables.Length)
yield return new Stack<T>(fe.Select(e => e.Current));
else
fe.Push(enumerables[fe.Count].GetEnumerator());
}
else
{
fe.Pop().Dispose();
}
}
}
Not very efficient but very easy to understand approach might be to solve this task recursively. Consider a method which computes permutations for N lists. If you have such a method then you can easily compute permutations for N+1 lists by combining all permutation of N lists with every number in the last list. You should also handle corner case which permutations of 0 lists. Then implementation seems to be straightforward:
IEnumerable<IEnumerable<T>> GetAllPermutations<T>(IEnumerable<IEnumerable<T>> inputLists)
{
if (!inputLists.Any()) return new [] { Enumerable.Empty<T>() };
else
{
foreach (var perm in GetAllPermutations(inputLists.Skip(1)))
foreach (var x in inputLists.First())
yield return new[]{x}.Concat(perm);
}
}
As an alternative, following rawlings general idea the following should work
public static IEnumerable<IEnumerable<T>> Permutations<T> (this IEnumerable<IEnumerable<T>> underlying)
{
var enumerators = new Queue<IEnumerator<T>>(underlying.Select(u => u.GetEnumerator())
.Where(enumerator => enumerator.MoveNext());
Boolean streaming = enumerators.Any();
if(streaming)
{
IEnumerable<T> result;
IEnumerator<T> finalEnumerator = enumerators.Dequeue();
Func<Boolean,Boolean> finalAction = b => b ? b : finalEnumerator.MoveNext();
Func<Boolean,Boolean> interimAction =
enumerators.Reverse()
.Select(enumerator => new Func<Boolean,Boolean>(b => b ? b : (enumerator.MoveNext() ? true : enumerator.ResetMove())))
.Aggregate((f1,f2) => (b => f1(f2(b)));
enumerators.Enqueue(finalEnumerator);
Func<Boolean,Boolean> permutationAction =
interimAction == null ?
finalAction :
b => finalAction(interimAction(b));
while(streaming)
{
result = new Queue<T>(enumerators.Select(enumerator => enumerator.Current))
streaming = permutationAction(true);
yield return result;
}
}
private static Boolean ResetMove<T>(this IEnumerator<T> underlying)
{
underlying.Reset();
underlying.MoveNext();
return false;
}