Last active
December 9, 2018 04:33
-
-
Save YSRKEN/fe4e105f3b9e9e66e525d21404de0e93 to your computer and use it in GitHub Desktop.
地上最速の「大石泉すき」判定コードを書いてみた ref: https://qiita.com/YSRKEN/items/2f1603df95af3dc00ef6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <chrono> | |
using namespace std; | |
using namespace std::chrono; | |
const size_t LOOP_COUNT = 10000; | |
int judge_hand(const int digit[]) { | |
// ロイヤルストレートフラッシュ | |
if (digit[0] == 0 && digit[1] == 1 && digit[2] == 2 && digit[3] == 3 && digit[4] == 4) | |
return 0; | |
// ファイブカード | |
if (digit[0] == digit[1] && digit[1] == digit[2] && digit[2] == digit[3] && digit[3] == digit[4]) | |
return 1; | |
// フォーカード | |
int count[] = {0, 0, 0, 0, 0}; | |
for (int i = 0; i < 5; ++i){ | |
++count[digit[i]]; | |
} | |
for (int i = 0; i < 5; ++i){ | |
if (count[i] == 4) | |
return 2; | |
} | |
// ストレートフラッシュ | |
bool flg = true; | |
for (int i = 0; i < 5; ++i){ | |
if (count[i] == 0) { | |
flg = false; | |
break; | |
} | |
} | |
if (flg) { | |
return 3; | |
} | |
// フルハウス | |
bool flg_2 = false; | |
bool flg_3 = false; | |
for (int i = 0; i < 5; ++i){ | |
if (count[i] == 2) { | |
flg_2 = true; | |
continue; | |
} | |
if (count[i] == 3) { | |
flg_3 = true; | |
continue; | |
} | |
} | |
if (flg_2 && flg_3) { | |
return 4; | |
} | |
// すき | |
if (digit[0] == 3 && digit[1] == 4) | |
return 5; | |
if (digit[1] == 3 && digit[2] == 4) | |
return 5; | |
if (digit[2] == 3 && digit[3] == 4) | |
return 5; | |
if (digit[3] == 3 && digit[4] == 4) | |
return 5; | |
// スリーカード | |
if (flg_3) { | |
return 6; | |
} | |
// ツーペア | |
if (flg_2) { | |
int digit_count = 0; | |
for (int i = 0; i < 5; ++i){ | |
if (count[i] != 0) { | |
++digit_count; | |
} | |
} | |
if (digit_count == 3) { | |
return 7; | |
} | |
} | |
return 99; | |
} | |
int main() | |
{ | |
cout << "ループ回数:" << LOOP_COUNT << "回" << endl; | |
auto start = system_clock::now(); | |
volatile int result = 99; | |
int digit[] = {0, 0, 0, 0, 0}; | |
for (size_t n = 0; n < LOOP_COUNT; ++n) { | |
for (size_t i1 = 0; i1 < 5; ++i1){ | |
digit[0] = i1; | |
for (size_t i2 = 0; i2 < 5; ++i2){ | |
digit[1] = i2; | |
for (size_t i3 = 0; i3 < 5; ++i3){ | |
digit[2] = i3; | |
for (size_t i4 = 0; i4 < 5; ++i4){ | |
digit[3] = i4; | |
for (size_t i5 = 0; i5 < 5; ++i5){ | |
digit[4] = i5; | |
result = 99; | |
}}}}} | |
} | |
auto dur = system_clock::now() - start; | |
auto nanosec = std::chrono::duration_cast<std::chrono::nanoseconds>(dur).count(); | |
cout << "ループ自体の時間:" << nanosec << "ナノ秒(" << (1.0 * nanosec / LOOP_COUNT / 5 / 5 / 5 / 5 / 5) << "ナノ秒/回)" << endl; | |
start = system_clock::now(); | |
for (size_t n = 0; n < LOOP_COUNT; ++n) { | |
for (size_t i1 = 0; i1 < 5; ++i1){ | |
digit[0] = i1; | |
for (size_t i2 = 0; i2 < 5; ++i2){ | |
digit[1] = i2; | |
for (size_t i3 = 0; i3 < 5; ++i3){ | |
digit[2] = i3; | |
for (size_t i4 = 0; i4 < 5; ++i4){ | |
digit[3] = i4; | |
for (size_t i5 = 0; i5 < 5; ++i5){ | |
digit[4] = i5; | |
result = judge_hand(digit); | |
}}}}} | |
} | |
dur = system_clock::now() - start; | |
auto nanosec2 = std::chrono::duration_cast<std::chrono::nanoseconds>(dur).count() - nanosec; | |
cout << "計算時間:" << nanosec2 << "ナノ秒(" << (1.0 * nanosec2 / LOOP_COUNT / 5 / 5 / 5 / 5 / 5) << "ナノ秒/回)" << endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int judge_hand_fast(volatile int digit[]) { | |
// 各数字の出現回数 | |
int count[] = {0, 0, 0, 0, 0}; | |
for (int i = 0; i < 5; ++i) | |
++count[digit[i]]; | |
// 出現回数の出現回数 | |
int count2[] = {0, 0, 0, 0, 0, 0}; | |
for (int i = 0; i < 5; ++i) | |
++count2[count[i]]; | |
// 判定 | |
if (count2[1] == 5) { | |
if (digit[0] == 0 && digit[1] == 1 && digit[2] == 2 && digit[3] == 3 && digit[4] == 4) | |
// ロイヤルストレートフラッシュ | |
return 0; | |
else | |
// ストレートフラッシュ | |
return 3; | |
} | |
// ファイブカード | |
if (count2[5] == 1) | |
return 1; | |
// フォーカード | |
if (count2[4] == 1) | |
return 2; | |
// フルハウス | |
if (count2[3] == 1 && count2[2] == 1) | |
return 4; | |
// すき | |
if (digit[0] == 3 && digit[1] == 4) | |
return 5; | |
if (digit[1] == 3 && digit[2] == 4) | |
return 5; | |
if (digit[2] == 3 && digit[3] == 4) | |
return 5; | |
if (digit[3] == 3 && digit[4] == 4) | |
return 5; | |
// スリーカード | |
if (count2[3] == 1) | |
return 6; | |
if (count2[2] == 2) | |
return 7; | |
return 99; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int judge_hand_fast2(volatile int digit[]) { | |
// 各数字の出現回数 | |
int count[] = {0, 0, 0, 0, 0}; | |
for (int i = 0; i < 5; ++i) | |
++count[digit[i]]; | |
// 出現回数の出現回数 | |
int count2[] = {0, 0, 0, 0, 0, 0}; | |
for (int i = 0; i < 5; ++i) | |
++count2[count[i]]; | |
// 判定 | |
// ツーペア・すき | |
if (count2[2] == 2){ | |
// すき | |
if (digit[0] == 3 && digit[1] == 4) | |
return 5; | |
if (digit[1] == 3 && digit[2] == 4) | |
return 5; | |
if (digit[2] == 3 && digit[3] == 4) | |
return 5; | |
if (digit[3] == 3 && digit[4] == 4) | |
return 5; | |
// ツーペア | |
return 7; | |
} | |
// スリーカード・すき・フルハウス | |
if (count2[3] == 1){ | |
// すき | |
bool sukiFlg = false; | |
if (digit[0] == 3 && digit[1] == 4) | |
sukiFlg = true; | |
else if (digit[1] == 3 && digit[2] == 4) | |
sukiFlg = true; | |
else if (digit[2] == 3 && digit[3] == 4) | |
sukiFlg = true; | |
else if (digit[3] == 3 && digit[4] == 4) | |
sukiFlg = true; | |
// フルハウス | |
if (count2[2] == 1) | |
return 4; | |
if (sukiFlg) | |
return 5; | |
// スリーカード | |
return 6; | |
} | |
// すき | |
bool sukiFlg = false; | |
if (digit[0] == 3 && digit[1] == 4) | |
sukiFlg = true; | |
else if (digit[1] == 3 && digit[2] == 4) | |
sukiFlg = true; | |
else if (digit[2] == 3 && digit[3] == 4) | |
sukiFlg = true; | |
else if (digit[3] == 3 && digit[4] == 4) | |
sukiFlg = true; | |
// ストレートフラッシュ・ロイヤルストレートフラッシュ | |
if (count2[1] == 5) { | |
if (digit[0] == 0 && digit[1] == 1 && digit[2] == 2 && digit[3] == 3 && digit[4] == 4) | |
// ロイヤルストレートフラッシュ | |
return 0; | |
else | |
// ストレートフラッシュ | |
return 3; | |
} | |
// フォーカード | |
if (count2[4] == 1) | |
return 2; | |
// ファイブカード | |
if (count2[5] == 1) | |
return 1; | |
if (sukiFlg) | |
return 5; | |
return 99; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int cache[3125] = {}; | |
// 判定用関数 | |
int judge_hand_fast3(const int digit[]) { | |
return cache[digit[0]*5*5*5*5+digit[1]*5*5*5+digit[2]*5*5+digit[3]*5+digit[4]]; | |
} | |
// 使用前の初期化 | |
for (size_t i1 = 0; i1 < 5; ++i1){ | |
digit[0] = i1; | |
for (size_t i2 = 0; i2 < 5; ++i2){ | |
digit[1] = i2; | |
for (size_t i3 = 0; i3 < 5; ++i3){ | |
digit[2] = i3; | |
for (size_t i4 = 0; i4 < 5; ++i4){ | |
digit[3] = i4; | |
for (size_t i5 = 0; i5 < 5; ++i5){ | |
digit[4] = i5; | |
cache[i1*5*5*5*5+i2*5*5*5+i3*5*5+i4*5+i5] = judge_hand(digit); | |
}}}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline uint32_t calc_bitboard(const int index){ | |
return 1 << (index * 3); | |
} | |
int judge_hand_fast4(const int digit[]) { | |
// 各数字の出現回数をビットボードを利用してカウント | |
uint32_t count_board = 0; | |
count_board += calc_bitboard(digit[0]); | |
count_board += calc_bitboard(digit[1]); | |
count_board += calc_bitboard(digit[2]); | |
count_board += calc_bitboard(digit[3]); | |
count_board += calc_bitboard(digit[4]); | |
const int count_0 = count_board & 0x7; | |
const int count_1 = (count_board >> 3) & 0x7; | |
const int count_2 = (count_board >> 6) & 0x7; | |
const int count_3 = (count_board >> 9) & 0x7; | |
const int count_4 = (count_board >> 12) & 0x7; | |
// 各数字の出現回数の出現回数をビットボードを利用してカウント | |
count_board = 0; | |
count_board += calc_bitboard(count_0); | |
count_board += calc_bitboard(count_1); | |
count_board += calc_bitboard(count_2); | |
count_board += calc_bitboard(count_3); | |
count_board += calc_bitboard(count_4); | |
const int count2_0 = count_board & 0x7; | |
const int count2_1 = (count_board >> 3) & 0x7; | |
const int count2_2 = (count_board >> 6) & 0x7; | |
const int count2_3 = (count_board >> 9) & 0x7; | |
const int count2_4 = (count_board >> 12) & 0x7; | |
const int count2_5 = (count_board >> 15) & 0x7; | |
// 判定 | |
// ツーペア・すき | |
if (count2_2 == 2){ | |
// すき | |
if (digit[0] == 3 && digit[1] == 4) | |
return 5; | |
if (digit[1] == 3 && digit[2] == 4) | |
return 5; | |
if (digit[2] == 3 && digit[3] == 4) | |
return 5; | |
if (digit[3] == 3 && digit[4] == 4) | |
return 5; | |
// ツーペア | |
return 7; | |
} | |
// スリーカード・すき・フルハウス | |
if (count2_3 == 1){ | |
// フルハウス | |
if (count2_2 == 1) | |
return 4; | |
// すき | |
bool sukiFlg = false; | |
if (digit[0] == 3 && digit[1] == 4) | |
return 5; | |
else if (digit[1] == 3 && digit[2] == 4) | |
return 5; | |
else if (digit[2] == 3 && digit[3] == 4) | |
return 5; | |
else if (digit[3] == 3 && digit[4] == 4) | |
return 5; | |
// スリーカード | |
return 6; | |
} | |
// ストレートフラッシュ・ロイヤルストレートフラッシュ | |
if (count2_1 == 5) { | |
if (digit[0] == 0 && digit[1] == 1 && digit[2] == 2 && digit[3] == 3 && digit[4] == 4) | |
// ロイヤルストレートフラッシュ | |
return 0; | |
else | |
// ストレートフラッシュ | |
return 3; | |
} | |
// フォーカード | |
if (count2_4 == 1) | |
return 2; | |
// ファイブカード | |
if (count2_5 == 1) | |
return 1; | |
// すき | |
if (digit[0] == 3 && digit[1] == 4) | |
return 5; | |
else if (digit[1] == 3 && digit[2] == 4) | |
return 5; | |
else if (digit[2] == 3 && digit[3] == 4) | |
return 5; | |
else if (digit[3] == 3 && digit[4] == 4) | |
return 5; | |
return 99; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment