import
java.util.*;
class
Main {
private
static
final
int
SIZE = (
1
<<
16
);
private
static
int
[] GROUP_A(
int
x)
{
return
new
int
[] { x, x +
1
, x +
1
, x +
2
};
}
private
static
int
[] GROUP_B(
int
x)
{
return
new
int
[] {
GROUP_A(x)[
0
], GROUP_A(x)[
1
],
GROUP_A(x)[
2
], GROUP_A(x)[
3
],
GROUP_A(x +
1
)[
0
], GROUP_A(x +
1
)[
1
],
GROUP_A(x +
1
)[
2
], GROUP_A(x +
1
)[
3
],
GROUP_A(x +
1
)[
0
], GROUP_A(x +
1
)[
1
],
GROUP_A(x +
1
)[
2
], GROUP_A(x +
1
)[
3
],
GROUP_A(x +
2
)[
0
], GROUP_A(x +
2
)[
1
],
GROUP_A(x +
2
)[
2
], GROUP_A(x +
2
)[
3
],
};
}
private
static
int
[] GROUP_C(
int
x)
{
return
new
int
[] {
GROUP_B(x)[
0
], GROUP_B(x)[
1
],
GROUP_B(x)[
2
], GROUP_B(x)[
3
],
GROUP_B(x +
1
)[
0
], GROUP_B(x +
1
)[
1
],
GROUP_B(x +
1
)[
2
], GROUP_B(x +
1
)[
3
],
GROUP_B(x +
1
)[
0
], GROUP_B(x +
1
)[
1
],
GROUP_B(x +
1
)[
2
], GROUP_B(x +
1
)[
3
],
GROUP_B(x +
2
)[
0
], GROUP_B(x +
2
)[
1
],
GROUP_B(x +
2
)[
2
], GROUP_B(x +
2
)[
3
],
};
}
public
static
int
[] META_LOOK_UP(String parameter)
{
int
[] look_up =
new
int
[
256
];
switch
(parameter) {
case
"A"
:
for
(
int
i =
0
; i <
256
; i +=
2
) {
int
x = i + (i <<
8
);
look_up[i] = look_up[i +
1
] = GROUP_A(x)[
0
];
look_up[i +
2
] = look_up[i +
3
]
= GROUP_A(x)[
1
];
}
break
;
case
"B"
:
for
(
int
i =
0
; i <
256
; i +=
4
) {
int
x = i + (i <<
8
);
int
[] groupB = GROUP_B(x);
look_up[i] = groupB[
0
];
look_up[i +
1
] = groupB[
1
];
look_up[i +
2
] = groupB[
2
];
look_up[i +
3
] = groupB[
3
];
}
break
;
case
"C"
:
for
(
int
i =
0
; i <
256
; i +=
16
) {
int
x = i + (i <<
8
);
int
[] groupC = GROUP_C(x);
for
(
int
j =
0
; j <
16
; j++) {
look_up[i + j] = groupC[j];
}
}
break
;
default
:
throw
new
IllegalArgumentException(
"Invalid parameter: "
+ parameter);
}
return
look_up;
}
public
static
int
countSetBits(
int
[] array)
{
int
count =
0
;
int
[] look_up = META_LOOK_UP(
"C"
);
for
(
int
index =
0
; index < array.length; index++) {
count += look_up[array[index] &
0xff
];
count += look_up[(array[index] >>
8
) &
0xff
];
count += look_up[(array[index] >>
16
) &
0xff
];
count += look_up[(array[index] >>
24
) &
0xff
];
}
return
count;
}
public
static
void
main(String[] args)
{
final
int
SIZE = (
1
<<
16
);
int
[] random =
new
int
[SIZE];
for
(
int
i =
0
; i < SIZE; i++) {
random[i]
= (
int
)(Math.random() * Math.pow(
2
,
32
));
}
System.out.println(
"Total number of bits = "
+ countSetBits(random));
}
}