This question was asked in my interview.
random(0,1) is a function that generates integers 0 and 1 randomly.
Using this function how would you design a function that takes two integers a,b as input and generates random integers including a and b.
I have No idea how to solve this.
We can do this easily by bit logic (E,g, a=4 b=10)
Calculate difference b-a (for given e.g. 6)
Now calculate ceil(log(b-a+1)(Base 2)) i.e. no of bits required to represent all numbers b/w a and b
now call random(0,1) for each bit. (for given example range will be b/w 000 - 111)
do step 3 till the number(say num) is b/w 000 to 110(inclusive) i.e. we need only 7 levels since b-a+1 is 7.So there are 7 possible states a,a+1,a+2,... a+6 which is b.
return num + a.
I hate this kind of interview Question because there are some
answer fulfilling it but the interviewer will be pretty mad if you use them. For example,
Call random,
if you obtain 0, output a
if you obtain 1, output b
A more sophisticate answer, and probably what the interviewer wants is
init(a,b){
c = Max(a,b)
d = log2(c) //so we know how much bits we need to cover both a and b
}
Random(){
int r = 0;
for(int i = 0; i< d; i++)
r = (r<<1)| Random01();
return r;
}
You can generate random strings of 0 and 1 by successively calling the sub function.
So we have randomBit() returning 0 or 1 independently, uniformly at random and we want a function random(a, b) that returns a value in the range [a,b] uniformly at random. Let's actually make that the range [a, b) because half-open ranges are easier to work with and equivalent. In fact, it is easy to see that we can just consider the case where a == 0 (and b > 0), i.e. we just want to generate a random integer in the range [0, b).
Let's start with the simple answer suggested elsewhere. (Forgive me for using c++ syntax, the concept is the same in Java)
int random2n(int n) {
int ret = n ? randomBit() + (random2n(n - 1) << 1) : 0;
}
int random(int b) {
int n = ceil(log2(b)), v;
while ((v = random2n(n)) >= b);
return v;
}
That is-- it is easy to generate a value in the range [0, 2^n) given randomBit(). So to get a value in [0, b), we repeatedly generate something in the range [0, 2^ceil(log2(b))] until we get something in the correct range. It is rather trivial to show that this selects from the range [0, b) uniformly at random.
As stated before, the worst case expected number of calls to randomBit() for this is (1 + 1/2 + 1/4 + ...) ceil(log2(b)) = 2 ceil(log2(b)). Most of those calls are a waste, we really only need log2(n) bits of entropy and so we should try to get as close to that as possible. Even a clever implementation of this that calculates the high bits early and bails out as soon as it exits the wanted range has the same expected number of calls to randomBit() in the worst case.
We can devise a more efficient (in terms of calls to randomBit()) method quite easily. Let's say we want to generate a number in the range [0, b). With a single call to randomBit(), we should be able to approximately cut our target range in half. In fact, if b is even, we can do that. If b is odd, we will have a (very) small chance that we have to "re-roll". Consider the function:
int random(int b) {
if (b < 2) return 0;
int mid = (b + 1) / 2, ret = b;
while (ret == b) {
ret = (randomBit() ? mid : 0) + random(mid);
}
return ret;
}
This function essentially uses each random bit to select between two halves of the wanted range and then recursively generates a value in that half. While the function is fairly simple, the analysis of it is a bit more complex. By induction one can prove that this generates a value in the range [0, b) uniformly at random. Also, it can be shown that, in the worst case, this is expected to require ceil(log2(b)) + 2 calls to randomBit(). When randomBit() is slow, as may be the case for a true random generator, this is expected to waste only a constant number of calls rather than a linear amount as in the first solution.
function randomBetween(int a, int b){
int x = b-a;//assuming a is smaller than b
float rand = random();
return a+Math.ceil(rand*x);
}
Related
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 2 years ago.
Improve this question
How is the gcd function below working I do not understand what the ger varible does. Also what is the lcm varible doing I find this function hard to understand I am not good at math.
long lcm,hcf = 0;
long i=1;
// This sets ger to max(a,b) - why?
long ger=a>b?a:b;
// This would return a wrong result if a == b
// that never happens here, though
while(i<ger)
{
if((a%i==0) && (b%i==0))
hcf=i;
i++;
}
lcm=(a*b)/hcf;
return lcm;
Unfortunately, this is not a very good implementation of finding the Greatest Common Divisor (GCD). I suggest you look up Euclid's method on WikiPedia.
The way the above works is the program continues to divide both numbers by increasing values of i starting with 1. When both a and b are divisible by i, i is assigned to hcf and the loop continues until i exceeds the larger of a and b. The last assignment to hcf is the GCD.
The Least Common Multiple (LCM) is the smallest number that is divisible by both a and b and is computed mathematically as the product of a and b divided by their greatest common divisor.
The % sign in java means for a % i get the remainder. So if the remainder of both a and b when divided by i is zero, then i would be the GCD.
Updated Answer
Although I don't like the above approach, the idea can still be improved in several ways which I will identify and explain here. (Euclid's method would still be better).
Don't find the largest of a and b, find the smallest. Why keep iterating from or toward a larger termination point? No value larger than v will ever divide v. So stop as soon as the smaller value is exceeded.
Don't iterate starting at 1 and increasing toward the smaller number. Start with the smaller number and decrease until you hit the first successful test. That would be the GCD of both numbers.
Don't do this (a*b)/gcd to get the LCM. It is possible that a*b could overflow a long. Since it is known that the gcd divides both, divide one of the values by gcd and then multiply by the other.
Here is the code with the changes.
public static long lcm(long a, long b) {
// find min(a,b)
long hcf = a<b?a:b;
// just loop and decrement
for (;; hcf--) {
if((a%hcf==0) && (b%hcf==0)) {
// guaranteed to exit
// when hcf reaches 1
break;
}
}
return a*(b/hcf);
}
1) I do not understand what the ger variable does?
long ger = a > b ? a : b; is supposed to set an upper bound for the following while-loop.
However
as you've already noted, it's wrong in combination with the while-condition while(i < ger) (wrong result when a == b)
and actually taking the maximum of the two integers is not making any sense as the upper bound should be the min(a, b) as the greatest common divisor of them cannot be larger than their minimum.
The while-loop finds the GCD by finding incrementally the largest divisor i (= GCD) which divides a and b without any remainder, i.e (a % i == 0) && (b % i == 0).
2) Also what is the lcm variable doing?
The lcm variable is the Least Common Multiple of two integers and can be computed using the Greatest Common Divisor (GCD = HCF). Simply put, it's just a formula.
Conclusion
So, the purpose of this function is to compute the LCM by first computing the GCD and then applying the formula: a × b = gcd(a, b) × lcm(a, b) Proof ⟶ lcm(a, b) = a × b / gcd(a, b)
I want to generate an endless series of quasi random numbers to the following specification:-
Source of numbers is uniformly distributed and random, ranging 0 through 255 inclusive. It's an existing hardware device.
Required output range is 1 through 8 inclusive.
Two consecutive output numbers are never the same. For example 5 will never follow 5, but you can have 5,2,5.
Exactly one output number is required for every single source number. Rejection sampling therefore cannot be used. And while() loops, shuffles etc. can't be used.
It's this last stipulation that's vexing me. The source generator can only supply random bytes at a constant 1 /s and I want output at a constant 1 /s. Typically you'd simply reject a generated number if it was equal to the previous one, and generate another. In my case you only get one shot at each output. I think that it's some sort of random selection process, but this requirement has me going around in circles as I'm a bad programmer. An algorithm, flowchart or picture will do, but I'll be implementing in Java.
Apologies for the semi generic title, but I couldn't really think of anything more accurate yet concise.
If I understand the problem correctly, the first random number will be chosen randomly from among 8 different numbers (1 to 8), while every successive random number will be chosen from 7 different possibilities (1 to 8 excluding the previous one). Thus, your range of 256 values will need to be divided into 7 possibilities. It won't come out even, but that's the best you can do. So you need something like
public class RandomClass {
public RandomClass(HardwareSource source) {
this.source = source;
first = true;
}
pubic int nextRandom() {
int sourceValue = source.read();
int value;
if (first) {
value = sourceValue % 8 + 1;
prev = value;
} else {
value = sourceValue % 7 + 1;
if (value >= prev) {
value++;
}
prev = value;
first = false;
return value;
}
}
Suppose the first call generates 5. The second time you call it, value is first computed to be a number from 1 to 7; by incrementing it if the value is >= 5, the range of possible outputs becomes 1, 2, 3, 4, 6, 7, 8. The output will be almost evenly distributed between those two values. Since 256 is not divisible by 7, the distribution isn't quite even, and there will be a slight bias toward the lower numbers. You could fix it so that the bias will shift on each call and even out over the entire sequence; I believe one way is
value = (sourceValue + countGenerated) % 7 + 1;
where you keep track of how many numbers you've generated.
I think this is better than solutions that take the input modulo 8 and add 1 if the number equals the previous one. Those solutions will generate prev + 1 with twice the probability of generating other numbers, so it's more skewed than necessary.
int sum=0;
int prev=-1;
int next(int input){
sum=(sum+input)%8;
if(sum==prev)sum=(sum+1)%8;
prev=sum;
return sum+1;
}
(As I interpret even with the new bold emphasis, it is not required to always generate the same output value for the same input value - that would make the task impossible to solve)
This is a question regarding a piece of coursework so would rather you didn't fully answer the question but rather give tips to improve the run time complexity of my current algorithm.
I have been given the following information:
A function g(n) is given by g(n) = f(n,n) where f may be defined recursively by
I have implemented this algorithm recursively with the following code:
public static double f(int i, int j)
{
if (i == 0 && j == 0) {
return 0;
}
if (i ==0 || j == 0) {
return 1;
}
return ((f(i-1, j)) + (f(i-1, j-1)) + (f(i, j-1)))/3;
}
This algorithm gives the results I am looking for, but it is extremely inefficient and I am now tasked to improve the run time complexity.
I wrote an algorithm to create an n*n matrix and it then computes every element up to the [n][n] element in which it then returns the [n][n] element, for example f(1,1) would return 0.6 recurring. The [n][n] element is 0.6 recurring because it is the result of (1+0+1)/3.
I have also created a spreadsheet of the result from f(0,0) to f(7,7) which can be seen below:
Now although this is much faster than my recursive algorithm, it has a huge overhead of creating a n*n matrix.
Any suggestions to how I can improve this algorithm will be greatly appreciated!
I can now see that is it possible to make the algorithm O(n) complexity, but is it possible to work out the result without creating a [n][n] 2D array?
I have created a solution in Java that runs in O(n) time and O(n) space and will post the solution after I have handed in my coursework to stop any plagiarism.
This is another one of those questions where it's better to examine it, before diving in and writing code.
The first thing i'd say you should do is look at a grid of the numbers, and to not represent them as decimals, but fractions instead.
The first thing that should be obvious is that the total number of you have is just a measure of the distance from the origin, .
If you look at a grid in this way, you can get all of the denominators:
Note that the first row and column are not all 1s - they've been chosen to follow the pattern, and the general formula which works for all of the other squares.
The numerators are a little bit more tricky, but still doable. As with most problems like this, the answer is related to combinations, factorials, and then some more complicated things. Typical entries here include Catalan numbers, Stirling's numbers, Pascal's triangle, and you will nearly always see Hypergeometric functions used.
Unless you do a lot of maths, it's unlikely you're familiar with all of these, and there is a hell of a lot of literature. So I have an easier way to find out the relations you need, which nearly always works. It goes like this:
Write a naive, inefficient algorithm to get the sequence you want.
Copy a reasonably large amount of the numbers into google.
Hope that a result from the Online Encyclopedia of Integer Sequences pops up.
3.b. If one doesn't, then look at some differences in your sequence, or some other sequence related to your data.
Use the information you find to implement said sequence.
So, following this logic, here are the numerators:
Now, unfortunately, googling those yielded nothing. However, there are a few things you can notice about them, the main being that the first row/column are just powers of 3, and that the second row/column are one less than powers of three. This kind boundary is exactly the same as Pascal's triangle, and a lot of related sequences.
Here is the matrix of differences between the numerators and denominators:
Where we've decided that the f(0,0) element shall just follow the same pattern. These numbers already look much simpler. Also note though - rather interestingly, that these numbers follow the same rules as the initial numbers - except the that the first number is one (and they are offset by a column and a row). T(i,j) = T(i-1,j) + T(i,j-1) + 3*T(i-1,j-1):
1
1 1
1 5 1
1 9 9 1
1 13 33 13 1
1 17 73 73 17 1
1 21 129 245 192 21 1
1 25 201 593 593 201 25 1
This looks more like the sequences you see a lot in combinatorics.
If you google numbers from this matrix, you do get a hit.
And then if you cut off the link to the raw data, you get sequence A081578, which is described as a "Pascal-(1,3,1) array", which exactly makes sense - if you rotate the matrix, so that the 0,0 element is at the top, and the elements form a triangle, then you take 1* the left element, 3* the above element, and 1* the right element.
The question now is implementing the formulae used to generate the numbers.
Unfortunately, this is often easier said than done. For example, the formula given on the page:
T(n,k)=sum{j=0..n, C(k,j-k)*C(n+k-j,k)*3^(j-k)}
is wrong, and it takes a fair bit of reading the paper (linked on the page) to work out the correct formula. The sections you want are proposition 26, corollary 28. The sequence is mentioned in Table 2 after proposition 13. Note that r=4
The correct formula is given in proposition 26, but there is also a typo there :/. The k=0 in the sum should be a j=0:
Where T is the triangular matrix containing the coefficients.
The OEIS page does give a couple of implementations to calculate the numbers, but neither of them are in java, and neither of them can be easily transcribed to java:
There is a mathematica example:
Table[ Hypergeometric2F1[-k, k-n, 1, 4], {n, 0, 10}, {k, 0, n}] // Flatten
which, as always, is ridiculously succinct. And there is also a Haskell version, which is equally terse:
a081578 n k = a081578_tabl !! n !! k
a081578_row n = a081578_tabl !! n
a081578_tabl = map fst $ iterate
(\(us, vs) -> (vs, zipWith (+) (map (* 3) ([0] ++ us ++ [0])) $
zipWith (+) ([0] ++ vs) (vs ++ [0]))) ([1], [1, 1])
I know you're doing this in java, but i could not be bothered to transcribe my answer to java (sorry). Here's a python implementation:
from __future__ import division
import math
#
# Helper functions
#
def cache(function):
cachedResults = {}
def wrapper(*args):
if args in cachedResults:
return cachedResults[args]
else:
result = function(*args)
cachedResults[args] = result
return result
return wrapper
#cache
def fact(n):
return math.factorial(n)
#cache
def binomial(n,k):
if n < k: return 0
return fact(n) / ( fact(k) * fact(n-k) )
def numerator(i,j):
"""
Naive way to calculate numerator
"""
if i == j == 0:
return 0
elif i == 0 or j == 0:
return 3**(max(i,j)-1)
else:
return numerator(i-1,j) + numerator(i,j-1) + 3*numerator(i-1,j-1)
def denominator(i,j):
return 3**(i+j-1)
def A081578(n,k):
"""
http://oeis.org/A081578
"""
total = 0
for j in range(n-k+1):
total += binomial(k, j) * binomial(n-k, j) * 4**(j)
return int(total)
def diff(i,j):
"""
Difference between the numerator, and the denominator.
Answer will then be 1-diff/denom.
"""
if i == j == 0:
return 1/3
elif i==0 or j==0:
return 0
else:
return A081578(j+i-2,i-1)
def answer(i,j):
return 1 - diff(i,j) / denominator(i,j)
# And a little bit at the end to demonstrate it works.
N, M = 10,10
for i in range(N):
row = "%10.5f"*M % tuple([numerator(i,j)/denominator(i,j) for j in range(M)])
print row
print ""
for i in range(N):
row = "%10.5f"*M % tuple([answer(i,j) for j in range(M)])
print row
So, for a closed form:
Where the are just binomial coefficients.
Here's the result:
One final addition, if you are looking to do this for large numbers, then you're going to need to compute the binomial coefficients a different way, as you'll overflow the integers. Your answers are lal floating point though, and since you're apparently interested in large f(n) = T(n,n) then I guess you could use Stirling's approximation or something.
Well for starters here are some things to keep in mind:
This condition can only occur once, yet you test it every time through every loop.
if (x == 0 && y == 0) {
matrix[x][y] = 0;
}
You should instead: matrix[0][0] = 0; right before you enter your first loop and set x to 1. Since you know x will never be 0 you can remove the first part of your second condition x == 0 :
for(int x = 1; x <= i; x++)
{
for(int y = 0; y <= j; y++)
{
if (y == 0) {
matrix[x][y] = 1;
}
else
matrix[x][y] = (matrix[x-1][y] + matrix[x-1][y-1] + matrix[x][y-1])/3;
}
}
No point in declaring row and column since you only use it once. double[][] matrix = new double[i+1][j+1];
This algorithm has a minimum complexity of Ω(n) because you just need to multiply the values in the first column and row of the matrix with some factors and then add them up. The factors stem from unwinding the recursion n times.
However you therefore need to do the unwinding of the recursion. That itself has a complexity of O(n^2). But by balancing unwinding and evaluation of recursion, you should be able to reduce complexity to O(n^x) where 1 <= x <= 2. This is some kind of similiar to algorithms for matrix-matrix multiplication, where the naive case has a complexity of O(n^3) but Strassens's algorithm is for example O(n^2.807).
Another point is the fact that the original formula uses a factor of 1/3. Since this is not accurately representable by fixed point numbers or ieee 754 floating points, the error increases when evaluating the recursion successively. Therefore unwinding the recursion could give you higher accuracy as a nice side effect.
For example when you unwind the recursion sqr(n) times then you have complexity O((sqr(n))^2+(n/sqr(n))^2). The first part is for unwinding and the second part is for evaluating a new matrix of size n/sqr(n). That new complexity actually can be simplified to O(n).
To describe time complexity we usually use a big O notation. It is important to remember that it only describes the growth given the input. O(n) is linear time complexity, but it doesn't say how quickly (or slowly) the time grows when we increase input. For example:
n=3 -> 30 seconds
n=4 -> 40 seconds
n=5 -> 50 seconds
This is O(n), we can clearly see that every increase of n increases the time by 10 seconds.
n=3 -> 60 seconds
n=4 -> 80 seconds
n=5 -> 100 seconds
This is also O(n), even though for every n we need twice that much time, and the raise is 20 seconds for every increase of n, the time complexity grows linearly.
So if you have O(n*n) time complexity and you will half the number of operations you perform, you will get O(0.5*n*n) which is equal to O(n*n) - i.e. your time complexity won't change.
This is theory, in practice the number of operations sometimes makes a difference. Because you have a grid n by n, you need to fill n*n cells, so the best time complexity you can achieve is O(n*n), but there are a few optimizations you can do:
Cells on the edges of the grid could be filled in separate loops. Currently in majority of the cases you have two unnecessary conditions for i and j equal to 0.
You grid has a line of symmetry, you could utilize it to calculate only half of it and then copy the results onto the other half. For every i and j grid[i][j] = grid[j][i]
On final note, the clarity and readability of the code is much more important than performance - if you can read and understand the code, you can change it, but if the code is so ugly that you cannot understand it, you cannot optimize it. That's why I would do only first optimization (it also increases readability), but wouldn't do the second one - it would make the code much more difficult to understand.
As a rule of thumb, don't optimize the code, unless the performance is really causing problems. As William Wulf said:
More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity.
EDIT:
I think it may be possible to implement this function with O(1) complexity. Although it gives no benefits when you need to fill entire grid, with O(1) time complexity you can instantly get any value without having a grid at all.
A few observations:
denominator is equal to 3 ^ (i + j - 1)
if i = 2 or j = 2, numerator is one less than denominator
EDIT 2:
The numerator can be expressed with the following function:
public static int n(int i, int j) {
if (i == 1 || j == 1) {
return 1;
} else {
return 3 * n(i - 1, j - 1) + n(i - 1, j) + n(i, j - 1);
}
}
Very similar to original problem, but no division and all numbers are integers.
If the question is about how to output all values of the function for 0<=i<N, 0<=j<N, here is a solution in time O(N²) and space O(N). The time behavior is optimal.
Use a temporary array T of N numbers and set it to all ones, except for the first element.
Then row by row,
use a temporary element TT and set it to 1,
then column by column, assign simultaneously T[I-1], TT = TT, (TT + T[I-1] + T[I])/3.
Thanks to will's (first) answer, I had this idea:
Consider that any positive solution comes only from the 1's along the x and y axes. Each of the recursive calls to f divides each component of the solution by 3, which means we can sum, combinatorially, how many ways each 1 features as a component of the solution, and consider it's "distance" (measured as how many calls of f it is from the target) as a negative power of 3.
JavaScript code:
function f(n){
var result = 0;
for (var d=n; d<2*n; d++){
var temp = 0;
for (var NE=0; NE<2*n-d; NE++){
temp += choose(n,NE);
}
result += choose(d - 1,d - n) * temp / Math.pow(3,d);
}
return 2 * result;
}
function choose(n,k){
if (k == 0 || n == k){
return 1;
}
var product = n;
for (var i=2; i<=k; i++){
product *= (n + 1 - i) / i
}
return product;
}
Output:
for (var i=1; i<8; i++){
console.log("F(" + i + "," + i + ") = " + f(i));
}
F(1,1) = 0.6666666666666666
F(2,2) = 0.8148148148148148
F(3,3) = 0.8641975308641975
F(4,4) = 0.8879743941472337
F(5,5) = 0.9024030889600163
F(6,6) = 0.9123609205913732
F(7,7) = 0.9197747256986194
I have the following piece of code:
public class Main {
private static final Random rnd = new Random();
private static int getRand(int n) {
return (Math.abs(rnd.nextInt())%n);
}
public static void main(String[] args) {
int count=0, n = 2 * (Integer.MAX_VALUE/3);
for(int i=0; i<1000000; i++) {
if(getRand(n) < n/2) {
count++;
}
}
System.out.print(count);
}
}
This always gives me a number close to 666,666. Meaning two-thirds of the numbers generated are below the lower half of n. Not that this is obtained when n = 2/3 * Integer.MAX_VALUE. 4/7 is another fraction that gives me a similar spread (~5714285). However, I get an even spread if n = Integer.MAX_VALUE or if n = Integer.MAX_VALUE/2. How does this behavior differ with the fraction used. Can somebody throw some light on it.
PS: I got this problem from the book Effective Java by Joshua Bloch.
The problem is in the modulo (%) operator which results in an uneven distribution of numbers.
For example, imagine MAX_INT is 10, and n = 7, the mod operator will map the values 8, 9 and 10 to 1, 2 and 3, respectively. This will result that the numbers 1, 2 and 3 will have double the probability of all other numbers.
One way to solve this is by checking the output of rnd.nextInt() and try again while it's bigger than N.
You would get 50-50 if you kept only values of Math.abs(rnd.nextInt()) in the range of [0..2/3(Integer.MAX_VALUE)]. For the rest 1/3*Integer.MAX_VALUE numbers, due to modulo you will get a smaller number in the range of [0..1/3 Integer.MAX_VALUE].
All in all, numbers in the range of [0..1/3 Integer.MAX_VALUE] have double the chance to appear.
The Random class is designed to generate pseudo-random numbers. That means they are elements of a defined sequence that have an uniform distribution. If you don't know the sequence, they seem to be random.
Having said that, the problem is that you mess up the uniform distribution you get by using the modulus operator. On coding horror, there is a very nice article that explains this issue, although for a slightly different problem. Now, you can find a solution to your problem along with a proof here.
As observed above, getRand does not generate uniformly distributed random numbers over the range [0, n].
In general, suppose that n = a * Integer.MAX_VALUE / b, where a/b > 0.5
For ease of writing, let M = Integer.MAX_VALUE
The Probability Density Function (PDF) of getRand(n) is given by:
PDF(x) = 2/M for 0 < x < (b-a)M/b
= 1/M for (b-a)M/b < x < aM/b
n/2 corresponds to the mid-point of the range [0, aM/b] = aM/2b
Integrating the PDF over the 'first-half' range [0, n/2] we find that the probability (P) that getRand(n) is less than n/2 is given by:
P = a/b
Examples:
a=2, b=3. P = 2/3 = 2/3 = 0.66666... as computed by the questioner.
a=4, b=7. P = 4/7 = 0.5714... close to the questioner's computational result.
I am trying to come up with a solution to the problem that given two numbers, find if they are the consecutive numbers in the gray code sequence i.e., if they are gray code neighbors assuming that the gray code sequence is not mentioned.
I searched on various forums but couldn't get the right answer. It would be great if you can provide a solution for this.
My attempt to the problem - Convert two integers to binary and add the digits in both the numbers separately and find the difference between the sum of the digits in two numbers. If the difference is one then they are gray code neighbors.
But I feel this wont work for all cases. Any help is highly appreciated. Thanks a lot in advance!!!
Actually, several of the other answers seem wrong: it's true that two binary reflected Gray code neighbours differ by only one bit (I assume that by « the » Gray code sequence, you mean the original binary reflected Gray code sequence as described by Frank Gray). However, that does not mean that two Gray codes differing by one bit are neighbours (a => b does not mean that b => a). For example, the Gray codes 1000 and 1010 differ by only one bit but are not neighbours (1000 and 1010 are respectively 15 and 12 in decimal).
If you want to know whether two Gray codes a and b are neighbours, you have to check whether previous(a) = b OR next(a) = b. For a given Gray code, you get one neighbour by flipping the rightmost bit and the other neighbour bit by flipping the bit at the left of the rightmost set bit. For the Gray code 1010, the neighbours are 1011 and 1110 (1000 is not one of them).
Whether you get the previous or the next neighbour by flipping one of these bits actually depends on the parity of the Gray code. However, since we want both neighbours, we don't have to check for parity. The following pseudo-code should tell you whether two Gray codes are neighbours (using C-like bitwise operations):
function are_gray_neighbours(a: gray, b: gray) -> boolean
return b = a ^ 1 OR
b = a ^ ((a & -a) << 1)
end
Bit trick above: a & -a isolates the rigthmost set bit in a number. We shift that bit by one position to the left to get the bit we need to flip.
Assumptions:
Inputs a and b are grey code sequences in binary reflected gray code.
i.e a's and b's bit encoding is binary gray code representations.
#convert from greycode bits into regular binary bits
def gTob(num): #num is binary graycode
mask = num >> 1
while mask!=0:
num = num^mask
mask >>= 1
return num; #num is converted
#check if a and b are consecutive gray code encodings
def areGrayNeighbors(a,b):
return abs(gTob(a) - gTob(b)) == 1
Few Test cases:
areGrayNeighbors(9,11) --> True (since (1001, 1011) differ in only one
bit and are consecutive numbers in decimal representation)
areGrayNeighbors(9,10) --> False
areGrayNeighbors(14,10) --> True
References:
method gTob() used above is from rodrigo in this post The neighbors in Gray code
public int checkConsecutive2(int b1, int b2){
int x = (b1 ^ b2);
if((x & (x - 1)) !=0){
return 0;
}else{
return 1;
}
}
If two numbers are in gray code sequence, they differ by one binary digit. i.e the exclusive OR on the two numbers returns a power of 2. So, find XOR and check if the result is a power of two.
This solution works well for the all the test cases written by CodeKaichu above. I would love to know if it fails in any cases.
public boolean grayCheck(int x, int y) {
int z = x^y;
return (z&z-1)==0;
}
An obvious answer, but it works.
Convert each gray code into its respective Binary form, subtract the two. If you answer is a binary equivalent of +1 or -1 then the two gray codes are adjacent.
This seems like an over kill, but when you're siting in an interview and don't know the correct method, this works. Also to optimize, one can check the single bit difference filter, so we don't waste time converting and subtracting numbers that we know for sure aren't adjacent.
If you just want to check if the input numbers differ by just one bit:
public boolean checkIfDifferByOneBit(int a, int b){
int diff = 0;
while(a > 0 && b > 0){
if(a & 1 != b & 1)
diff++;
a = a >> 1;
b = b >> 1;
}
if (a > 0 || b > 0) // a correction in the solution provided by David Jones
return diff == 0 // In the case when a or b become zero before the other
return diff == 1;
}
You can check if two numbers differ by one bit or not as follows. In this method, difference in the length of binary numbers are taken care of. Eg, the output for 11 (1011) and 3 (11) will be returned as true.
Also, this does not solve the second criteria for Gray code adjacency. But if you only want to check if the numbers differ by one bit, the code below will help.
class Graycode{
public static boolean graycheck(int one, int two){
int differences = 0;
while (one > 0 || two > 0){
// Checking if the rightmost bit is same
if ((one & 1) != (two & 1)){
differences++;
}
one >>= 1;
two >>= 1;
}
return differences == 1;
}
public static void main(String[] args){
int one = Integer.parseInt(args[0]);
int two = Integer.parseInt(args[1]);
System.out.println(graycheck(one,two));
}
}
If two numbers are in gray code sequence, they differ by one binary digit. i.e the exclusive OR on the two numbers returns a power of 2. So, find XOR and check if the result is a power of two.
python 3.8
a=int(input())
b=int(input())
x=a^b
if((x and (not(x & (x - 1))) )):
print("True")
else:
print("False")
I've had to solve this question in an interview as well. One of the conditions for the two values to be a gray code sequence is that their values only differ by 1 bit. Here is a solution to this problem:
def isGrayCode(num1, num2):
differences = 0
while (num1 > 0 or num2 > 0):
if ((num1 & 1) != (num2 & 1)):
differences++
num1 >>= 1
num2 >>= 1
return differences == 1