#include <ctime>
#include <iostream>
// テスト用のmix(この関数は遅いよ!これより早いの作ってね!)
uint32_t mix_test(uint16_t a, uint16_t b) {
uint32_t o = 0;
for (int i = 0; i < 16; i++) {
if (a & (1 << i)) o |= 1 << (i * 2 + 0);
if (b & (1 << i)) o |= 1 << (i * 2 + 1);
}
return o;
}
// mixはaとbのbitを交互に詰めて返す。aが下位に来る。
// (例)
// a : 1111111111111111
// b : 0000000000000000
// o : 01010101010101010101010101010101
uint32_t mix1(uint16_t a, uint16_t b) {
// uint32_t a = a16;
// uint32_t b = b16;
return
(a & 0b1) << 0 | (a & 0b10) << 1| (a & 0b100) << 2| (a & 0b1000) << 3| (a & 0b10000) << 4| (a & 0b100000) << 5| (a & 0b1000000) << 6| (a & 0b10000000) << 7| (a & 0b100000000) << 8| (a & 0b1000000000) << 9| (a & 0b10000000000) << 10| (a & 0b100000000000) << 11| (a & 0b1000000000000) << 12| (a & 0b10000000000000) << 13| (a & 0b100000000000000) << 14| (a & 0b1000000000000000) << 15
|(b & 0b1) << 1 | (b & 0b10) << 2| (b & 0b100) << 3| (b & 0b1000) << 4| (b & 0b10000) << 5| (b & 0b100000) << 6| (b & 0b1000000) << 7| (b & 0b10000000) << 8| (b & 0b100000000) << 9| (b & 0b1000000000) << 10| (b & 0b10000000000) << 11| (b & 0b100000000000) << 12| (b & 0b1000000000000) << 13| (b & 0b10000000000000) << 14| (b & 0b100000000000000) << 15| (b & 0b1000000000000000) << 16;
}
// テスト
void test(uint32_t(*func)(uint16_t, uint16_t)) {
std::cout << "test...";
for (int i = 0; i < 100; i++) {
uint16_t a = rand(), b = rand();
if (func(a, b) != mix_test(a, b)) {
std::cout << "failed" << std::endl;
exit(EXIT_FAILURE);
}
}
std::cout << "passed!" << std::endl;
}
// ベンチマーク
void benchmark(uint32_t (*func)(uint16_t, uint16_t)) {
std::cout << "benchmark...";
uint32_t dammy = 0;
double start = clock();
for (int i = 0; i < 50000000; i++) dammy ^= func(rand(), rand());
double end = clock();
std::cout << "end! elapsed:" << (end - start) / CLOCKS_PER_SEC << "s " << dammy << std::endl;
}
int main() {
test(mix1);
benchmark(mix1);
return 0;
}
I2luY2x1ZGUgPGN0aW1lPgojaW5jbHVkZSA8aW9zdHJlYW0+CgovLyDjg4bjgrnjg4jnlKjjga5taXjvvIjjgZPjga7plqLmlbDjga/pgYXjgYTjgojvvIHjgZPjgozjgojjgorml6njgYTjga7kvZzjgaPjgabjga3vvIHvvIkKdWludDMyX3QgbWl4X3Rlc3QodWludDE2X3QgYSwgdWludDE2X3QgYikgewogICAgdWludDMyX3QgbyA9IDA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IDE2OyBpKyspIHsKICAgICAgICBpZiAoYSAmICgxIDw8IGkpKSBvIHw9IDEgPDwgKGkgKiAyICsgMCk7CiAgICAgICAgaWYgKGIgJiAoMSA8PCBpKSkgbyB8PSAxIDw8IChpICogMiArIDEpOwogICAgfQogICAgcmV0dXJuIG87Cn0KCi8vIG1peOOBr2Hjgahi44GuYml044KS5Lqk5LqS44Gr6Kmw44KB44Gm6L+U44GZ44CCYeOBjOS4i+S9jeOBq+adpeOCi+OAggovLyAo5L6LKQovLyBhIDogMTExMTExMTExMTExMTExMQovLyBiIDogMDAwMDAwMDAwMDAwMDAwMAovLyBvIDogMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEKdWludDMyX3QgbWl4MSh1aW50MTZfdCBhLCB1aW50MTZfdCBiKSB7CiAgICAvLyB1aW50MzJfdCBhID0gYTE2OwogICAgLy8gdWludDMyX3QgYiA9IGIxNjsKCiAgICByZXR1cm4KICAgIChhICYgMGIxKSA8PCAwIHwgKGEgJiAwYjEwKSA8PCAxfCAoYSAmIDBiMTAwKSA8PCAyfCAoYSAmIDBiMTAwMCkgPDwgM3wgKGEgJiAwYjEwMDAwKSA8PCA0fCAoYSAmIDBiMTAwMDAwKSA8PCA1fCAoYSAmIDBiMTAwMDAwMCkgPDwgNnwgKGEgJiAwYjEwMDAwMDAwKSA8PCA3fCAoYSAmIDBiMTAwMDAwMDAwKSA8PCA4fCAoYSAmIDBiMTAwMDAwMDAwMCkgPDwgOXwgKGEgJiAwYjEwMDAwMDAwMDAwKSA8PCAxMHwgKGEgJiAwYjEwMDAwMDAwMDAwMCkgPDwgMTF8IChhICYgMGIxMDAwMDAwMDAwMDAwKSA8PCAxMnwgKGEgJiAwYjEwMDAwMDAwMDAwMDAwKSA8PCAxM3wgKGEgJiAwYjEwMDAwMDAwMDAwMDAwMCkgPDwgMTR8IChhICYgMGIxMDAwMDAwMDAwMDAwMDAwKSA8PCAxNQogICB8KGIgJiAwYjEpIDw8IDEgfCAoYiAmIDBiMTApIDw8IDJ8IChiICYgMGIxMDApIDw8IDN8IChiICYgMGIxMDAwKSA8PCA0fCAoYiAmIDBiMTAwMDApIDw8IDV8IChiICYgMGIxMDAwMDApIDw8IDZ8IChiICYgMGIxMDAwMDAwKSA8PCA3fCAoYiAmIDBiMTAwMDAwMDApIDw8IDh8IChiICYgMGIxMDAwMDAwMDApIDw8IDl8IChiICYgMGIxMDAwMDAwMDAwKSA8PCAxMHwgKGIgJiAwYjEwMDAwMDAwMDAwKSA8PCAxMXwgKGIgJiAwYjEwMDAwMDAwMDAwMCkgPDwgMTJ8IChiICYgMGIxMDAwMDAwMDAwMDAwKSA8PCAxM3wgKGIgJiAwYjEwMDAwMDAwMDAwMDAwKSA8PCAxNHwgKGIgJiAwYjEwMDAwMDAwMDAwMDAwMCkgPDwgMTV8IChiICYgMGIxMDAwMDAwMDAwMDAwMDAwKSA8PCAxNjsKfQoKLy8g44OG44K544OICnZvaWQgdGVzdCh1aW50MzJfdCgqZnVuYykodWludDE2X3QsIHVpbnQxNl90KSkgewogICAgc3RkOjpjb3V0IDw8ICJ0ZXN0Li4uIjsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTAwOyBpKyspIHsKICAgICAgICB1aW50MTZfdCBhID0gcmFuZCgpLCBiID0gcmFuZCgpOwogICAgICAgIGlmIChmdW5jKGEsIGIpICE9IG1peF90ZXN0KGEsIGIpKSB7CiAgICAgICAgICAgIHN0ZDo6Y291dCA8PCAiZmFpbGVkIiA8PCBzdGQ6OmVuZGw7CiAgICAgICAgICAgIGV4aXQoRVhJVF9GQUlMVVJFKTsKICAgICAgICB9CiAgICB9CiAgICBzdGQ6OmNvdXQgPDwgInBhc3NlZCEiIDw8IHN0ZDo6ZW5kbDsKfQoKLy8g44OZ44Oz44OB44Oe44O844KvCnZvaWQgYmVuY2htYXJrKHVpbnQzMl90ICgqZnVuYykodWludDE2X3QsIHVpbnQxNl90KSkgewogICAgc3RkOjpjb3V0IDw8ICJiZW5jaG1hcmsuLi4iOwogICAgdWludDMyX3QgZGFtbXkgPSAwOwogICAgZG91YmxlIHN0YXJ0ID0gY2xvY2soKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNTAwMDAwMDA7IGkrKykgZGFtbXkgXj0gZnVuYyhyYW5kKCksIHJhbmQoKSk7CiAgICBkb3VibGUgZW5kID0gY2xvY2soKTsKICAgIHN0ZDo6Y291dCA8PCAiZW5kISBlbGFwc2VkOiIgPDwgKGVuZCAtIHN0YXJ0KSAvIENMT0NLU19QRVJfU0VDIDw8ICJzICIgPDwgZGFtbXkgPDwgc3RkOjplbmRsOwp9CgppbnQgbWFpbigpIHsKICAgIHRlc3QobWl4MSk7CiAgICBiZW5jaG1hcmsobWl4MSk7CiAgICByZXR1cm4gMDsKfQ==