001package squidpony.squidmath;
002
003/**
004 * A group of similar methods for getting hashes of points based on long coordinates in 2, 3, 4, or 6 dimensions and
005 * a long for state; like {@link PointHash} but faster and maybe not as high-quality. This implementation has
006 * high enough quality to be useful as a source of random numbers based on positions, but would likely not be a good
007 * option in a hash table (or at least not as good as the tailored implementation of {@link Coord#hashCode()}, for
008 * instance). At low dimensions, this is a little faster than {@link PointHash}, but this class doesn't slow 
009 * down much at all as more dimensions are used, while PointHash and most other implementations do slow down. You
010 * can also consider {@link IntPointHash} if your input and output types are usually int, since it's even faster.
011 * <br>
012 * This implements {@link IPointHash} and has a long it uses internally for state, exposed by {@link #getState()}.
013 */
014public final class HastyPointHash extends IPointHash.LongImpl
015{
016    @Override
017    public int hashWithState(int x, int y, int state) {
018        return (int)hashAll(x, y, state);
019    }
020
021    @Override
022    public int hashWithState(int x, int y, int z, int state) {
023        return (int)hashAll(x, y, z, state);
024    }
025
026    @Override
027    public int hashWithState(int x, int y, int z, int w, int state) {
028        return (int)hashAll(x, y, z, w, state);
029    }
030
031    @Override
032    public int hashWithState(int x, int y, int z, int w, int u, int v, int state) {
033        return (int)hashAll(x, y, z, w, u, v, state);
034    }
035    
036    public long getState(){
037        return state;
038    }
039
040    /**
041     * Gets a 64-bit point hash of a 2D point (x and y are both longs) and a state/seed as a long. This point
042     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
043     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
044     * <br>
045     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
046     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
047     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
048     * generalized ratio. See
049     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
050     * for some more information on how he uses this, but we do things differently because we want random-seeming
051     * results instead of separated sub-random results.
052     * @param x x position; any long
053     * @param y y position; any long
054     * @param s the state/seed; any long
055     * @return 64-bit hash of the x,y point with the given state
056     */
057    public static long hashAll(long x, long y, long s) {
058        y += s * 0xD1B54A32D192ED03L;
059        x += y * 0xABC98388FB8FAC03L;
060        s += x * 0x8CB92BA72F3D8DD7L;
061        return ((s = (s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) ^ s >>> 25);
062    }
063
064    /**
065     * Gets a 64-bit point hash of a 3D point (x, y, and z are all longs) and a state/seed as a long. This point
066     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
067     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
068     * <br>
069     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
070     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
071     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
072     * generalized ratio. See
073     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
074     * for some more information on how he uses this, but we do things differently because we want random-seeming
075     * results instead of separated sub-random results.
076     * @param x x position; any long
077     * @param y y position; any long
078     * @param z z position; any long
079     * @param s the state/seed; any long
080     * @return 64-bit hash of the x,y,z point with the given state
081     */
082    public static long hashAll(long x, long y, long z, long s) {
083        z += s * 0xDB4F0B9175AE2165L;
084        y += z * 0xBBE0563303A4615FL;
085        x += y * 0xA0F2EC75A1FE1575L;
086        s += x * 0x89E182857D9ED689L;
087        return ((s = (s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) ^ s >>> 25);
088    }
089
090    /**
091     * Gets a 64-bit point hash of a 4D point (x, y, z, and w are all longs) and a state/seed as a long. This point
092     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
093     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
094     * <br>
095     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
096     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
097     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
098     * generalized ratio. See
099     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
100     * for some more information on how he uses this, but we do things differently because we want random-seeming
101     * results instead of separated sub-random results.
102     * @param x x position; any long
103     * @param y y position; any long
104     * @param z z position; any long
105     * @param w w position; any long
106     * @param s the state; any long
107     * @return 64-bit hash of the x,y,z,w point with the given state
108     */
109    public static long hashAll(long x, long y, long z, long w, long s) {
110        w += s * 0xE19B01AA9D42C633L;
111        z += w * 0xC6D1D6C8ED0C9631L;
112        y += z * 0xAF36D01EF7518DBBL;
113        x += y * 0x9A69443F36F710E7L;
114        s += x * 0x881403B9339BD42DL;
115        return ((s = (s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) ^ s >>> 25);
116    }
117
118    /**
119     * Gets a 64-bit point hash of a 6D point (x, y, z, w, u, and v are all longs) and a state/seed as a long. This
120     * point hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
121     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
122     * <br>
123     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
124     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
125     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
126     * generalized ratio. See
127     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
128     * for some more information on how he uses this, but we do things differently because we want random-seeming
129     * results instead of separated sub-random results.
130     * @param x x position; any long
131     * @param y y position; any long
132     * @param z z position; any long
133     * @param w w position; any long
134     * @param u u position; any long
135     * @param v v position; any long
136     * @param s the state; any long
137     * @return 64-bit hash of the x,y,z,w,u,v point with the given state
138     */
139    public static long hashAll(long x, long y, long z, long w, long u, long v, long s) {
140        v += s * 0xE95E1DD17D35800DL;
141        u += v * 0xD4BC74E13F3C782FL;
142        w += u * 0xC1EDBC5B5C68AC25L;
143        z += w * 0xB0C8AC50F0EDEF5DL;
144        y += z * 0xA127A31C56D1CDB5L;
145        x += y * 0x92E852C80D153DB3L;
146        s += x * 0x85EB75C3024385C3L;
147        return ((s = (s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) ^ s >>> 25);
148    }
149    /**
150     * Gets an 8-bit point hash of a 2D point (x and y are both longs) and a state/seed as a long. This point
151     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
152     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
153     * <br>
154     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
155     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
156     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
157     * generalized ratio. See
158     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
159     * for some more information on how he uses this, but we do things differently because we want random-seeming
160     * results instead of separated sub-random results.
161     * @param x x position; any long
162     * @param y y position; any long
163     * @param s the state/seed; any long
164     * @return 8-bit hash of the x,y point with the given state
165     */
166    public static int hash256(long x, long y, long s) {
167        y += s * 0xD1B54A32D192ED03L;
168        x += y * 0xABC98388FB8FAC03L;
169        s += x * 0x8CB92BA72F3D8DD7L;
170        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 56);
171    }
172
173    /**
174     * Gets an 8-bit point hash of a 3D point (x, y, and z are all longs) and a state/seed as a long. This point
175     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
176     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
177     * <br>
178     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
179     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
180     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
181     * generalized ratio. See
182     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
183     * for some more information on how he uses this, but we do things differently because we want random-seeming
184     * results instead of separated sub-random results.
185     * @param x x position; any long
186     * @param y y position; any long
187     * @param z z position; any long
188     * @param s the state/seed; any long
189     * @return 8-bit hash of the x,y,z point with the given state
190     */
191    public static int hash256(long x, long y, long z, long s) {
192        z += s * 0xDB4F0B9175AE2165L;
193        y += z * 0xBBE0563303A4615FL;
194        x += y * 0xA0F2EC75A1FE1575L;
195        s += x * 0x89E182857D9ED689L;
196        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 56);
197    }
198
199    /**
200     * Gets an 8-bit point hash of a 4D point (x, y, z, and w are all longs) and a state/seed as a long. This point
201     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
202     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
203     * <br>
204     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
205     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
206     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
207     * generalized ratio. See
208     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
209     * for some more information on how he uses this, but we do things differently because we want random-seeming
210     * results instead of separated sub-random results.
211     * @param x x position; any long
212     * @param y y position; any long
213     * @param z z position; any long
214     * @param w w position; any long
215     * @param s the state; any long
216     * @return 8-bit hash of the x,y,z,w point with the given state
217     */
218    public static int hash256(long x, long y, long z, long w, long s) {
219        w += s * 0xE19B01AA9D42C633L;
220        z += w * 0xC6D1D6C8ED0C9631L;
221        y += z * 0xAF36D01EF7518DBBL;
222        x += y * 0x9A69443F36F710E7L;
223        s += x * 0x881403B9339BD42DL;
224        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 56);
225    }
226
227    /**
228     * Gets an 8-bit point hash of a 6D point (x, y, z, w, u, and v are all longs) and a state/seed as a long. This
229     * point hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
230     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
231     * <br>
232     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
233     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
234     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
235     * generalized ratio. See
236     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
237     * for some more information on how he uses this, but we do things differently because we want random-seeming
238     * results instead of separated sub-random results.
239     * @param x x position; any long
240     * @param y y position; any long
241     * @param z z position; any long
242     * @param w w position; any long
243     * @param u u position; any long
244     * @param v v position; any long
245     * @param s the state; any long
246     * @return 8-bit hash of the x,y,z,w,u,v point with the given state
247     */
248    public static int hash256(long x, long y, long z, long w, long u, long v, long s) {
249        v += s * 0xE95E1DD17D35800DL;
250        u += v * 0xD4BC74E13F3C782FL;
251        w += u * 0xC1EDBC5B5C68AC25L;
252        z += w * 0xB0C8AC50F0EDEF5DL;
253        y += z * 0xA127A31C56D1CDB5L;
254        x += y * 0x92E852C80D153DB3L;
255        s += x * 0x85EB75C3024385C3L;
256        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 56);
257    }
258    /**
259     * Gets a 5-bit point hash of a 2D point (x and y are both longs) and a state/seed as a long. This point
260     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
261     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
262     * <br>
263     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
264     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
265     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
266     * generalized ratio. See
267     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
268     * for some more information on how he uses this, but we do things differently because we want random-seeming
269     * results instead of separated sub-random results.
270     * @param x x position; any long
271     * @param y y position; any long
272     * @param s the state/seed; any long
273     * @return 5-bit hash of the x,y point with the given state
274     */
275    public static int hash32(long x, long y, long s) {
276        y += s * 0xD1B54A32D192ED03L;
277        x += y * 0xABC98388FB8FAC03L;
278        s += x * 0x8CB92BA72F3D8DD7L;
279        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 59);
280    }
281
282    /**
283     * Gets a 5-bit point hash of a 3D point (x, y, and z are all longs) and a state/seed as a long. This point
284     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
285     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
286     * <br>
287     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
288     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
289     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
290     * generalized ratio. See
291     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
292     * for some more information on how he uses this, but we do things differently because we want random-seeming
293     * results instead of separated sub-random results.
294     * @param x x position; any long
295     * @param y y position; any long
296     * @param z z position; any long
297     * @param s the state/seed; any long
298     * @return 5-bit hash of the x,y,z point with the given state
299     */
300    public static int hash32(long x, long y, long z, long s) {
301        z += s * 0xDB4F0B9175AE2165L;
302        y += z * 0xBBE0563303A4615FL;
303        x += y * 0xA0F2EC75A1FE1575L;
304        s += x * 0x89E182857D9ED689L;
305        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 59);
306    }
307
308    /**
309     * Gets a 5-bit point hash of a 4D point (x, y, z, and w are all longs) and a state/seed as a long. This point
310     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
311     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
312     * <br>
313     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
314     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
315     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
316     * generalized ratio. See
317     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
318     * for some more information on how he uses this, but we do things differently because we want random-seeming
319     * results instead of separated sub-random results.
320     * @param x x position; any long
321     * @param y y position; any long
322     * @param z z position; any long
323     * @param w w position; any long
324     * @param s the state; any long
325     * @return 5-bit hash of the x,y,z,w point with the given state
326     */
327    public static int hash32(long x, long y, long z, long w, long s) {
328        w += s * 0xE19B01AA9D42C633L;
329        z += w * 0xC6D1D6C8ED0C9631L;
330        y += z * 0xAF36D01EF7518DBBL;
331        x += y * 0x9A69443F36F710E7L;
332        s += x * 0x881403B9339BD42DL;
333        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 59);
334    }
335
336    /**
337     * Gets a 5-bit point hash of a 6D point (x, y, z, w, u, and v are all longs) and a state/seed as a long. This
338     * point hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
339     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
340     * <br>
341     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
342     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
343     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
344     * generalized ratio. See
345     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
346     * for some more information on how he uses this, but we do things differently because we want random-seeming
347     * results instead of separated sub-random results.
348     * @param x x position; any long
349     * @param y y position; any long
350     * @param z z position; any long
351     * @param w w position; any long
352     * @param u u position; any long
353     * @param v v position; any long
354     * @param s the state; any long
355     * @return 5-bit hash of the x,y,z,w,u,v point with the given state
356     */
357    public static int hash32(long x, long y, long z, long w, long u, long v, long s) {
358        v += s * 0xE95E1DD17D35800DL;
359        u += v * 0xD4BC74E13F3C782FL;
360        w += u * 0xC1EDBC5B5C68AC25L;
361        z += w * 0xB0C8AC50F0EDEF5DL;
362        y += z * 0xA127A31C56D1CDB5L;
363        x += y * 0x92E852C80D153DB3L;
364        s += x * 0x85EB75C3024385C3L;
365        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 59);
366    }
367    
368    /**
369     * Gets a 6-bit point hash of a 2D point (x and y are both longs) and a state/seed as a long. This point
370     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
371     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
372     * <br>
373     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
374     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
375     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
376     * generalized ratio. See
377     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
378     * for some more information on how he uses this, but we do things differently because we want random-seeming
379     * results instead of separated sub-random results.
380     * @param x x position; any long
381     * @param y y position; any long
382     * @param s the state/seed; any long
383     * @return 6-bit hash of the x,y point with the given state
384     */
385    public static int hash64(long x, long y, long s) {
386        y += s * 0xD1B54A32D192ED03L;
387        x += y * 0xABC98388FB8FAC03L;
388        s += x * 0x8CB92BA72F3D8DD7L;
389        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 58);
390    }
391
392    /**
393     * Gets a 6-bit point hash of a 3D point (x, y, and z are all longs) and a state/seed as a long. This point
394     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
395     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
396     * <br>
397     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
398     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
399     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
400     * generalized ratio. See
401     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
402     * for some more information on how he uses this, but we do things differently because we want random-seeming
403     * results instead of separated sub-random results.
404     * @param x x position; any long
405     * @param y y position; any long
406     * @param z z position; any long
407     * @param s the state/seed; any long
408     * @return 6-bit hash of the x,y,z point with the given state
409     */
410    public static int hash64(long x, long y, long z, long s) {
411        z += s * 0xDB4F0B9175AE2165L;
412        y += z * 0xBBE0563303A4615FL;
413        x += y * 0xA0F2EC75A1FE1575L;
414        s += x * 0x89E182857D9ED689L;
415        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 58);
416    }
417
418    /**
419     * Gets a 6-bit point hash of a 4D point (x, y, z, and w are all longs) and a state/seed as a long. This point
420     * hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
421     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
422     * <br>
423     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
424     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
425     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
426     * generalized ratio. See
427     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
428     * for some more information on how he uses this, but we do things differently because we want random-seeming
429     * results instead of separated sub-random results.
430     * @param x x position; any long
431     * @param y y position; any long
432     * @param z z position; any long
433     * @param w w position; any long
434     * @param s the state; any long
435     * @return 6-bit hash of the x,y,z,w point with the given state
436     */
437    public static int hash64(long x, long y, long z, long w, long s) {
438        w += s * 0xE19B01AA9D42C633L;
439        z += w * 0xC6D1D6C8ED0C9631L;
440        y += z * 0xAF36D01EF7518DBBL;
441        x += y * 0x9A69443F36F710E7L;
442        s += x * 0x881403B9339BD42DL;
443        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 58);
444    }
445
446    /**
447     * Gets a 6-bit point hash of a 6D point (x, y, z, w, u, and v are all longs) and a state/seed as a long. This
448     * point hash has close to the best speed of any algorithms tested, and though its quality is mediocre for
449     * traditional uses of hashing (such as hash tables), it's sufficiently random to act as a positional RNG.
450     * <br>
451     * This uses a technique related to the one used by Martin Roberts for his golden-ratio-based sub-random
452     * sequences, where each axis is multiplied by a different constant, and the choice of constants depends on the
453     * number of axes but is always related to a generalized form of golden ratios, repeatedly dividing 1.0 by the
454     * generalized ratio. See
455     * <a href="http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/">Roberts' article</a>
456     * for some more information on how he uses this, but we do things differently because we want random-seeming
457     * results instead of separated sub-random results.
458     * @param x x position; any long
459     * @param y y position; any long
460     * @param z z position; any long
461     * @param w w position; any long
462     * @param u u position; any long
463     * @param v v position; any long
464     * @param s the state; any long
465     * @return 6-bit hash of the x,y,z,w,u,v point with the given state
466     */
467    public static int hash64(long x, long y, long z, long w, long u, long v, long s) {
468        v += s * 0xE95E1DD17D35800DL;
469        u += v * 0xD4BC74E13F3C782FL;
470        w += u * 0xC1EDBC5B5C68AC25L;
471        z += w * 0xB0C8AC50F0EDEF5DL;
472        y += z * 0xA127A31C56D1CDB5L;
473        x += y * 0x92E852C80D153DB3L;
474        s += x * 0x85EB75C3024385C3L;
475        return (int)(((s ^ s >>> 27 ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L) >>> 58);
476    }
477
478    public static int hash256_alt(final long x, final long y, final long z, final long w, final long seed) {
479        long a = 0x632BE59BD9B4E019L;
480        return (int) ((0x9E3779B97F4A7C15L
481                + (a ^= 0x85157AF5L * seed + x)
482                + (a ^= 0x85157AF5L * x + y)
483                + (a ^= 0x85157AF5L * y + z)
484                + (a ^= 0x85157AF5L * z + w)
485                + (a ^= 0x85157AF5L * w + seed)) * a >>> 56);
486    }
487
488}