The Nine Tails game [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Nine coins are placed in a three-by-three matrix with
some face up and some face down. A legal move is to take any coin that is face up and
reverse it, together with the coins adjacent to it (this does not include coins that are diagonally
adjacent). The task is to find the minimum number of moves that lead to all coins
being face down.
The problem can be reduced to the shortest path problem and solved using BST.
We find all the possible combinations of the 9 coins, and create an UnweightedGraph. Each state (or combination) of the nine coins represents a node in the graph. We assign an edge from node v to u if there is a legal move from u to v.
Here's the algorithm to find all the 512 possible combinations
for (int u = 0; u < 512; u++) {
char[] node = getNode(u);
/* ..... */
}
public static char[] getNode(int index) {
char[] result = new char[9];
for (int i = 0; i < 9; i++) {
int digit = index % 2;
if (digit == 0)
result[8 - i] = 'H';
else
result[8 - i] = 'T';
index = index / 2;
}
return result;
}
How is this algorithm working?
I've only embedded the part I can't understand. If you want I can embed the whole nineTailsProblem.

The logic behind this is that when iterating u=[0, 512), u's binary representation gives you all possible 9-bit combinations of 1s and 0s.
Example with u=[0, 8):
000
001
010
011
100
101
110
111
getNode just converts these u's to char[], representing bit value 0 with H (head) and 1 with T (tail).
This gives you the value of least significant bit (LSB):
int digit = index % 2;
and division by 2 shifts the bits to the right by one, so that in the next iteration, you'll get the 2nd, then 3rd, 4th bit and so on:
index = index / 2;

Related

How to make a +5 (or any +number) jump in array values inside a for loop? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
So i have a column of data which consists of numbers where i have to find 5 instances of the same number.
So ,for example, 8,8,8,8,8,8,8,8,8,9,9,9,5,6,4,7,,6,2,3, etc. In this 8 has occurred 9 times. So i want to increment the count only once because even though there are nine 8's what my code is doing is taking the first 8 and getting the 5 consecutive numbers are incrementing. Then it takes the next 8 and increments the count and so on where the count becomes 5 but i want it to be 1. What i want is the first occurrence of any number to be the base value and take 5 consecutive numbers and increment the count. Then then take the 6th 8 and count if there are 5 consecutive 8's or that specific number or not. So, for example, 8,8,8,8,8,8,9,9,9,9,9,9,9,9,5,5,5,5,5,1,1,2,2,5,4,3,6,7,9,3,4,2,2,2,2,2,1,2,1. In this the count should be 4.
**count=0;
count1=0;
for i=1:length(data)-4
for j=i+1:i+4
if data(i)~=data(j)
count1=0;
break;
else
count1=count1+1;
end
if count1==5 % line 0
count=count+1;
%data(i,1)=data(i+5,1); //line 1 <=comment
%data(i)=data(i+5); //line 2 <=comment
else
continue;
end
end**
If(count_consecutive==5){
count_main=count_main+1; ...
a[i]=a[i+5];// continue for the base value. It should skip all the numbers that were counted in the consecutive count one and take the next number as the base for counting the consecutive numbers}
The logic in any language would be fine as my error is in the logic
Thanks for any help. It would be greatly appreciated :).
Extra Elaboration
So the first one only has 5 consecutive 8's in the manner i specified. Hence the first one will have an output count =1 . In the second one, there are 4 of the 5 consecutive numbers of the same starting number. Hence the output would be 4, Another example i can give is 8,8,8,8,8,8,8,8,8,8(ten 8's),9,9,9,9,4,5,6,4,6,6,6,6,6. In this , the count should be 3 as it has 10 8's which increments the count to 2 and another 5 consecutive 6 which increments count one more time. Total count would be 3.
Now the error is i can't jump the array index from a[i] to a[i+5]. So the first one only has 5 consecutive 8's in the manner i specified. Hence the first one will have an output count =1 . In the second one, there are 4 of the 5 consecutive numbers of the same starting number. Hence the output would be 4, Another example i can give is 8,8,8,8,8,8,8,8,8,8(ten 8's),9,9,9,9,4,5,6,4,6,6,6,6,6. In this , the count should be 3 as it has 10 8's which increments the count to 2 and another 5 consecutive 6 which increments count one more time. Total count would be 3. My problem is that i'm not able to skip/jump the array index from x to x+5 in the for loop when my condition gets satisfied.
I attach the code in Matlab (also works in Octave):
vector = [8,8,8,8,8,8,9,9,9,9,9,9,9,9,5,5,5,5,5,1,1,2,2,5,4,3,6,7,9,3,4,2,2,2,2,2,1,2,1]
count = 1;
result = 0;
for i = 2:length(vector)
if vector(i-1) == vector(i)
count = count+1;
else
count = 1;
end
if count == 5
result = result+1;
count = 1;
end
end
Mainly, you have to count the number of times that a value appears and increase the result if this number of times arrises 5.
It would be simpler to count the length of the subsequence containing the same elements consecutive and as soon as the subsequence is finished, to increment the resulting counter by the number of groups consisting of N elements in the subsequence: result += consecutive / n:
public static int countConsecutiveN(int n, int ... arr) {
if (null == arr || arr.length < n) {
return 0;
}
int result = 0;
int previous = arr[0];
int consecutive = 1;
for (int i = 1; i < arr.length; i++) {
if (arr[i] == previous) {
consecutive++;
} else { // consecutive sequence ended
result += consecutive / n; // increment by the count of N elements in the subsequence
consecutive = 1;
}
previous = arr[i];
}
// check the trailing subsequence
result += consecutive / n;
return result;
}
Test
System.out.println(countConsecutiveN(5,
8,8,8,8,8,8, // six 8s
9,9,9,9,9,9,9,9,9,9, // ten 9s - 2 groups
5,5,5,5,5, // five 5s
1,1,2,2,5,4,3,6,7,9,3,4,
2,2,2,2,2,2,2, // seven 2s
1,2,
1,1,1,1,1,1 // six 1s
));
Output
6
If you want to count runs of equal values with a minimum length N, in Matlab this can be done very easily with diff (consecutive differences) and find (indices of nonzero entries):
N = 5; % mininum desired run length
x = [8,8,8,8,8,8,9,9,9,9,9,9,9,9,5,5,5,5,5,1,1,2,2,5,4,3,6,7,9,3,4,2,2,2,2,2,1,2,1];
result = sum(diff(find([true diff(x)]))>=N);
If a run ends immediately when reaching length N (so for example 11 consecutive equal values count as two runs of length N=5):
result = sum(floor(diff(find([true diff(x)]))/N));

Adding Values to a List and Converting to BigInteger - Java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm writing a code that determines the smallest integer that is a sequence of sevens followed by some number of zeros (possibly none) that is divisible by int n. Since this number can be massive, the return value should be a BigInteger.
My code so far has an if-else ladder that covers the case that if any int n is not divisible by two or five is guaranteed to only contain sevens (no zeros). In the case where int n is not divisible by two or five, my thought process was to continue adding sevens to a LinkedList in a while loop, until that list (converted to a BigInteger) is divisible by int n. The same logic goes for the case where int n is divisible by two or five, except a two for-loops would add seven and zero to the list.
My code is getting a runtime error when converting the list to a string and then to a BigInteger, specifically on the line BigInteger numBig = new BigInteger(str);. The error is: "java.lang.NumberFormatException: Zero length BigInteger (in java.math.BigInteger)" Also, I'm not quite sure the logic is sound for the case where int n is divisible by two or five.
You don't need BigInteger for this task. The idea is the following:
First you determine the number of required zeros. Since number composed of only sevens cannot be divided by 2 or 5, the number of zeros is equal to the maximum power of 2 or 5 in number n.
Now we have a number n which is not divisible by 2 or 5. Suppose that a remainder of the division of a number composed of m sevens by n is equal to r:
777...m-times..777 mod n = r
Then number composed of (m+1) sevens will have a remainder 10*r + 7, because
777..(m+1)-times...777 = 777...m-times...7 * 10 + 7
So you can just recalculate the remainder until it becomes zero.
public static BigInteger method(int n) {
int two;
for (two = 0; n % 2 == 0; two++) n /= 2;
int five;
for (five = 0; n % 5 == 0; five++) n /= 5;
int zeros = Math.max(two, five);
int sevens = 1;
int r = 7 % n;
while (r != 0) {
r = (r * 10 + 7) % n;
sevens++;
}
// Now just make a number of 'sevens' sevens and 'zeros' zeros:
StringBuilder result = new StringBuilder();
for (int i = 0; i < sevens; i++) {
result.append("7");
}
for (int i = 0; i < zeros; i++) {
result.append("0");
}
return new BigInteger(result.toString());
}
"Zero length BigInteger" means you're trying to create a BigInteger from something that has length of 0. The stack trace would tell you on which line exactly.
I would guess the bug is in your convert method. If you pass in an empty list, it tries to convert an empty string into BigInteger with new BigInteger("")
I don't know what your algorithm is supposed to do in this case. If for example you want to convert an empty list into the number zero, you can do:
if (res.isEmpty()) return BigInteger.ZERO;

Read n, Find the value of M where M = 2 * 4 * 6 * … * ≤ n [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
n is any integer value, given by the user. M is Multiply of all even numbers in 1..n:
M = 2 * 4 * 6 * … * ≤ n
Example :
int n = 9
output
int output = 2*4*6*8; // 384
My code:
Scanner in = new Scanner(System.in)
int n=inut.nextInt();
for(....)
In short you need to multiply all even numbers between 1 and n.
For this you can use a for-loop and if-statement. for-loop will give you all numbers between 1..n, and if-statement will reject odd numbers, leaving only even.
Last path would be to multiply all values.
int n = 9;// input;
int result = 1; // because you are multiplying, initial result must be 1
for (int i = 1; i <= n; i++) {
if (i % 2 == 0) { // ignore all odd numbers
result *= i; // multiply result with next even value
}
}
System.out.println(result); // print the result: 384
You can look at this like an assembly line. At the start someone is generating numbers from 1 to n. Then someone called 'the filter' rejects (push to trash) all odd numbers, at the end of the line someone called 'the aggregator' multiplies all values into an result.
With Java 8 and streams this can be represented by:
int result = IntStream.range(1,n)// generate numbers from 1 to n
.filter(value->value%2==0) // reject all odd numbers
.reduce(1, (a,b)-> a*b); // multiple all values, with 1 as initial result
System.out.println(result);

Can someone explain to me this code of multiplying two variables using shifts? [duplicate]

This question already has answers here:
Bitwise Multiply and Add in Java
(4 answers)
Closed 4 years ago.
So I have the following code to multiply two variables x and y using left and right shifts.
class Multiply {
public static long multiply(long x,long y) {
long sum = 0;
while(x != 0) {
if((x & 1) != 0) {
sum = sum+y;
}
x >>>= 1;
y <<= 1;
}
return sum;
}
public static void main(String args[]) {
long x = 7;
long y = 5;
long z = multiply(x,y);
}
}
But I dont understand the logic behind it, I understand that when you do
y<<=1
You are doubling y, but what does it mean that the number of iterations of the while loop depends on the number of bits x has?
while(x != 0)
Also why do I only sum if the rightmost bit of x is a 1?
if((x & 1) != 0) {
sum = sum+y;
}
I've really tried to understand the code but I haven't been able to get my head around the algorithm.
Those of us who remember from school how to multiply two numbers, each with two or more digits, will remember the algorithm:
23
x45
---
115
92x
----
1035
For every digit in the bottom factor, multiply it by the top factor and add the partial sums together. Note how we "shift" the partial sums (multiply them by 10) with each digit of the bottom factor.
This could apply to binary numbers as well. The thing to remember here is that no multiplication (by a factor's digit) is necessary, because it's either a 0 (don't add) or a 1 (add).
101
x110
-----
000
101
101
-----
11110
That's essentially what this algorithm does. Check the least significant bit; if it's a 1, add in the other factor (shifted), else don't add.
The line x >>>= 1; shifts right so that the next bit down becomes the least significant bit, so that the next bit can be tested during the next loop iteration. The number of loops depends on where the most significant bit 1 in x is. After the last 1 bit is shifted out of x, x is 0 and the loop terminates.
The line y <<= 1; shifts the other factor (multiplies by 2) in preparation for it be possibly added during the next loop iteration.
Overall, for every 1 bit in x at position n, it adds 2^n times y to the sum.
It does this without keeping track of n, but rather shuffling the bits x of 1 place right (dividing by 2) every iteration and shuffling the bits of y left (multiplying by 2).
Every time the 0 bit is set, which is tested by (x & 1) != 0, the amount to add is the current value of y.
Another reason this works are these equivalences:
(a + b) * y == a*y + b*y
x * y == (x/2) * (y*2)
which is the essence of what’s going on. The first equivalence allows bit-by-bit addition, and the second allows the opposite shuffling.
The >>> is an unsigned right shift which basically fills 0 irrespective of the sign of the number.
So for value x in the example 7 (in binary 111) the first time you do x >>>= 1; You are making the left most bit a zero so it changes from 111 to 011 giving you 3.
You do it again now you have 011 to 001 giving you 1
Once again and you have 001 to 000 giving you 0
So basically is giving you how many iterations before your number becomes zero. (Basically is diving your number in half and it is Integer division)
Now for the y value (5) you are adding it to your sum and then doubling the value of y
so you get:
y = 5 sum = 5
y = 10 sum = 15
y = 20 sum = 35
Only 3 iterations since x only needed to shift 3 times.
Now you have your result! 35

How to improve: Given two integers, return the number of digits that they share [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I received this question during an interview, the question is
Given two integers, return the number of digits that they share.
For example 129 and 431 would return 1 - as they both share the digit 1, but no other digit. 95 and 780 would return 0, since none of the integers overlap.
My thoughts are just iterate through the digits, store them into a hashtable and check .containsKey.
My Java solution:
public int commonDigits(int x, int y) {
int count = 0;
HashTable<Integer, String> ht = new HashTable<Integer, String>();
while (x != 0) {
ht.put(x % 10, "x");
x /= 10;
}
while (y != 0) {
if ((ht.containsKey(y % 10)) {
count++;
}
y /= 10;
}
return count;
}
But this takes up O(n) space and O(n + m) time, anyways I can improve this?
Why not just use some simple bit fiddling? 
public int commonDigits(int x, int y) {
int dX = 0;
while (x != 0) {
dX |= 1 << (x % 10);
x /= 10;
}
int count = 0;
while (y != 0) {
int mask = 1 << (y % 10);
if ((dX & mask) != 0) {
count ++;
dX &= ~mask;
}
y /= 10;
}
return count;
}
This just sets a corresponding bit in dX for each digit in x. In the second loop, for each digit in x, the code checks whether it has an entry in dX. If so, it's counted and the bit is reset to avoid double-counting (note that this is missing in your code, consider 123 and 141). Obviously doesn't use any additional storage (dX and count could just be bytes if that matters).
Note that you don't need a HashTable in your solution -- you could just use a HasSet or a BitSet..
Your code translated to using a BitSet with the double-counting problem fixed:
public int commonDigits(int x, int y) {
int count = 0;
BitSet ht = new BitSet();
while (x != 0) {
ht.set(x % 10, true);
x /= 10;
}
while (y != 0) {
if ((ht.get(y % 10)) {
count++;
ht.set(y % 10, false);
}
y /= 10;
}
return count;
}
Both snippets work exactly the same way, the latter just has some more overhead for the BitSet (and embedded array) instance.
This article shows why a BitSet is better than a boolean array in the general case: http://chrononsystems.com/blog/hidden-evils-of-javas-byte-array-byte
Edit:
If counting the same digit multiple times is actually desired (was not clear from the examples in the question), use an int array to store the counts:
public int commonDigits(int x, int y) {
int count = 0;
int[] digits = new int[10];
while (x != 0) {
digits[x % 10]++;
x /= 10;
}
while (y != 0) {
if (digits[x % 10] > 0) {
count++;
digits[x % 10]--;
}
y /= 10;
}
return count;
}
This is your solution with the minimum storage (an array of 10 bytes instead of a hash table):
public int commonDigits(int x, int y) {
int count = 0;
byte[] digits=new byte[10];
while (x != 0) {
digits[x%10] ++;
x /= 10;
}
while (y != 0) {
if (digits[y % 10] > 0) {
count++;
digits[y % 10] --;
}
y /= 10;
}
return count;
}
The solution is optimum in running time O(n+m), where n is the number of digits in x and m is the number of digits in y. You cannot do less than enumerating the digits of x then the digits of y.
Since there are only 10 possible digits, why not just store an integer array? Indexed from 0-9, one for each digit. Loop through each digit and increment the corresponding array element. The space complexity of this depends on what you define to be "constant" - this will always take up 10 units of space (would be 10 bytes in C/C++, not sure how JVM does it)
By conservation of information, you have to loop through each digit of both numbers (they are independent so you can't just infer one from the other), so your time complexity will remain at O(m + n). Also I think by O(n) you really mean O(log n), as this is the number of digits in any representation of the number.
There is at maximum 10 digits that can be shared. This means you don't need a complicated data structure like Hashtable, an array or bitmask will suffice!
You would simply iterate over the first number, and every digit you hit is marked as "true" (in your bitmask or array). You can even short-circuit this and return early if you have found every digit once (which is easy and cheap with a bitmask). Then go over the second number. Every time you hit a digit that is also marked as true, increase the counter. If the bitmask contains every digit, short-circuit by returning the length of the number (its highest exponent), otherwise return the counter at the end.
This doesn't reduce O-complexity, but it reduces memory footprint and adds some short-circuits for large numbers.
For example, if the first number is 1234567890, then it will always share as many digits with the second number as the second number has decimal places.
A hash table is overkill, just use an array of ten flags (whether you pack them in a single integer with bitwise operations or keep independent variables is up to you).
Scan the first integer and raise the relevant flag for every digit.
Scan the second integer and reset the relevant flag for every digit.
Return the number of true resets (from 1 to 0).
Update: to deal with duplicates, the flags need to be replaced by counters.
If both numbers have M digits, they must all be looked at so that the time complexity is at certainly Ω(M).
The case of the space complexity is less clear. All solutions presented here are O(N), where N is the number of possible digits (10 in the decimal base). But O(1) space is possible: take every digit of the first number in turn, check if it is the first such digit in the first number (to avoid counting duplicates), then check if it exists in the second number. This is an O(M²)-time process, but O(1)-space only.
Update: to deal with duplicates, every time you process a digit, count the number of identical predecessors in the first number; when looking for a match in the second number, also match the number of predecessors.
So one may wonder if a O(M)-time, O(1)-space solution is possible.
My solution is O(M+N)-time, O(N)-space. The +N in the time complexity is only required for the initialization of all N flags. If you accept not to count the initialization, you can write the algorithm in such a way that it clears all the flags it has set (so that the algorithm can be played again) and this yields a O(M)-time, O(N)-space solution.
There is an easy O(M Log M)-time, O(M)-space solution, by sorting the two strings of digits and counting the identical digits in a merge-like step. Can be of use if M is very small compared to N.
Your solution doesn't account for duplicates.
# 11, 211 -> 2
You're right to use a hash, it's faster than an array. Gonna do this in python because it's faster to type...
# Returns an array containing the shared digits
def getShared(num1, num2):
shared = []
digits1 = getDigits(num1)
digits2 = getDigits(num2)
for digit in digits1:
if digit in digits2:
while digits2[digit] > 1 and digits1[digit] > 1:
digits2[digit] = digits2[digit] - 1
digits1[digit] = digits1[digit] - 1
shared += [digit]
del digits2[digit]
del digits1[digit]
return shared
# Given an integer, returns a dictionary with the keys as the digits,
# and the value as the number of times the digit appears
def getDigits(num)
dict = {}
while num > 0:
newDigit = num % 10
if newDigit not in dict:
dict[newDigit] = 1
else:
dict[newDigit] = dict[newDigit] + 1
return dict

Categories