0

I have two numbers fields in the db. One with max 15 digits (say x), and the other one with maximum 5 digits (say y). I need to produce unique number from any pair (x,y), such that for any other pair (w,z), k(x,y) = k(w,z) if and only if x=w and y=z.

Note: I read about Cantor function but since i have a known limit on the number length, i'd like to use a more efficient function to generate the shortest possible key.

axelrod
  • 3,782
  • 1
  • 20
  • 25
  • Pretty much a duplicate - [Hash Value for 3D Vector](http://stackoverflow.com/questions/31951502/hash-value-for-3d-vector). Yes, 2D vs 3D, but the answers there still holds for 2D. – Bernhard Barker Sep 24 '15 at 12:15

3 Answers3

0

Just concatenate them together. k(111111111111111,22222) = 11111111111111122222. Be sure to include leading zeroes: k(3,4) = 300004. If you leave them out, then k(3,4) will have the same result as k(0,34).

By the pigeonhole principle, if you want perfect uniqueness, you can't do any better than 15+5 digits.

Kevin
  • 74,910
  • 12
  • 133
  • 166
  • Combine them isn't enough because 15 and 5 is an upper bound only. It can be that x is 3 and y is 6, or x is 4 and y is 5, and then 3+6=5+4=9 – axelrod Sep 24 '15 at 12:17
  • By concatenate I don't mean addition, I mean laying them out side by side. k(3,6) = 300006. k(4,5) = 400005. – Kevin Sep 24 '15 at 12:18
  • But how did you define the number of zeros between them? – axelrod Sep 24 '15 at 12:19
  • there's always four digits separating x's least significant digit and y's least significant digit. The arithmetic formula would be `k(x,y) = (x*10^5) + y` – Kevin Sep 24 '15 at 12:21
0

Lets say that x could hold the numbers between 0 - 4 and y could hold the numbers between 0 - 3 then you could create a grid like so

  x  0  1  2  3  4
 y----------------  
 0|  0  1  2  3  4
 1|  5  6  7  8  9
 2| 10 11 12 13 14
 3| 15 16 17 18 19

Given an (x, y) you would find the unique number by doing x + 5y

For example, (3, 2) would be 3 + 5*2 = 13, and if you check the grid you will see that 13 is the column where the x label is 3 and in the row where the y label is 2.

Going back the other way, given a number lets say 16 then x = 16 modulo 5 = 1 and y = (16 - x) / 5 = 3

You can see from the grid that in column 1 row 3 is the number 16.

To extend it to your question your x holds the values between 0 - 999999999999999 and your y holds the values between 0 - 99999

so your formula would be

(x, y) = 1000000000000000*y + x

DanL
  • 1,974
  • 14
  • 13
  • In the other answer it says i can do the oposite (k(x,y) = (x*10^5) + y) and get a shorter result. Is that not enough from uniqueness? – axelrod Sep 24 '15 at 12:29
  • I could have did the same thing with my small grid and made it have 4 columns and 5 rows (instead of 5 columns and 4 rows). Either way you would still have 5 * 4 = 4 * 5 = 20 grid entries. Applying that to your case you still going to get 10^5 * 10^15 grid entries. – DanL Sep 24 '15 at 12:34
0

I would store second number's length in a first digit, then two digits concatenated, it's easy and will work in every case. Since the second number is 5 digits max, then our first digit can store that.

without it if you want concatenate 23 and 45 it will be same result as 234 and 5, the same case with zeroes between them.

example:

k(3,4) = 134
k(30,4) = 1304
k(3,40) = 2340
k(3333,4) = 133334
k(3,4321) = 434321

expression for f(x,y) would be:

n*(10^(n+m))+x*(10^n)+y 
    where 
n = log10(y)+1 m = log10(x)+1 (n and m are integer floor)
Zbigniew Kisły
  • 692
  • 1
  • 6
  • 12