001package squidpony.squidmath;
002
003/**
004 * A relatively simple {@link IPointHash} that multiplies each of the x, y, etc. components and the state by a different
005 * constant for each (a "harmonious number" related to the golden ratio), sums them, and keeps only the upper bits.
006 * This benefits from dot-product optimizations performed by recent JVMs (since at least Java 8). It finishes each hash
007 * with an XLCG step to improve the upper bits, then it right-shifts the whole long so it fits in the desired output
008 * range (such as 8 bits for {@link #hash256(int, int, int)}), casts it to int and returns that.
009 * <br>
010 * This hash is slightly faster for some noise applications than {@link IntPointHash}, and has comparable quality, but
011 * does require a lot of math on long values, and that can be quite slow on GWT. This should probably be used primarily
012 * on desktop targets, and/or maybe mobile.
013 */
014public final class GoldPointHash extends IPointHash.IntImpl {
015
016    @Override
017    public int hashWithState(int x, int y, int state) {
018        return hashAll(x, y, state);
019    }
020
021    @Override
022    public int hashWithState(int x, int y, int z, int state) {
023        return 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 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 hashAll(x, y, z, w, u, v, state);
034    }
035
036    /**
037     * A 32-bit-result point hash that uses multiplication with long constants.
038     * @param x x position, as an int
039     * @param y y position, as an int
040     * @param s any int, a seed to be able to produce many hashes for a given point
041     * @return 32-bit hash of the x,y point with the given state s
042     */
043    public static int hashAll(int x, int y, int s) {
044        return (int)((0xD1B54A32D192ED03L * x + 0xABC98388FB8FAC03L * y + -0x8CB92BA72F3D8DD7L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 32);
045    }
046    /**
047     * A 32-bit-result point hash that uses multiplication with long constants.
048     * @param x x position, as an int
049     * @param y y position, as an int
050     * @param z z position, as an int
051     * @param s any int, a seed to be able to produce many hashes for a given point
052     * @return 32-bit hash of the x,y,z point with the given state s
053     */
054    public static int hashAll(int x, int y, int z, int s) {
055        return (int)((0xDB4F0B9175AE2165L * x + 0xBBE0563303A4615FL * y + -0xA0F2EC75A1FE1575L * z + 0x89E182857D9ED689L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 32);
056    }
057
058    /**
059     * A 32-bit-result point hash that uses multiplication with long constants.
060     * @param x x position, as an int
061     * @param y y position, as an int
062     * @param z z position, as an int
063     * @param w w position, as an int
064     * @param s any int, a seed to be able to produce many hashes for a given point
065     * @return 32-bit hash of the x,y,z,w point with the given state s
066     */
067    public static int hashAll(int x, int y, int z, int w, int s) {
068        return (int)((0xE19B01AA9D42C633L * x + 0xC6D1D6C8ED0C9631L * y + -0xAF36D01EF7518DBBL * z +
069                0x9A69443F36F710E7L * w + -0x881403B9339BD42DL * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 32);
070    }
071
072    /**
073     * A 32-bit-result point hash that uses multiplication with long constants.
074     * @param x x position, as an int
075     * @param y y position, as an int
076     * @param z z position, as an int
077     * @param w w position, as an int
078     * @param u u position, as an int
079     * @param v v position, as an int
080     * @param s any int, a seed to be able to produce many hashes for a given point
081     * @return 32-bit hash of the x,y,z,w,u,v point with the given state s
082     */
083    public static int hashAll(int x, int y, int z, int w, int u, int v, int s) {
084        return (int)((0xE95E1DD17D35800DL * x + 0xD4BC74E13F3C782FL * y + -0xC1EDBC5B5C68AC25L * z +
085                0xB0C8AC50F0EDEF5DL * w + -0xA127A31C56D1CDB5L * u + 0x92E852C80D153DB3L * v -
086                0x85EB75C3024385C3L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 32);
087    }
088
089    /**
090     * A 8-bit point hash that smashes x and y into s using XOR and multiplications by harmonious numbers,
091     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
092     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
093     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
094     * been stripped down heavily, both for speed and because unless points are selected specifically to target
095     * flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
096     * @param x x position, as an int
097     * @param y y position, as an int
098     * @param s any int, a seed to be able to produce many hashes for a given point
099     * @return 8-bit hash of the x,y point with the given state s
100     */
101    public static int hash256(int x, int y, int s) {
102        return (int)((0xD1B54A32D192ED03L * x + 0xABC98388FB8FAC03L * y + -0x8CB92BA72F3D8DD7L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 56);
103    }
104    /**
105     * A 8-bit point hash that smashes x, y, and z into s using XOR and multiplications by harmonious numbers,
106     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
107     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
108     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
109     * been stripped down heavily, both for speed and because unless points are selected specifically to target
110     flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
111     * @param x x position, as an int
112     * @param y y position, as an int
113     * @param z z position, as an int
114     * @param s any int, a seed to be able to produce many hashes for a given point
115     * @return 8-bit hash of the x,y,z point with the given state s
116     */
117    public static int hash256(int x, int y, int z, int s) {
118        return (int)((0xDB4F0B9175AE2165L * x + 0xBBE0563303A4615FL * y + -0xA0F2EC75A1FE1575L * z + 0x89E182857D9ED689L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 56);
119    }
120
121    /**
122     * A 8-bit point hash that smashes x, y, z, and w into s using XOR and multiplications by harmonious numbers,
123     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
124     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
125     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
126     * been stripped down heavily, both for speed and because unless points are selected specifically to target
127     * flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
128     * @param x x position, as an int
129     * @param y y position, as an int
130     * @param z z position, as an int
131     * @param w w position, as an int
132     * @param s any int, a seed to be able to produce many hashes for a given point
133     * @return 8-bit hash of the x,y,z,w point with the given state s
134     */
135    public static int hash256(int x, int y, int z, int w, int s) {
136        return (int)((0xE19B01AA9D42C633L * x + 0xC6D1D6C8ED0C9631L * y + -0xAF36D01EF7518DBBL * z +
137                0x9A69443F36F710E7L * w + -0x881403B9339BD42DL * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 56);
138    }
139
140    /**
141     * A 8-bit point hash that smashes x, y, z, w, u, and v into s using XOR and multiplications by harmonious
142     * numbers, then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash,
143     * especially for ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by
144     * Pelle Evensen's rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary
145     * hash used here has been stripped down heavily, both for speed and because unless points are selected
146     * specifically to target flaws in the hash, it doesn't need the intense resistance to bad inputs that
147     * rrxmrrxmsx_0 has.
148     * @param x x position, as an int
149     * @param y y position, as an int
150     * @param z z position, as an int
151     * @param w w position, as an int
152     * @param u u position, as an int
153     * @param v v position, as an int
154     * @param s any int, a seed to be able to produce many hashes for a given point
155     * @return 8-bit hash of the x,y,z,w,u,v point with the given state s
156     */
157    public static int hash256(int x, int y, int z, int w, int u, int v, int s) {
158        return (int)((0xE95E1DD17D35800DL * x + 0xD4BC74E13F3C782FL * y + -0xC1EDBC5B5C68AC25L * z +
159                0xB0C8AC50F0EDEF5DL * w + -0xA127A31C56D1CDB5L * u + 0x92E852C80D153DB3L * v -
160                0x85EB75C3024385C3L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 56);
161    }
162
163    /**
164     * A 6-bit point hash that smashes x and y into s using XOR and multiplications by harmonious numbers,
165     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
166     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
167     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
168     * been stripped down heavily, both for speed and because unless points are selected specifically to target
169     * flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
170     * @param x x position, as an int
171     * @param y y position, as an int
172     * @param s any int, a seed to be able to produce many hashes for a given point
173     * @return 6-bit hash of the x,y point with the given state s
174     */
175    public static int hash64(int x, int y, int s) {
176        return (int)((0xD1B54A32D192ED03L * x + 0xABC98388FB8FAC03L * y + -0x8CB92BA72F3D8DD7L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 58);
177    }
178    /**
179     * A 6-bit point hash that smashes x, y, and z into s using XOR and multiplications by harmonious numbers,
180     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
181     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
182     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
183     * been stripped down heavily, both for speed and because unless points are selected specifically to target
184     flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
185     * @param x x position, as an int
186     * @param y y position, as an int
187     * @param z z position, as an int
188     * @param s any int, a seed to be able to produce many hashes for a given point
189     * @return 6-bit hash of the x,y,z point with the given state s
190     */
191    public static int hash64(int x, int y, int z, int s) {
192        return (int)((0xDB4F0B9175AE2165L * x + 0xBBE0563303A4615FL * y + -0xA0F2EC75A1FE1575L * z + 0x89E182857D9ED689L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 58);
193    }
194
195    /**
196     * A 6-bit point hash that smashes x, y, z, and w into s using XOR and multiplications by harmonious numbers,
197     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
198     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
199     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
200     * been stripped down heavily, both for speed and because unless points are selected specifically to target
201     * flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
202     * @param x x position, as an int
203     * @param y y position, as an int
204     * @param z z position, as an int
205     * @param w w position, as an int
206     * @param s any int, a seed to be able to produce many hashes for a given point
207     * @return 6-bit hash of the x,y,z,w point with the given state s
208     */
209    public static int hash64(int x, int y, int z, int w, int s) {
210        return (int)((0xE19B01AA9D42C633L * x + 0xC6D1D6C8ED0C9631L * y + -0xAF36D01EF7518DBBL * z +
211                0x9A69443F36F710E7L * w + -0x881403B9339BD42DL * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 58);
212    }
213
214    /**
215     * A 6-bit point hash that smashes x, y, z, w, u, and v into s using XOR and multiplications by harmonious
216     * numbers, then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash,
217     * especially for ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by
218     * Pelle Evensen's rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary
219     * hash used here has been stripped down heavily, both for speed and because unless points are selected
220     * specifically to target flaws in the hash, it doesn't need the intense resistance to bad inputs that
221     * rrxmrrxmsx_0 has.
222     * @param x x position, as an int
223     * @param y y position, as an int
224     * @param z z position, as an int
225     * @param w w position, as an int
226     * @param u u position, as an int
227     * @param v v position, as an int
228     * @param s any int, a seed to be able to produce many hashes for a given point
229     * @return 6-bit hash of the x,y,z,w,u,v point with the given state s
230     */
231    public static int hash64(int x, int y, int z, int w, int u, int v, int s) {
232        return (int)((0xE95E1DD17D35800DL * x + 0xD4BC74E13F3C782FL * y + -0xC1EDBC5B5C68AC25L * z +
233                0xB0C8AC50F0EDEF5DL * w + -0xA127A31C56D1CDB5L * u + 0x92E852C80D153DB3L * v -
234                0x85EB75C3024385C3L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 58);
235    }
236    /**
237     * A 5-bit point hash that smashes x and y into s using XOR and multiplications by harmonious numbers,
238     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
239     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
240     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
241     * been stripped down heavily, both for speed and because unless points are selected specifically to target
242     * flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
243     * @param x x position, as an int
244     * @param y y position, as an int
245     * @param s any int, a seed to be able to produce many hashes for a given point
246     * @return 5-bit hash of the x,y point with the given state s
247     */
248    public static int hash32(int x, int y, int s) {
249        return (int)((0xD1B54A32D192ED03L * x + 0xABC98388FB8FAC03L * y + -0x8CB92BA72F3D8DD7L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 59);
250    }
251    /**
252     * A 5-bit point hash that smashes x, y, and z into s using XOR and multiplications by harmonious numbers,
253     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
254     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
255     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
256     * been stripped down heavily, both for speed and because unless points are selected specifically to target
257     flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
258     * @param x x position, as an int
259     * @param y y position, as an int
260     * @param z z position, as an int
261     * @param s any int, a seed to be able to produce many hashes for a given point
262     * @return 5-bit hash of the x,y,z point with the given state s
263     */
264    public static int hash32(int x, int y, int z, int s) {
265        return (int)((0xDB4F0B9175AE2165L * x + 0xBBE0563303A4615FL * y + -0xA0F2EC75A1FE1575L * z + 0x89E182857D9ED689L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 59);
266    }
267
268    /**
269     * A 5-bit point hash that smashes x, y, z, and w into s using XOR and multiplications by harmonious numbers,
270     * then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash, especially for
271     * ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by Pelle Evensen's
272     * rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary hash used here has
273     * been stripped down heavily, both for speed and because unless points are selected specifically to target
274     * flaws in the hash, it doesn't need the intense resistance to bad inputs that rrxmrrxmsx_0 has.
275     * @param x x position, as an int
276     * @param y y position, as an int
277     * @param z z position, as an int
278     * @param w w position, as an int
279     * @param s any int, a seed to be able to produce many hashes for a given point
280     * @return 5-bit hash of the x,y,z,w point with the given state s
281     */
282    public static int hash32(int x, int y, int z, int w, int s) {
283        return (int)((0xE19B01AA9D42C633L * x + 0xC6D1D6C8ED0C9631L * y + -0xAF36D01EF7518DBBL * z +
284                0x9A69443F36F710E7L * w + -0x881403B9339BD42DL * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 59);
285    }
286
287    /**
288     * A 5-bit point hash that smashes x, y, z, w, u, and v into s using XOR and multiplications by harmonious
289     * numbers, then runs a simple unary hash on s and returns it. Has better performance than HastyPointHash,
290     * especially for ints, and has slightly fewer collisions in a hash table of points. GWT-optimized. Inspired by
291     * Pelle Evensen's rrxmrrxmsx_0 unary hash, though this doesn't use its code or its full algorithm. The unary
292     * hash used here has been stripped down heavily, both for speed and because unless points are selected
293     * specifically to target flaws in the hash, it doesn't need the intense resistance to bad inputs that
294     * rrxmrrxmsx_0 has.
295     * @param x x position, as an int
296     * @param y y position, as an int
297     * @param z z position, as an int
298     * @param w w position, as an int
299     * @param u u position, as an int
300     * @param v v position, as an int
301     * @param s any int, a seed to be able to produce many hashes for a given point
302     * @return 5-bit hash of the x,y,z,w,u,v point with the given state s
303     */
304    public static int hash32(int x, int y, int z, int w, int u, int v, int s) {
305        return (int)((0xE95E1DD17D35800DL * x + 0xD4BC74E13F3C782FL * y + -0xC1EDBC5B5C68AC25L * z +
306                0xB0C8AC50F0EDEF5DL * w + -0xA127A31C56D1CDB5L * u + 0x92E852C80D153DB3L * v -
307                0x85EB75C3024385C3L * s ^ 0x9E3779B97F4A7C15L) * 0xC6BC279692B5CC83L >>> 59);
308    }
309
310
311}