If you have sets Si
, i=1..n
of size Ci = |Si|
, then the cartesian product set S = S1 x S2 x ... x Sn
has size C = C1 * C2 * ... * Cn
.
This motivates an obvious way to do the packing one-to-one. If you have elements e1,...,en
from each set, each in the range 0
to Ci-1
, then you give the element e=(e1,...,en)
the value e1+C1*(e2 + C2*(e3 + C3*(...Cn*en...)))
.
You can do any permutation of this packing if you feel like it, but unless the values are perfectly correlated, the size of the full set must be the product of the sizes of the component sets.
In the particular case of three 32 bit integers, if they can take on any value, you should treat them as one 96 bit integer.
If you particularly want to, you can map small values to small values through any number of means (e.g. filling out spheres with the L1 norm), but you have to specify what properties you want to have.
(For example, one can map (n,m)
to (max(n,m)-1)^2 + k
where k=n
if n<=m
and k=n+m
if n>m
--you can draw this as a picture of filling in a square like so:
1 2 5 | draw along the edge of the square this way
4 3 6 v
8 7
if you start counting from 1
and only worry about positive values; for integers, you can spiral around the origin.)