Suppose we have two longs, x and y. What operator or function involving x and y would produce another long, z, which is least likely to be equal to the result of applying the same operator or function to different of x’s and y’s?
Ex: Addition would be a poor choice. 1+4=5, but 2+3 also equals 5.
EDIT: Let me explain why I’m asking this question. I’m creating a space rpg game. The game’s environment (solarsystems) will be procedurally generated from two seeds. These seeds consist of the x and y coordinates of the system in the universe. So there is a good probability that the player might encounter the systems at (500,501) and (501,500) over the course of his adventures. I need a way to these the solar systems generated unique. But also, I want to make sure that as many coordinate pairs as possible will produce unique seeds.
EDIT 2: I tested two of the solutions given to me. Accipitridae’s answer was far superior to Artelius’s answer. Here’s the code to test the solutions:
HashSet<Long> set = new HashSet<Long>();
for(int x=0; x<1000; x++)
for(int y=0; y<1000; y++)
//I commented out one of the solutions at a time
set.add((long)(((x&0x7FFFFFFF) << 33) | ((y&0x7FFFFFFF) << 2) | ((x>>>62) & 2) | (y>>>63)));//Artelius
set.add((long)(x - y * 7046029254386353131l));//Accipitridae
System.out.println(set.size());
From the size of the HashSet, I could tell how many unique seeds were generated through each method. For these parameters, Artelius’s solution generated 2048 unique longs, while Accipitridae’s generated 1000000, meaning that there were no collisions at all.
Thank you all for you effort in trying to solve this problem. 🙂
I like the answer and anlysis by Artelius. Especially the proposal to use
for some constant K is interesting and I’d like to just add a few more thoughts.
What I’m doing here is not new, but very closely related to the
Fibonacci hashing, which I think has been proposed by Knuth.
If we are using 64-bit integers then a collision f(x1, y1) = f(x2, y2) means
where dx = x1 – x2 and dy = y1 – y2. This is the same as
where dy-1 is the modular inverse modulo 264. If we want to choose the K such that f(x1, y1) != f(x2, y2) whenever the differences dx and dy are both small then we have to choose K such that
has no solution such that both dx and dy are small. This can be achieved for example by choosing
K close to phi * 264, where phi = (sqrt(5)-1)/2 is the golden ratio. The golden ratio has a very special continued fraction expansion, i.e. in a certain sense it is a number that is hard to approximate well with a fraction.
Hence, for 64-bit unsigned integers the following functions could be used
or equivalently when using signed 64-bit integers