SequenceEqual always returning false - c#

I making a lottery simulation and i have 2 different arrays with 6 numbers to hold firstly the numbers the user wishes to play and secondly the numbers that get generated each run.
The user enters their numbers into a textbox and its saved as a string and placed into respective spots in the aray, the randomly generated nums are also saved as a string into the string array.
After this i have a SequenceEqual for comparison
bool equal = lotteryNums.SequenceEqual(playerNums);
This always returns false, i have set all the generated array elements manually to 1-6 and then the players nums accordingly through the textboxes yet it will always return a false.
The generated array is currently filled like this for testing
lotteryNums[0] = "1";
lotteryNums[1] = "2";
lotteryNums[2] = "3";
lotteryNums[3] = "4";
lotteryNums[4] = "5";
lotteryNums[5] = "6";
The player array is filled like this using the next array position for the next number
string inputNum = inputBox_txt.Text;
playerNums[0] = inputNum;
Why is this always returning false?
Since people are asking the arrays are both in the exact same order and do not appear to contain anything more or anything less than the numbers in the arrays

SequenceEqual returns true if the two source sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type; otherwise, false.
Since the two arrays you provide are not identical then you are getting false.

In addition to what Athanasios Emmanouilidis said: it seems that the collections need to have the same order. So you should order them:
bool equal = playerNums.OrderBy(n => n).SequenceEqual(lotteryNums.OrderBy(n => n));

Another thing to consider: SequenceEquals requires that the numbers be in the exact same order in both arrays. Even if the arrays contain the same numbers, but they are in a different order, you will get false. You can solve this by sorting each list prior to comparing (just make sure you sort both in the same way).
If that doesn't work, verify that the strings from the textbox are actually just the numbers, and do not include any white space or special characters.

SeqqnceEqual will also take the order of the elemnts into account, which you probably donĀ“t want in a lottery. What you want instead is to check if all the expected values are in the inout as well:
var sixCorrects = lotteryNums.All(x => playerNums.Contains(x));
All will stop iterating as soon as an element of lotteryNums was not found within playerNums.

Related

How to use SkipWhile() to skip duplicate elements in two arrays?

I am trying to get a list of numbers (upto 9) that don't contain any numbers already in a 3x3 cell from which is contained within a 81 large 2d array of integers. I'm attempting to make sudoku. There are likely better solutions that have nothing to with skipwhile or something similar, but they all seem to rely on duplicate numbers having the same index in both array which doesn't work.
int[] inCellNumbers = thisCell.Intersect(Numbers).ToArray();
int[] availableNumbers = Numbers.SkipWhile(Numbers.Contains<int>(inCellNumbers) == true);
This is the code that I tried, numbers is an array of integers and I get this error:
'MemoryExtensions.Contains(ReadOnlySpan, int)' requires a receiver of type 'ReadOnlySpan'
I was attempting to skip all numbers that are in 'inCellNumbers' and have them in 'availableNumbers' from 'Numbers'
You can use the Enumerable.Except Method:
int[] availableNumbers = Numbers.Except(inCellNumbers).ToArray();
The Enumerable.SkipWhile Method stops skipping at the first element that does not fulfill the condition. Even if others follow later that do fulfill it.
I'm not sure of the algorithm for checking around a sudoku grid but it sounds like you would want to use some hashsets.
A hashset may only have unique entries. An array or list can be dumped to a hashset using its constructor new HashSet(arrOrList), and you can evaluate immediately to one from LINQ using .ToHashSet().
As for the error, it looks like you are using List<T>.Contains<T>(T item) (notice all of the T here), which is going to check if the List contains the entire parameterized array as a single element/item. Unless Numbers is of type List<int[]> this is going to be a problem, but I'm unsure of what type you give it so this may not be the true issue. I see you are using .Contains<int> but this won't work as inCellNumbers is int[]

Fastest way to compare two integer arrays for value comparison

I know that array comparison questions have been asked multiple times but I am curious to know if there is a better method than the ones I have tried so far.
The requirement is to compare two integer arrays of same length to check if one of them has values which are always greater than or equal to the ones in the second one when mapped one to one. So, if you were to sort the arrays (which I did for comparing them), the values at the same indices in the first array should always be greater than or equal to the ones at the same indices in the second one.
I tried the check in two ways so far:
Sort the arrays. Run a for loop and return a false value if any of the values in the second array turns out to be greater than the corresponding value in the first array:
Array.Sort(Array1);
Array.Sort(Array2);
//
for (int i = 0; i < Array1.length; i++)
{
if (Array2[i] > Array1[i])
{
return false;
}
}
return true;
In the alternate method, I tried to be cute and used the chaining of FindIndex and IndexOf methods to get the solution in one go. I think it's actually less efficient since, as far as I can tell and please correct me if I am wrong, it is traversing the array twice instead of once as is the case in the previous method:
Array.Sort(Array1);
Array.Sort(Array2);
//
return Array.FindIndex(Array2, i => i > Array1[Array.IndexOf(Array2, i)]) >= 0
? false
: true;
I think the first method works better but is there a faster/better way to achieve the same result? The number of elements can range from 10 to 10000.
Thanks.

C# String.CompareTo not returning the results I would expect

I am trying to compare strings for less than etc - in a similar way I would compare numbers.
My issue is the following comparison returns true:
var expectThisToBeFalse = "315160".CompareTo("40000") < 0;
I know I can compare these as numbers, but in my application I do not know if they are numbers or letters.
Can anyone explain what I am misssing, and if there is a comparison method that would work
eg would show:
"1" is less than "2"
"a" is less than "b"
"aa" is greater than "b"
etc...
You are not missing anything. The metod you use compares two strings alphabetically. It means that if string A is in the alphabet ahead of string B, then it returns -1.
Because you're comparing two strings, not two numbers, the function looks at the first character of both of the strings ("3" and "4" in your example. Because "3" has a lower ASCII code than "4" (51 and 52, respectively), the function concludes that "315160" is ahead in the alphabet than "40000", so it returns -1. Because you compared the result of this function (-1) with 0, the variable is (correctly) true, because -1<0.
For what you wish, you will need to program your own function. I don't know if there is any function already programmed.
Later edit: more info on string.compare.
Later edit 2: something else struck me as interesting:
but in my application I do not know if they are numbers or letters.
For a simpler way of solving this, you may begin by checking if the two inputs are numbers or letters. You would save yourself a lot of trouble, because sometimes these two inputs will be numbers and solving is super-easy.

Logical error while creating Palindrome Program

I tried to make Palindrome program as small as possible. However, this program is giving logical error. When I enter palindrome string it gives "False" as result which is opposite of what is expected.
char[] phrase;
Console.WriteLine((phrase = Console.ReadLine().ToArray())==phrase.Reverse().ToArray());
Console.ReadLine();
I do not want to increase number of statements of this program.
In .NET, arrays do not have an overloaded equality operator. Use Enumerable.SequenceEquals.
Reading your code more thoroughly, you are making things more complicated than necessary.
string phrase = Console.ReadLine();
var reversedPhrase = phrase.Reverse(); //Type is IEnumerable<char>
Console.WriteLine(phrase.SequenceEquals(reversedPhrase));
I recommend that you don't burry side-effects inside of expressions in the way you did. That code could well have been a test question to see if a student can work it out.
If you want to do it by array then you can try this
char[] phrase;
Console.WriteLine(phrase = Console.ReadLine().ToArray().SequenceEqual(phrase.Reverse().ToArray()));
Console.ReadLine();
just like usr said use sequenceequal
Since you created 2 different array and arrays are reference type, == checks for reference equality, not value.
You can use Enumerable.SequenceEqual instead which returns;
true if the two source sequences are of equal length and their
corresponding elements are equal according to the default equality
comparer for their type;
Console.WriteLine(myString.SequenceEqual(myString.Reverse()));
Easiest way to compare arrays in C#

How to sort numbers

I need some help to be able to handle the following logic. The program gets many integers input like 10,16,3,17,21,29,6.
Logic to be done:
Scenario 1:
First select the biggest 4 numbers of input which is 16,17,21,29. Now assign the values to A,B,C and D:
A = smallest in the selected 4
B = biggest in the selected 4
C =
second smallest in the selected 4
D = third smallest in the selected
4
Result to be Displayed:
A = 16
B = 29
C = 17
D = 21
Scenario: 2
If the user gives 3 inputs like 3,6,10 assign only to A,B,C and should ignore D
Result to be Displayed:
A = 3
B = 10
C = 6
Assuming that you have your input values in an array, you can sort it using the static Array.Sort() method and then pick the top/bottom ones by indexing (eg. values[value.Length - 1] gets the highest value). Do make sure to do some bounds checking to avoid runtime exceptions, and to solve "scenario 2" of the assignment correctly.
If you want something more modern, you could also use some LINQ magic to get the top 4 items:
values = values.OrderByDescending(i => i).Take(4).ToArray();
The four highest values are now in highOnes for you to print in whatever order you please. Once again, make sure to do some bounds checking - there might be less than four numbers in the array.
I would take the input and store them into a List. I would then sort this list.
Once sorted you can then pull out the numbers as required.
Logic:
Sort in descending order
Select top 4 element
Assign value as per your requirement in A,B,C,D
Sounds like this could be an assignment so I'll give you these tips:
If you have all these numbers in an array, you can try partially sorting the array. Write a simple bubble sort, and have it sort the largest numbers to the front. But instead of sorting the whole array, make it stop after it brings the 4 largest elements to the front of the array.
That way, your first element will be your largest, and so forth. From there, you can do the rest of the things you need easily.
Hope that helped.

Categories