using linq to find 2 values in a row - c#

Is it easier to use linq to do the same thing as this code? (check and see how many values are equal to the value following):
int[] values = {1,2,3,3,5,6,7};
int counter=0;
for (int f =0; f< values.Length-1; f++)
{
if(values[f]==values[f+1])
{
counter++;
}
}

Yes, you can do this quite easily with Zip in .NET 4:
var count = values.Zip(values.Skip(1), (x, y) => new { x, y })
.Count(pair => pair.x == pair.y);
The trick of combining Zip and Skip(1) takes a little bit of getting your head round, but it's a really neat one. Basically you start with a sequence of n values, and the result is a sequence of n - 1 pairs, each of which contains a value and its successor.
From there, it's just a matter of counting the pairs which are the same :)
Note that the sequence in question will be evaluated twice, so you wouldn't want to do this for anything which was lazily evaluated, or which wouldn't give the same results when evaluated twice.

No I don't think it's easier. The code you have is easy to understand and concise, I wouldn't refactor it with linq. Make sure you test it a bit more though, as you might get an out of bounds error on the last loop.

There exists a very neat solution:
var list = new[] { 1, 2, 3, 3, 5, 6, 7, 7 };
var pairs = SeqModule.Pairwise(list);
var count = pairs.Count(p => p.Item1 == p.Item2);
This requires that you reference the assembly FSharp.Core and you use using Microsoft.FSharp.Collections;. Alternatively, you can implement the Pairwise method as a extension method and thereby avoid using another assembly.
For anyone who might be interested in F#, here is a solution:
let lst = [1;2;3;3;5;6;7;7]
let count = lst |> Seq.pairwise
|> Seq.filter (fun (x, y) -> x = y)
|> Seq.length

Try this:
var set = values.Where((value, i) => i < (values.Length - 1) ? values[i] == values[i + 1] : false);
EDIT:
Sorry, forgot to add set.Count() to get the result :-)

Given that the values are in an array, you can do this:
int duplicates = values.Skip(1).Where((n, i) => n == values[i]).Count();

You could say something like:
private static int CountDoubles( IEnumerable<int> Xs )
{
int? prev = null ;
int count = Xs.Count( curr => {
bool isMatch = prev.HasValue && prev == curr ;
prev = curr ;
return isMatch ;
} ) ;
return count ;
}
but that's neither simpler nor cleaner than your original version. I'd tweak yours slightly, though::
public static int CountDoubles( int[] Xs )
{
int n = 0 ;
for ( int i = 1 ; i < Xs.Length ; ++i )
{
n += ( Xs[i-1] == Xs[i] ? 1 : 0 ) ;
}
return n ;
}

Related

How to list all possible combinations of a N value set, where each value is from a fixed subset of values using C#?

if there are N values, each value can be drawn from a sub-set of values, say (1,2,3) for example, then how to derive the possible combinations? note that each one will contain N values, not the subsets.
for example, let's say N = 4, the possible outputs could be:
1,1,1,1
1,2,1,3
2,1,1,3
...
If you have M different values and want to generate N-element combinations, consider these combinations as N-digit numbers in M-ary numeral system. There are M^N such combinations. Pseudocode:
for i = 0 to Power(M, N) - 1 do
represent i in M-ary system:
tmp = i
for k = 0 to N - 1 do
digit[k] = tmp % M //integer modulo
tmp = tmp / M //integer division
Example: if N = 3, M = 3, there are 27 combinations , and at 11-th step we have
11(dec) = 102 (trinary), combination is (1,0,2) if set is zero-based, or (2,1,3) if it is 1-based
This is another solution, using a static utility class:
static class SequencesCalculation
{
public static List<int[]> Calculate(int[] availableValues, int digitsCount)
{
var combIndexes = CalculateRecursive(new List<int[]>(), availableValues.Length, new int[digitsCount], digitsCount - 1);
var result = combIndexes.Select(x => x.Select(i => availableValues[i]).ToArray()).ToList();
return result;
}
static List<int[]> CalculateRecursive(List<int[]> doneCombinations, int valuesCount, int[] array, int i)
{
doneCombinations.Add((int[])array.Clone());
//base case
if (array.All(x => x == valuesCount - 1))
return doneCombinations;
NextCombination(array, valuesCount, i);
return CalculateRecursive(doneCombinations, valuesCount, array, i);
}
static void NextCombination(int[] array, int valuesCount, int i)
{
array[i] = (array[i] + 1) % valuesCount;
if (i == 0)
return;
if (array[i] == 0)
NextCombination(array, valuesCount, i - 1);
}
}
I think the #MBo solution is far more elegant than mine. I don't know which is faster. His solution has lot of arithmetic divisions, but mine has much stack allocation forward and backward because of all the recursive method calls.
Anyway, I think that his solution should be checked as the correct answer.

Fast/efficient way to get index of minimum value in List<T>?

Is there any way to find minimum value index more efficient/faster than this?
int minimumValueIndex = List.IndexOf(List.Min());
Yes, you can remove the overhead of List.IndexOf() by building a custom Min() extension. (Really, Enumerable.Min() should have an extension that selects the original element by key instead of selecting a transformation. This oversight is particularly painful in situations like this.)
public static int IndexOfMin(this IList<int> self)
{
if (self == null) {
throw new ArgumentNullException("self");
}
if (self.Count == 0) {
throw new ArgumentException("List is empty.", "self");
}
int min = self[0];
int minIndex = 0;
for (int i = 1; i < self.Count; ++i) {
if (self[i] < min) {
min = self[i];
minIndex = i;
}
}
return minIndex;
}
In my own experience the LINQ aggregation methods such as Array.Max() and Array.Min() are typically slower than a manual for loop. So, you can consider something like this as an alternative approach:
int minima=0;
int mindex=0;
for(int i=0;i<List.Count;i++)
{
if (List[i]<minima)
{minima=List[i]; mindex=i;}
}
You can always test the speeds of both approaches on your environment by using System.Diagnostics.StopWatch.
At present .NET supports value tuples which allows trivial solution:
var index = List.Select((item, index) => (item, index)).Max().index;
There's a problem with answer posted by #cdhowie in that it assumes that an IList<T> can efficiently access a particular item via its indexer. While that it true for arrays and List[T], it is in nono way guaranteed (take for an example, a singly-linked list that implements Ilist<T>).
If i was going to do this in a generic, Linqy way, I'd do something like:
public static IndexOfMinValue<T>( this IList<T> list ) where T:IComparable
{
if ( list == null ) throw new ArgumentNullException("list") ;
int? offset = null ;
T min = default(T) ;
int i = 0 ;
foreach ( T item in list )
{
if ( !offset.HasValue || item.CompareTo(min) < 0 )
{
offset = i ;
min = item ;
}
++i ;
}
if ( !offset.HasValue ) throw new ArgumentOutOfRangeException("list","list is empty") ;
return offset.Value ;
}
Or, arguably cleaner, since we get rid of extraneous initialization and an extraneous compare in the body of the loop:
public static int IndexOfMin<T>( this IList<T> list ) where T:IComparable
{
if ( list == null ) throw new ArgumentNullException("list") ;
IEnumerator<T> enumerator = list.GetEnumerator() ;
bool isEmptyList = ! enumerator.MoveNext() ;
if ( isEmptyList ) throw new ArgumentOutOfRangeException("list","list is empty") ;
int minOffset = 0 ;
T minValue = enumerator.Current ;
for ( int i = 1 ; enumerator.MoveNext() ; ++i )
{
if ( enumerator.Current.CompareTo(minValue) >= 0 ) continue ;
minValue = enumerator.Current ;
minOffset = i ;
}
return minOffset ;
}
You could also use the stock Linq Aggregate() overload, though it's no cleaner or simpler than the brute force method (probably less efficient, too, IMHO):
IList<int> = GetSomeIntegers() ;
int minIndex = list.Aggregate( (Tuple<int,int,int>)null,
( acc , item ) => {
int offset = 0 ;
int minValue = item ;
int minOffset = 0 ;
if ( acc != null )
{
offset = acc.Item3 + 1 ;
minValue = item < acc.Item1 ? item : acc.Item1 ;
minOffset = item < acc.Item1 ? offset : acc.Item2 ;
}
return new Tuple<int, int, int>( minValue , minOffset , offset ) ;
}).Item2 ;
Min Calculation: Finding the Min value in a collection cannot be done faster than O(n) so it may be no better way than that but just a different in the code style.
Finding Step: depending on your problem you may use some special data structure (such as binary tree, heap tree, ...) so you can find the index more faster.
Using something like min-heap tree you can get the min value with O(1) in expense of some special Add, Remove functions.
If possible, keep track of the min value/index as the values are placed in to the list, so you do not need to loop through a full list. Then if new values are added to the list, check them against the min value that you saved, and change the new min value as necessary.
Of course that might not be suitable for your situation.
I improved #cdhowie's answer a little bit to make it more powerful. If there are more than one minimum elements, then this method will return the first one.
public static T GetMin<T, TOrder>(this IEnumerable<T> self, Func<T, TOrder> orderFunc,
out int minIndex, IComparer<TOrder> cmp = null)
{
if (self == null) throw new ArgumentNullException("self");
IEnumerator<T> selfEnumerator = self.GetEnumerator();
if (!selfEnumerator.MoveNext()) throw new ArgumentException("List is empty.", "self");
if (cmp == null) cmp = Comparer<TOrder>.Default;
T min = selfEnumerator.Current;
minIndex = 0;
int intCount = 1;
while (selfEnumerator.MoveNext ())
{
if (cmp.Compare(orderFunc(selfEnumerator.Current), orderFunc(min)) < 0)
{
min = selfEnumerator.Current;
minIndex = intCount;
}
intCount++;
}
return min;
}
Sure. Just write your own Min function, instead of using LINQ, that keeps track of the index of the current minimum value. By doing that you can avoid needing to find the index of the item based on it's min value.
Microsoft seems don't want to rest, so they implemented another way to achieve the goal.
See MaxBy() in .NET 6.0.
It allows to find an item by max value of some key.
I'm lazy so I would use:
List.Sort();/* sorts the values least to greatest */
List[0];/* first item has the least value */

Is there an equivalent to the F# Seq.windowed in C#?

I am working on some C# code dealing with problems like moving averages, where I often need to take a List / IEnumerable and work on chunks of consecutive data. The F# Seq module has a great function, windowed, which taking in a Sequence, returns a sequence of chunks of consecutive elements.
Does C# have an equivalent function out-of-the-box with LINQ?
You can always just call SeqModule.Windowed from C#, you just need to reference FSharp.Core.Dll. The function names are also slightly mangled, so you call Windowed rather than windowed, so that it fits with the C# capitalisation conventions
You could always roll your own (or translate the one from F# core):
let windowed windowSize (source: seq<_>) =
checkNonNull "source" source
if windowSize <= 0 then invalidArg "windowSize" (SR.GetString(SR.inputMustBeNonNegative))
seq { let arr = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked windowSize
let r = ref (windowSize-1)
let i = ref 0
use e = source.GetEnumerator()
while e.MoveNext() do
arr.[!i] <- e.Current
i := (!i + 1) % windowSize
if !r = 0 then
yield Array.init windowSize (fun j -> arr.[(!i+j) % windowSize])
else
r := (!r - 1) }
My attempt looks like this, it's way slower than just calling F# directly (as suggested by John Palmer). I'm guessing it's because of F# using an Unchecked array.:
public static IEnumerable<T[]> Windowed<T>(this IEnumerable<T> list, int windowSize)
{
//Checks elided
var arr = new T[windowSize];
int r = windowSize - 1, i = 0;
using(var e = list.GetEnumerator())
{
while(e.MoveNext())
{
arr[i] = e.Current;
i = (i + 1) % windowSize;
if(r == 0)
yield return ArrayInit<T>(windowSize, j => arr[(i + j) % windowSize]);
else
r = r - 1;
}
}
}
public static T[] ArrayInit<T>(int size, Func<int, T> func)
{
var output = new T[size];
for(var i = 0; i < size; i++) output[i] = func(i);
return output;
}
John Palmer's answer is great, here is an example based on his answer.
var numbers = new[] {1, 2, 3, 4, 5};
var windowed = SeqModule.Windowed(2, numbers);
You may (or not) want to add ToArray() to the end, without ToArray, the return type is still in F# world (Sequence). With ToArray, it is back to C# world (Array).
The Reactive Extensions have a few operators to help with this, such as Buffer and Window. The Interactive Extensions, which can be found in the experimental branch, add these and a significant number of additional operators to LINQ.

Easy way to compare values of more than 3 variables?

I want to check whether these variables have same values.
EXAMPLE:
int a = 5;
int b = 5;
int c = 5;
int d = 5;
int e = 5;
. . .
int k = 5;
if(a==b && b==c && c==d && d==e && .... && j==k)
{
//this is Complex way and not well understandable.
}
Any easy way to Compare all are same?
LIKE in below example
if(a==b==c==d==e.....j==k)
{
//Understandable but not work
}
how about something like this:
if (Array.TrueForAll<int>(new int[] {a, b, c, d, e, f, g, h, i, j, k },
val => (a == val))) {
// do something
}
With this many variables, would it make sense to move them into an array?
You could then test to see if they are all equal using Linq expressions like myarray.Distinct().Count() == 1; or perhaps myarray.All(r => r == 5);
You could create a var args method to do that:
bool intsEqual (params int[] ints) {
for (int i = 0; i < ints.Length - 1; i++) {
if (ints[i] != ints[i+1]) {
return False;
}
}
return True;
}
Then just call it with all your ints as parameters:
if (intsEqual(a, b, c, d, e, f, g, h, i, j, k)) {
doSomeStuff();
}
Just a thought, but if you can calculate the standard deviation of the entire list, and it is equal to zero, you would have your answer.
Here's an answer on the site that addresses this that may help with that: Standard deviation of generic list?
Interesting problem. Good luck with it.
I agree that the easiest way is to place them all into a list and then use the following to compare. This is in essence looping through and comparing to the first value, but this is a little cleaner.
var match = counts.All(x => x == counts[0])
How about
int common = a;
if (a==common && b==common && c==common && d==common && .... && k==common)
You could write a helper method like this:
public static bool AllEqual<T> (params T[] values) where T : IEquatable<T>
{
if (values.Length < 2) return true;
for (int i = 1; i < values.Length; i++)
if (!values[i].Equals (values[0])) return false;
return true;
}
This will be subtly different to the == operator in special cases, though:
AllEqual (double.NaN, double.NaN).Dump(); // True
(double.NaN == double.NaN).Dump(); // False
It doesn't work because a==b evaluates to a boolean which can't be compared to an integer, c. What you have seems to be the best way.
You might consider putting the values in an array and using a for() loop. It isn't really any simpler, but it might help if the number of values changed.
You could use a variable argument helper function to perform the comparison pretty easily.
static bool CompareLongList(params int[] args)
{
if (args.Length > 1)
{
int value = args[0];
for (int i = 1; i < args.Length; ++i)
{
if (value != args[i])
return false;
}
}
return true;
}
Then you would just use the function as follows
if(CompareLongList(a,b,c,d,e,f,j,h,i,j,k))
{
// True Code
}
I know it's an old question I came across but I was wondering what's wrong with:
if (a == (b & c & d & e & f & g & h & i & j & k))
{
}
Compare the same elements in array:
same = len(uniq([1,2,3,4])) == 1
Use Linq Query.
var greatestInt = new List() { a,b,c,d,e,f}.Max();
Bitwise and is a possible way to check multiple variables for same value.
Such a helper method could of course also check for equality instead of using the '&' operator. Helper method accepting a params array of variables seems to be the right method here. We could adjust this method to accept a generic argument also, but there are only a few data types which support boolean logical operators anyways in C# (and other languages).
Testing with a high value of Int32 to check validity of this:
void Main()
{
int a = 1234567891;
int b = 1234567891;
int c = 1234567891;
int d = 1234567891;
int e = 1234567891;
int f = 1234567891;
int g = 1234567891;
int h = 1234567891;
int i = 1234567891;
int j = 1234567891;
int k = 1234567891;
bool areAllSameValue = IntUtils.AreAllVariablesSameValue(a,b,c,d,e,f,g,h,i,j,k);
areAllSameValue.Dump(); //Linqpad method - dump this code into Linqpad to test
}
public class IntUtils
{
public static bool AreAllVariablesSameValue(params int[] values)
{
if (values == null || !values.Any())
{
return false;
}
int bitWiseAndValue = values[0];
foreach (var value in values)
{
bitWiseAndValue &= value;
}
return bitWiseAndValue == values[0];
}
}
This spots also if one of the values got a different sign (negative number).

Sudoku algorithm in C#

I need one liner (or close to it) that verifies that given array of 9 elements doesn't contain repeating numbers 1,2,3,...,9. Repeating zeroes do not count (they represent empty cells).
The best I have came out so far is:
var a = new int[9] {1,2,3,4,5,6,7,8,9};
var itIsOk = a.Join(a, i => i, j => j, (x, y) => x)
.GroupBy(y => y).Where(g => g.Key > 0 && g.Count() > 1).Count() == 0;
If you don't want to solve my problems :), could you at least tell if the above algorithm works correctly?
And, yes, a have read this one.
This is about 50-250 times faster than a LINQ solution (depending on how early the duplicate is found):
public static bool IsValid(int[] values) {
int flag = 0;
foreach (int value in values) {
if (value != 0) {
int bit = 1 << value;
if ((flag & bit) != 0) return false;
flag |= bit;
}
}
return true;
}
Lucky for you I built a sudoku solver myself not too long ago :) The whole thing was about 200 lines of C#, and it would solve the toughest puzzles I could find line in 4 seconds or less.
Performance probably isn't that great due to the use of .Count, but it should work:
!a.Any(i => i != 0 && a.Where(j => j != 0 && i == j).Count > 1)
Also, the j != 0 part isn't really needed, but it should help things run a bit faster.
[edit:] kvb's answer gave me another idea:
!a.Where(i => i != 0).GroupBy(i => i).Any(gp => gp.Count() > 1)
Filter the 0's before grouping. Though based on how IEnumerable works it may not matter any.
Either way, For best performance replace .Count > 1 in either of those with a new IEnumerable extension method that looks like this:
bool MoreThanOne(this IEnumerable<T> enumerable, Predictate<T> pred)
{
bool flag = false;
foreach (T item in enumerable)
{
if (pred(item))
{
if (flag)
return true;
flag = true;
}
}
return false;
}
It probably won't matter too much since arrays are limited to 9 items, but if you call it a lot it might add up.
!a.GroupBy(i => i).Any(gp => gp.Key != 0 && gp.Count() > 1)
This is an old question, but I recently was pointed to a 1 line solution using Oracle's custom SQL for doing tree-like structures. I thought it would be nice to convert this into Linq.
You can read more on my blog about how to Solve Sudoku in 1 line of Linq
Here is the code:
public static string SolveStrings(string Board)
{
string[] leafNodesOfMoves = new string[] { Board };
while ((leafNodesOfMoves.Length > 0) && (leafNodesOfMoves[0].IndexOf(' ') != -1))
{
leafNodesOfMoves = (
from partialSolution in leafNodesOfMoves
let index = partialSolution.IndexOf(' ')
let column = index % 9
let groupOf3 = index - (index % 27) + column - (index % 3)
from searchLetter in "123456789"
let InvalidPositions =
from spaceToCheck in Enumerable.Range(0, 9)
let IsInRow = partialSolution[index - column + spaceToCheck] == searchLetter
let IsInColumn = partialSolution[column + (spaceToCheck * 9)] == searchLetter
let IsInGroupBoxOf3x3 = partialSolution[groupOf3 + (spaceToCheck % 3) +
(int)Math.Floor(spaceToCheck / 3f) * 9] == searchLetter
where IsInRow || IsInColumn || IsInGroupBoxOf3x3
select spaceToCheck
where InvalidPositions.Count() == 0
select partialSolution.Substring(0, index) + searchLetter + partialSolution.Substring(index + 1)
).ToArray();
}
return (leafNodesOfMoves.Length == 0)
? "No solution"
: leafNodesOfMoves[0];
}
Why do you want a convoluted line of Linq code, rather than wrapping up an efficient implementation of the test in an extension method and calling that?
var a = new int[9] {1,2,3,4,5,6,7,8,9};
var itIsOk = a.HasNoNonZeroRepeats();
One implementation of NoNonZeroRepeats could be to use the 9 lowest bits of a short to indicate presence of a value in the array, giving an O(length(a)) test with no dynamic memory use. Linq is cute, but unless you're only using it for aesthetic reasons (you don't specifically say that you're writing a sudoku solver using only Linq as an exercise) it seems to be just adding complexity here.
How about:
var itIsOk = a.Where(x => x > 0).Distinct().Count() == a.Where(x => x > 0).Count();
Reasoning: First create an enumeration without 0s. Out of the remaining numbers, if its distinct list is the same length as the actual list, then there are no repeats.
or:
If the list of unique numbers is smaller than the actual list, then you must have a repeated number.
This is the one-liner version. The a.Where(x=>x>0) list could be factored out.
var nonZeroList = a.Where(x => x > 0).ToList();
var itIsOk = nonZeroList.Distinct().Count() == nonZeroList.Count();
I usually frown on solutions that involve captured variables, but I had an urge to write this:
bool hasRepeating = false;
int previous = 0;
int firstDuplicateValue = a
.Where(i => i != 0)
.OrderBy(i => i)
.FirstOrDefault(i =>
{
hasRepeating = (i == previous);
previous = i;
return hasRepeating;
});
if (hasRepeating)
{
Console.WriteLine(firstDuplicateValue);
}
For brevity if not performance, how about
var itIsOk = a.Sum() == a.Distinct().Sum();
The following is simple and fast.
if a.Select(i => Math.Pow(2, i - 1)).ToArray().Sum()==511 ...

Categories

Resources