/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
static int funnySum(long x, long y) {
int result = 0;
for (int i=0; i<32; ++i) {
int xNum = (int) (x & 3);
int yNum = (int) (y & 3);
result
+= Math.
abs(xNum
- yNum
);
x >>= 2;
y >>= 2;
}
return result;
}
static int freakySum(long a, long b) {
long result = a^b;
long is3 = result & result << 1; //high bit per pair will contain whether the pair is 3
is3 &= 0xaaaa_aaaa_aaaa_aaaaL; //extract the high bit per pair
long is0 = a&b;
is0 = ~(is0 | is0 << 1);//high bit per pair will contain whether the pair is 0
is0 &= 0xaaaa_aaaa_aaaa_aaaaL; //extract the high bit per pair
long notBoth0 = ~(a|a<<1) & ~(b|b<<1);
notBoth0 &= 0xaaaa_aaaa_aaaa_aaaaL; //extract the high bit per pair
result ^= is3 & is0 & notBoth0; // only invert the bits set in is3, is0 and notBoth0
result = (result & 0x3333_3333_3333_3333L) + ((result >> 2) & 0x3333_3333_3333_3333L);
result = (result & 0x0f0f_0f0f_0f0f_0f0fL) + ((result >> 4) & 0x0f0f_0f0f_0f0f_0f0fL);
result = (result & 0x00ff_00ff_00ff_00ffL) + ((result >> 8) & 0x00ff_00ff_00ff_00ffL);
result = (result & 0x0000_ffff_0000_ffffL) + ((result >> 16) & 0x0000_ffff_0000_ffffL);
result = (result & 0x0000_0000_ffff_ffffL) + ((result >> 32) & 0x0000_0000_ffff_ffffL);
return (int)(result&0xffL);
}
private static final long HIGH = 0xaaaa_aaaa_aaaa_aaaaL;
static int maaartySum(long x, long y) {
final long xor = x^y;
// high bit per pair will contain whether the pair is 3, low bit is garbled
final long is3 = xor & (xor << 1);
// high bit per pair will contain whether the pair is non-zero, low bit is garbled
final long x2 = x | (x << 1);
final long y2 = y | (y << 1);
// high bit per pair will contain whether both pairs are non-zero, low bit is garbled
final long is0 = x2 & y2;
// high bit per pair will contain whether the pairs need correction, low bit is 0
final long isBoth = (is3 & is0) & HIGH;
final long val = xor ^ isBoth; // only invert the bits set in both is3 and is0
// count the high bits twice
return Long.
bitCount(val
) + Long.
bitCount(val
& HIGH
); }
private static final long COMP = 0x1111111111111111L;
private static final long TWOBITS = 0x3333333333333333L;
private static final long THREEBITS = 0x7777777777777777L;
private static final long SIGNBIT = 0x4444444444444444L;
private static final long FOURSET = 0x0f0f0f0f0f0f0f0fL;
static long twoBitDiff(final long x, long y) {
// two's compliment on 2-bit sets of y - to make 3bit values.
// third bit is the sign bit.
y &= TWOBITS;
y ^= THREEBITS;
y += COMP;
long diff = (x & TWOBITS) + y;
// negate any negative results - (abs value)
// two's complement again
long sign = (diff & SIGNBIT) >>> 2;
diff ^= sign | (sign << 1);
diff += sign;
return diff & TWOBITS;
}
static int shiftySum(long x, long y) {
long diff = twoBitDiff(x, y) + twoBitDiff(x >>> 2, y >>> 2);
diff += diff >>> 4;
diff &= FOURSET;
diff += diff >>> 8;
diff += diff >>> 16;
diff += diff >>> 32;
return (int)(diff & 0xff);
}
private static final void testSum(long a, long b, boolean always) {
int fs = funnySum(a, b);
int ss = shiftySum(a, b);
int ks = freakySum(a, b);
int ms = maaartySum(a, b);
if (fs != ss || fs != ks || fs != ms || always) {
System.
out.
printf("%d -> %d funny %d shifty %d freaky %d maaarty %d\n",
a, b, funnySum(a, b), shiftySum(a, b), freakySum(a, b), maaartySum(a,b));
}
}
{
testSum(-1, 0, true);
testSum(0, -1, true);
testSum
(Long.
MIN_VALUE,
Long.
MAX_VALUE,
true); testSum
(Long.
MAX_VALUE,
0,
true); testSum
(Long.
MIN_VALUE,
0,
true); }
}