I was reading a question posted here: Sudoku algorithm in C#
And one of the solutions posted was this piece of code.
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;
}
The idea is that it will detect duplicates in the array of values; but I'm overwhelmed by how much I don't know. Can someone explain this to me?
EDIT: Thanks everyone. So many great answers, I don't know how to select one. It now makes perfect sense.
Lets work through it.
values = 1,2,3,2,5
Iteration 1:
bit = 1 << 1
bit = 10
if(00 & 10 != 00)
false
flag |= bit
flag = 10
Iteration 2:
bit = 1 << 2
bit = 100
if(010 & 100 != 000)
false
flag |= bit
flag = 110
Iteration 3:
bit = 1 << 3
bit = 1000
if(0110 & 1000 != 0000)
false
flag |= bit
flag = 1110
Iteration 4:
bit = 1 << 2
bit = 100
if(1110 & 0100 != 0000)
TRUE
This evaluates to true, meaning we found a double, and return falseIt checks to see if values in the array are unique. To do this, it creates an integer - flag - and it sets bits in the flag according to values in the array of values. It checks to see if a particular bit is already set; if it is, then there is a duplicate and it fails. Otherwise, it sets the bit.
Here's a breakdown:
The idea is to set the
nth
bit of a number, wheren
is the cell value. Since sudoku values range from 1-9, all the bits fit within a range of 0-512. With each value, check if thenth
bit is already set, and if so, we've found a duplicate. If not, set thenth
bit on our check number, in this caseflag
, to accumulate numbers that have already been used. It's a much faster way to store data than an array.Really a nice idea.
Basically, it uses an
int
flag (initially set to zero) as a "bit array"; for each value, it checks if the corresponding bit in the flag is set, and if it's not, it sets it.If, instead, that bit position is already set, it knows that the corresponding value has already been seen, so the piece of Sudoku is invalid.
More in detail:
Interesting. It stores the numbers it already found by setting that bit in the flag-integer. Example:
It also tests for each number if that bit is already set in the flag-int.