I was looking at the sudoku code of the "mine" sudoku Android application and I've noticed this code:
selX = Math.min(Math.max(x, 0), 8);
selY = Math.min(Math.max(y, 0), 8);
What does Math.min(Math.max(x, 0), 8) and Math.min(Math.max(y, 0), 8) mean?
Break it down step by step using the docs:
http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#max(long
max(int a, int b) Returns the greater of two int values.
min(int a, int b) Returns the smaller of two int values.
So Math.min(Math.max(x, 0), 8); breaks down to:
int maximum = Math.max(x,0);
int final = Math.min(maximum,8);
First you take the maximum value of x and 0, so if x < 0, it will be zero.
Next take the minimum of the result and 8, so the maximum value will be 8.
It is about the same as:
int selX = x;
if (selX < 0) selX = 0;
if (selX > 8) selX = 8;
or
int selX = (x < 0) ? 0 : ((x > 8) ? 8 : x);
The first one returns x, if x is between 0 and 8, 0 if x is less than 0, and 8 if x is greater than 8.
The second one works in a similar fashion. So basically you're getting a number back that is guaranteed to be between 0 and 8, inclusive.
The Java Math class describes what the min and max functions do in detail.
Sudoku means 9 x 9 squares. You can index them from 0 to 8. Math.min(Math.max(x, 0), 8) guarantees that you get a number in that range. Is x > 8 then min(x,8) makes it 8. If x < 0 then max(x,0) makes it 0. That's all.
Related
I have a piece of Matlab code but could not find out how to convert to a Java code. What does this row mean? How can be converted to Java?
Matlab code:
b = all(x <= y) && any(x<y);
Hint: x = [1,2,3,4,5], y = [5,4,3,2,1]
What is b as the result?
You can use Java Streams like in
var x = new int[] {1, 2, 3, 4, 5};
var y = new int[] {5, 4, 3, 2, 1};
var b = IntStream.range(0, x.length).allMatch(i -> x[i] <= y[i])
&& IntStream.range(0, x.length).anyMatch(i -> x[i] < y[i]);
not handling x and y having different sizes!
From the matlab official site:
A <= B returns a logical array with elements set to logical 1 (true) where A is less than or equal to B; otherwise, the element is logical 0 (false).
Up to this you have 11100 in the first comparison.
B = all(A) tests along the first array dimension of A whose size does not equal 1, and determines if the elements are all nonzero or logical 1 (true). In practice, all is a natural extension of the logical AND operator.
So all(x <= y) must return 0.
B = any(A) tests along the first array dimension of A whose size does not equal 1, and determines if any element is a nonzero number or logical 1 (true). In practice, any is a natural extension of the logical OR operator.
So any(x < y) should be 1.
&& is AND
The rest is up to you
I have to write a function that does a left circular shift of the bits of y positions.
For example, if I put: 01011000 and 2 as the y, the function has to return 01100001.
I have tried to use Integer.rotateLeft() but it seems to be useless for this.
This should work I think:
int rotate_8bits_left(int val, int y) {
// amend y to the range [0, 7] with this:
// y = ((y % 8) + 8) % 8;
// or better, with this:
y = y & 0x7;
// do the rotation
return ((val << y) & 0xFF) | (val >> (8-y));
}
Let's explain the different parts:
// move val left y bits:
(val << y)
Above however keeps the bits that get beyond the 8th bit, so we need to truncate them, so we go with:
// move val left y bits and truncate anything beyond the 8th bit:
(val << y) & 0xFF
Now we need to add the bits that went out, to the beginning. We can calculate the bit that went out to the left by just moving to the right:
// move to the right, 8-y bits
val >> (8-y)
If we now glue together the two parts, we would get the rotation:
int new_val = ((val << y) & 0xFF) | (val >> (8-y));
Now for the first part, we want to handle y that might not be in the range [0, 8]. We can amend y to this range, before using it, with:
y = ((y % 8) + 8) % 8;
The expression above fixes both negative and positive values of y, if y is negative the modulo would return a negative value in the range [-7, -1], then by adding 8 we get back to the positive range. We have to do modulo again, for the case where y was positive and adding 8 to fix the negative case took it back to be above 8. The second modulo fixes this.
But we can achieve the same amendment for y with a more simple approach, by leaving only the 3 first bits that encounter for the range [0, 7], treating 8 as 0, this can be done with the following expression, that works well for both negative and positive values of y:
y = y & 0x7;
I have an application that is sending me 2 shorts one increments from 0 -> 32 -> 48 -> 16 then back to 0 and the second increments each time the first one hits 0. The second one goes up to a maximum of 65535 and then loops round back to 0. I'm guessing this is some bits that are encoded which can be made to create a single number?
How can I combine these two shorts into a single number that increments by 1 if they increment in the behaviour described above?
0b0000_0000 0
0b0010_0000 32
0b0011_0000 48
0b0001_0000 16
So you can increment a counter modulo 4, 0, 1, 2, 3, 0, 1, 2, ... and switch the two bits. Modulo 4 means & 0b11.
int x = 0;
for (int i = 0; i < 100; ++i) {
System.out.printf("%04x%n", x);
x = (x + 1) & 0xFFFF;
x |= (x & 2) << 16;
x |= ~((x & 2) ^ (x & 1)) << 17; // Or something like that
}
I leave it to you to find the logic.
Consider 9 variables that can have values from to 1 to 9 each. What is a good and fast way to check if each variables has a distinct value. The first thought came to my mind was to sum them up to see if it is equal to n(n+1)/2 but this is nowhere foolproof. Any ideas?
Edit : Thanks a lot guys. Totally forgot about Set. What a noob I am.
Add them all to a Set, and check that the size of the Set is 9.
For example, to check if an array of 9 int are all different:
int[] array = new int[9];
// fill array
Set<Integer> set = new HashSet<Integer>();
for (int i : array)
set.add(i);
boolean allDistinct = set.size() == 9;
The set does all the work, because sets only allow distinct values to be added. If any values are the same, the size will be less than 9.
This technique works for any class of value types, any range and any quantity of values.
Start with a bitmask with bits 0 through 9 set, then clear the bits corresponding to values of each variable. If the resultant bitmask is a power of two, all values were distinct+; otherwise, there were duplicates.
int a, b, c, d, e, f, g, h, i;
int mask = 0x3FF; // bits zero through 9 are set
mask &= ~(1<<a);
mask &= ~(1<<b);
...
mask &= ~(1<<i);
if ((mask & -mask) == mask) {
// all bits were distinct
}
See this answer for an explanation of the bit trick used in the last condition.
+ You have ten possible values and nine variables; in order for the nine values to be distinct, they must clear out nine out of ten bits from the bitmask with all ten bits initially set. Removing nine out of ten bits leaves you with only one bit set to 1, meaning that the result is a power of two.
Use XOR to find the duplicate number is a trick.
int[] arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 9 };
int answer = 0;
for (int i = 0; i < arr.length; i++) {
answer = answer ^ (arr[i] + 1) ^ i;
}
System.out.println(answer - 1);
Output:
5
This algorithm is working with any count of number, but every number must be in interval <0, 31> or you can change mask and bit type to long for interval <0, 63>.
int[] numbers = {0, 1, 2, 3, 3, 5, 6, 7};
int mask = 0;
for (int number : numbers) {
int bit = 1 << number;
if ((mask & bit) > 0) {
System.out.println("Found duplicity " + number);
return;
}
mask |= bit;
}
System.out.println("No duplicity");
I have a byte array, for example 400 bytes.... and then a position of a bit, for example 6. How can I check if the value of this bit is 1? So in my example, the return value will be true.
example:
final byte[] b = new byte[] { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
what is 00000100....
pos = 6
result = true
It looks as if you count your bits like this:
Bit 1 is the highest bit of the first byte, bit 8 is the lowest bit of the first byte, bit 9 is the highest byte of the second byte and so on.
Then you can use:
private boolean isSet(int index) {
int bitIndex = (index-1) % 8;
int byteIndex = (index-1) / 8;
int bitMask = 1 << 7-bitIndex;
return (b[byteIndex] & bitMask) > 0;
}
However, if you used (for me) a more natural way to index so that bit 0 was the lowest bit in the first byte, bit 7 the highest bit of the first byte, bit 8 the lowest but of the second byte (and so on) the the could would be:
private boolean isSet(int index) {
int bitIndex = index % 8;
int byteIndex = index / 8;
int bitMask = 1 << bitIndex;
return (b[byteIndex] & bitMask) > 0;
}
Since you count positions in the byte and in the Array backwards:
public boolean bitAtPos (byte [] b, int pos) {
int el = b[pos/8];
return ((el >> (8-(pos%8)) & 1) == 1);
}
boolean validateValue(byte[] array, int numberToValidate, int position) {
return (array.length > position-1 && position >= 1) ? array[position-1] == numberToValidate : false;
}
This method helps you use it multiple time for any number you want to validate.
Note: I added some pre-validation:
if you use an invalid position as a parameter it will return false. Best practice would be to throw an exception but I'll you deal with that.