Google Interview Question
Software EngineersCountry: United States
If integers are unsigned, just concatenate bits; if they are signed, reserve two bits for signes:
template<typename T>
T f(T x, T y) {
if constexpr (std::is_signed_v<T>) {
const bool is_neg_x = (x < 0);
const bool is_neg_y = (y < 0);
const T xy = (std::abs(x) << (4 * sizeof(T) - 1)) | std::abs(y);
return (xy << 2) | (is_neg_x ? 1 : 0) | (is_neg_y ? 2 : 0);
}
else
return (x << (4 * sizeof(T))) | y;
}
template<typename T>
std::pair<T, T> f_inv(T i) {
if constexpr (std::is_signed_v<T>) {
const bool is_neg_x = (i & 1);
const bool is_neg_y = (i & 2);
constexpr T mask = (T{1} << (4 * sizeof(T) - 1)) - 1;
const T x = (i >> (4 * sizeof(T) + 1)) & mask;
const T y = (i >> 2 ) & mask;
return {is_neg_x ? -x : x, is_neg_y ? -y : y};
}
else {
constexpr T mask = (T{1} << (4 * sizeof(T))) - 1;
return {i >> (4 * sizeof(T)), i & mask};
}
}
Concat x and y and add an extra number to know where to split the coordinates. Example: f((45,3))=4530 and f((4,53))=4531
- Anonymous September 30, 2019