├── .gitignore ├── Makefile ├── README.org ├── arrays.h ├── generate_table.cpp ├── mtrand.cpp ├── mtrand.h ├── poker.h ├── pokerlib.cpp ├── rankhand.out.txt ├── rankhand.pas └── test.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | HandRanks.dat 2 | generate-table 3 | *~ 4 | *.o 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | main: generate-table 2 | ./generate-table 3 | 4 | generate-table: *.cpp *.h 5 | clang++ generate_table.cpp pokerlib.cpp mtrand.cpp -o ./generate-table 6 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * TwoPlusTwo Hand Evaluator 2 | 3 | This is the famous Two Plus Two hand evaluator for 5-to-7-card poker hands, created by Ray Wotton with help from many others in a [[http://archives1.twoplustwo.com/showflat.php?Cat=0&Number=8513906][giant thread the Two plus Two poker forums]] and popularized by an old [[https://web.archive.org/web/20111103160502/http://www.codingthewheel.com/archives/poker-hand-evaluator-roundup#2p2][coding the wheel blog post]]. 4 | 5 | It's basically an elaborate caching system for an [[http://www.suffecool.net/poker/evaluator.html][ealier evaluator by Cactus Kev and Paul Senzee]]. 6 | 7 | * About this fork 8 | 9 | This fork ([[https://github.com/tangentstorm/TwoPlusTwoHandEvaluator]]) was extracted from the [[https://github.com/tangentstorm/XPokerEval][XPokerEval]] distribution (which contains a bunch of hand evaluators compiled by the coding the wheel guy). 10 | 11 | I added a =Makefile= and made some minor changes to to improve readability and allow compilation on non-windows platforms (it works on freebsd, anyway). 12 | 13 | My own main contribution is =rankhand.pas=, a small example program made with [[http://freepascal.org/][free pascal]] that shows how to use the =HandRanks.dat= file that =generate_table.cpp= creates. 14 | 15 | With all the people who had touched the c and c++ code, I found it difficult to decipher exactly how the cards and hands were represented (Wotton's code uses a completely different coding system than the one in =poker.h=). 16 | 17 | 18 | * License 19 | 20 | The pascal program is my own, and available for use under the extremely liberal *zlib license*. I wrote the pascal program from scratch and it has no dependencies on or relation to any of the C/C++ code. The only requirement is the generated database file. 21 | 22 | Wotton's code contains the self-contradictory statement "My code is GPL, use it as you like". The Cactus Kev / Paul Senzee code has a copyright but no license. 23 | -------------------------------------------------------------------------------- /generate_table.cpp: -------------------------------------------------------------------------------- 1 | // HandRankSetup.cpp : Sets up the HandRank File for VERY fast Lookups 2 | // by Ray Wotton and the 2+2 list My code is GPL, use it as you like 3 | 4 | // ==== 5 | // 6 | // the basic concept here is that every 7-card permutation 7 | // is added to a giant directed graph, which is arranged to 8 | // eliminate as much redundancy as possible. it essentially 9 | // acts as a simple finite state machine. 10 | // 11 | // i'm just cleaning this up so i can read the code 12 | // and figure out the actual format of the numbers so 13 | // i can use the database from pascal and generate it 14 | // from non-windows machines. 15 | // 16 | // --tangentstorm / Oct 03,2014 17 | // 18 | // references: 19 | // http://archives1.twoplustwo.com/showflat.php?Cat=0&Number=8513906 20 | // https://web.archive.org/web/20111103160502/http://www.codingthewheel.com/archives/poker-hand-evaluator-roundup#2p2 21 | 22 | 23 | #include "poker.h" 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | const char HandRanks[][16] = { 30 | "BAD!!",//0 31 | "High Card",//1 32 | "Pair",//2 33 | "Two Pair",//3 34 | "Three of a Kind",//4 35 | "Straight",//5 36 | "Flush",//6 37 | "Full House",//7 38 | "Four of a Kind",//8 39 | "Straight Flush"//9 40 | }; 41 | 42 | #define LARGE_INTEGER int64_t 43 | #define int64 int64_t 44 | 45 | 46 | inline int min(int const x, int const y) { 47 | return y < x ? y : x; 48 | } 49 | 50 | int64 IDs[612978]; 51 | int HR[32487834]; 52 | 53 | int numIDs = 1; 54 | int numcards = 0; 55 | int maxHR = 0; 56 | int64 maxID = 0; 57 | 58 | 59 | int64 MakeID(int64 IDin, int newcard) { 60 | // returns a 64-bit hand ID, for up to 8 cards, stored 1 per byte. 61 | 62 | int64 ID = 0; 63 | int suitcount[4 + 1]; 64 | int rankcount[13 + 1]; 65 | int wk[8]; // intentially keeping one as a 0 end 66 | int cardnum; 67 | int getout = 0; 68 | 69 | memset(wk, 0, sizeof(wk)); 70 | memset(rankcount, 0, sizeof(rankcount)); 71 | memset(suitcount, 0, sizeof(suitcount)); 72 | 73 | // can't have more than 6 cards! 74 | for (cardnum = 0; cardnum < 6; cardnum++) { 75 | // leave the 0 hole for new card 76 | wk[cardnum + 1] = (int) ((IDin >> (8 * cardnum)) & 0xff); 77 | } 78 | 79 | // my cards are 2c = 1, 2d = 2 ... As = 52 80 | newcard--; // make 0 based! 81 | 82 | // add next card. formats card to rrrr00ss 83 | wk[0] = (((newcard >> 2) + 1) << 4) + (newcard & 3) + 1; 84 | 85 | for (numcards = 0; wk[numcards]; numcards++) { 86 | // need to see if suit is significant 87 | suitcount[wk[numcards] & 0xf]++; 88 | // and rank to be sure we don't have 4! 89 | rankcount[(wk[numcards] >> 4) & 0xf]++; 90 | if (numcards) { 91 | // can't have the same card twice 92 | // if so need to get out after counting numcards 93 | if (wk[0] == wk[numcards]) getout = 1; 94 | } 95 | } 96 | if (getout) return 0; // duplicated another card (ignore this one) 97 | 98 | // (MakeID) 99 | 100 | // for suit to be significant, need to have n-2 of same suit 101 | int needsuited = numcards - 2; 102 | if (numcards > 4) { 103 | for (int rank = 1; rank < 14; rank++) { 104 | // if I have more than 4 of a rank then I shouldn't do this one!! 105 | // can't have more than 4 of a rank so return an ID that can't be! 106 | if (rankcount[rank] > 4) return 0; 107 | } 108 | } 109 | 110 | // However in the ID process I prefered that 111 | // 2s = 0x21, 3s = 0x31,.... Kc = 0xD4, Ac = 0xE4 112 | // This allows me to sort in Rank then Suit order 113 | 114 | // if we don't have at least 2 cards of the same suit for 4, 115 | // we make this card suit 0. 116 | if (needsuited > 1) { 117 | for (cardnum = 0; cardnum < numcards; cardnum++) { // for each card 118 | if (suitcount[wk[cardnum] & 0xf] < needsuited) { 119 | // check suitcount to the number I need to have suits significant 120 | // if not enough - 0 out the suit - now this suit would be a 0 vs 1-4 121 | wk[cardnum] &= 0xf0; 122 | } 123 | } 124 | } 125 | 126 | // (MakeID) 127 | 128 | // Sort Using XOR. Netwk for N=7, using Bose-Nelson Algorithm: 129 | // Thanks to the thread! 130 | #define SWAP(I,J) {if (wk[I] < wk[J]) {wk[I]^=wk[J]; wk[J]^=wk[I]; wk[I]^=wk[J];}} 131 | 132 | SWAP(0, 4); SWAP(1, 5); SWAP(2, 6); SWAP(0, 2); SWAP(1, 3); 133 | SWAP(4, 6); SWAP(2, 4); SWAP(3, 5); SWAP(0, 1); SWAP(2, 3); 134 | SWAP(4, 5); SWAP(1, 4); SWAP(3, 6); SWAP(1, 2); SWAP(3, 4); 135 | SWAP(5, 6); 136 | 137 | // long winded way to put the pieces into a int64 138 | // cards in bytes --66554433221100 139 | // the resulting ID is a 64 bit value with each card represented by 8 bits. 140 | ID = (int64) wk[0] + 141 | ((int64) wk[1] << 8) + 142 | ((int64) wk[2] << 16) + 143 | ((int64) wk[3] << 24) + 144 | ((int64) wk[4] << 32) + 145 | ((int64) wk[5] << 40) + 146 | ((int64) wk[6] << 48); 147 | return ID; 148 | } 149 | 150 | int SaveID(int64 ID) { 151 | // this inserts a hand ID into the IDs array. 152 | 153 | if (ID == 0) return 0; // don't use up a record for a 0! 154 | 155 | // take care of the most likely first goes on the end... 156 | if (ID >= maxID) { 157 | if (ID > maxID) { // greater than create new else it was the last one! 158 | IDs[numIDs++] = ID; // add the new ID 159 | maxID = ID; 160 | } 161 | return numIDs - 1; 162 | } 163 | 164 | // find the slot (by a pseudo bsearch algorithm) 165 | int low = 0; 166 | int high = numIDs - 1; 167 | int64 testval; 168 | int holdtest; 169 | 170 | while (high - low > 1) { 171 | holdtest = (high + low + 1) / 2; 172 | testval = IDs[holdtest] - ID; 173 | if (testval > 0) high = holdtest; 174 | else if (testval < 0) low = holdtest; 175 | else return holdtest; // got it!! 176 | } 177 | // it couldn't be found so must be added to the current location (high) 178 | // make space... // don't expect this much! 179 | memmove(&IDs[high + 1], &IDs[high], (numIDs - high) * sizeof(IDs[0])); 180 | 181 | IDs[high] = ID; // do the insert into the hole created 182 | numIDs++; 183 | return high; 184 | } 185 | 186 | 187 | int DoEval(int64 IDin) { 188 | // converts a 64bit handID to an absolute ranking. 189 | 190 | // I guess I have some explaining to do here... 191 | // I used the Cactus Kevs Eval ref http://www.suffecool.net/poker/evaluator.html 192 | // I Love the pokersource for speed, but I needed to do some tweaking 193 | // to get it my way and Cactus Kevs stuff was easy to tweak ;-) 194 | int result = 0; 195 | int cardnum; 196 | int wkcard; 197 | int rank; 198 | int suit; 199 | int mainsuit = 20; // just something that will never hit... 200 | // TODO: need to eliminate the main suit from the iterator 201 | //int suititerator = 0; 202 | int suititerator = 1; // changed as per Ray Wotton's comment at http://archives1.twoplustwo.com/showflat.php?Cat=0&Number=8513906&page=0&fpart=18&vc=1 203 | int holdrank; 204 | int wk[8]; // "work" intentially keeping one as a 0 end 205 | int holdcards[8]; 206 | int numevalcards = 0; 207 | 208 | // See Cactus Kevs page for explainations for this type of stuff... 209 | const int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41 }; 210 | 211 | memset(wk, 0, sizeof(wk)); 212 | memset(holdcards, 0, sizeof(holdcards)); 213 | 214 | if (IDin) { // if I have a good ID then do it... 215 | for (cardnum = 0; cardnum < 7; cardnum++) { 216 | // convert all 7 cards (0s are ok) 217 | holdcards[cardnum] = (int) ((IDin >> (8 * cardnum)) & 0xff); 218 | if (holdcards[cardnum] == 0) break; // once I hit a 0 I know I am done 219 | numevalcards++; 220 | // if not 0 then count the card 221 | if (suit = holdcards[cardnum] & 0xf) { 222 | // find out what suit (if any) was significant and remember it 223 | mainsuit = suit; 224 | } 225 | } 226 | 227 | // (DoEval) 228 | 229 | for (cardnum = 0; cardnum < numevalcards; cardnum++) { 230 | // just have numcards... 231 | wkcard = holdcards[cardnum]; 232 | 233 | // convert to cactus kevs way!! 234 | // ref http://www.suffecool.net/poker/evaluator.html 235 | // +--------+--------+--------+--------+ 236 | // |xxxbbbbb|bbbbbbbb|cdhsrrrr|xxpppppp| 237 | // +--------+--------+--------+--------+ 238 | // p = prime number of rank (deuce=2,trey=3,four=5,five=7,...,ace=41) 239 | // r = rank of card (deuce=0,trey=1,four=2,five=3,...,ace=12) 240 | // cdhs = suit of card 241 | // b = bit turned on depending on rank of card 242 | 243 | rank = (wkcard >> 4) - 1; // my rank is top 4 bits 1-13 so convert 244 | suit = wkcard & 0xf; // my suit is bottom 4 bits 1-4, order is different, but who cares? 245 | if (suit == 0) { 246 | // if suit wasn't significant though... 247 | suit = suititerator++; // Cactus Kev needs a suit! 248 | if (suititerator == 5) // loop through available suits 249 | suititerator = 1; 250 | if (suit == mainsuit) { // if it was the sigificant suit... Don't want extras!! 251 | suit = suititerator++; // skip it 252 | if (suititerator == 5) // roll 1-4 253 | suititerator = 1; 254 | } 255 | } 256 | // now make Cactus Kev's Card 257 | wk[cardnum] = primes[rank] | (rank << 8) | (1 << (suit + 11)) | (1 << (16 + rank)); 258 | } 259 | 260 | // (DoEval) 261 | // James Devlin: replaced all calls to Cactus Kev's eval_5cards with calls to 262 | // Senzee's improved eval_5hand_fast 263 | 264 | switch (numevalcards) { // run Cactus Keys routines 265 | case 5 : holdrank = eval_5hand_fast(wk[0],wk[1],wk[2],wk[3],wk[4]); 266 | break; 267 | // if 6 cards I would like to find Result for them 268 | // Cactus Key is 1 = highest - 7362 lowest 269 | // I need to get the min for the permutations 270 | case 6 : 271 | holdrank = eval_5hand_fast(wk[0],wk[1],wk[2],wk[3],wk[4]); 272 | holdrank = min( holdrank, 273 | eval_5hand_fast(wk[0],wk[1],wk[2],wk[3],wk[5])); 274 | holdrank = min( holdrank, 275 | eval_5hand_fast(wk[0],wk[1],wk[2],wk[4],wk[5])); 276 | holdrank = min( holdrank, 277 | eval_5hand_fast(wk[0],wk[1],wk[3],wk[4],wk[5])); 278 | holdrank = min( holdrank, 279 | eval_5hand_fast(wk[0],wk[2],wk[3],wk[4],wk[5])); 280 | holdrank = min( holdrank, 281 | eval_5hand_fast(wk[1],wk[2],wk[3],wk[4],wk[5])); 282 | break; 283 | case 7 : holdrank = eval_7hand(wk); 284 | break; 285 | default : // problem!! shouldn't hit this... 286 | printf(" Problem with numcards = %d!!\n", numcards); 287 | break; 288 | } 289 | 290 | // (DoEval) 291 | // I would like to change the format of Catus Kev's ret value to: 292 | // hhhhrrrrrrrrrrrr hhhh = 1 high card -> 9 straight flush 293 | // r..r = rank within the above 1 to max of 2861 294 | result = 7463 - holdrank; // now the worst hand = 1 295 | 296 | if (result < 1278) result = result - 0 + 4096 * 1; // 1277 high card 297 | else if (result < 4138) result = result - 1277 + 4096 * 2; // 2860 one pair 298 | else if (result < 4996) result = result - 4137 + 4096 * 3; // 858 two pair 299 | else if (result < 5854) result = result - 4995 + 4096 * 4; // 858 three-kind 300 | else if (result < 5864) result = result - 5853 + 4096 * 5; // 10 straights 301 | else if (result < 7141) result = result - 5863 + 4096 * 6; // 1277 flushes 302 | else if (result < 7297) result = result - 7140 + 4096 * 7; // 156 full house 303 | else if (result < 7453) result = result - 7296 + 4096 * 8; // 156 four-kind 304 | else result = result - 7452 + 4096 * 9; // 10 str.flushes 305 | } 306 | return result; // now a handrank that I like 307 | } 308 | 309 | 310 | int main(int argc, char* argv[]) { 311 | int IDslot, card = 0, count = 0; 312 | int64 ID; 313 | 314 | clock_t timer = clock(); // remember when I started 315 | 316 | // Store the count of each type of hand (One Pair, Flush, etc) 317 | int handTypeSum[10]; 318 | 319 | // Clear our arrays 320 | memset(handTypeSum, 0, sizeof(handTypeSum)); 321 | memset(IDs, 0, sizeof(IDs)); 322 | memset(HR, 0, sizeof(HR)); 323 | 324 | 325 | // step through the ID array - always shifting the current ID and 326 | // adding 52 cards to the end of the array. 327 | // when I am at 7 cards put the Hand Rank in!! 328 | // stepping through the ID array is perfect!! 329 | 330 | int IDnum; 331 | int holdid; 332 | 333 | // main() 334 | 335 | printf("\nGetting Card IDs!\n"); 336 | 337 | // Jmd: Okay, this loop is going to fill up the IDs[] array which has 338 | // 612,967 slots. as this loops through and find new combinations it 339 | // adds them to the end. I need this list to be stable when I set the 340 | // handranks (next set) (I do the insertion sort on new IDs these) 341 | // so I had to get the IDs first and then set the handranks 342 | for (IDnum = 0; IDs[IDnum] || IDnum == 0; IDnum++) { 343 | // start at 1 so I have a zero catching entry (just in case) 344 | for (card = 1; card < 53; card++) { 345 | // the ids above contain cards upto the current card. Now add a new card 346 | ID = MakeID(IDs[IDnum], card); // get the new ID for it 347 | // and save it in the list if I am not on the 7th card 348 | if (numcards < 7) holdid = SaveID(ID); 349 | } 350 | printf("\rID - %d", IDnum); // show progress -- this counts up to 612976 351 | } 352 | 353 | // main() 354 | printf("\nSetting HandRanks!\n"); 355 | 356 | // this is as above, but will not add anything to the ID list, so it is stable 357 | for (IDnum = 0; IDs[IDnum] || IDnum == 0; IDnum++) { 358 | // start at 1 so I have a zero catching entry (just in case) 359 | for (card = 1; card < 53; card++) { 360 | ID = MakeID(IDs[IDnum], card); 361 | 362 | if (numcards < 7) { 363 | // when in the index mode (< 7 cards) get the id to save 364 | IDslot = SaveID(ID) * 53 + 53; 365 | } else { 366 | // if I am at the 7th card, get the equivalence class ("hand rank") to save 367 | IDslot = DoEval(ID); 368 | } 369 | 370 | maxHR = IDnum * 53 + card + 53; // find where to put it 371 | HR[maxHR] = IDslot; // and save the pointer to the next card or the handrank 372 | } 373 | 374 | if (numcards == 6 || numcards == 7) { 375 | // an extra, If you want to know what the handrank when there is 5 or 6 cards 376 | // you can just do HR[u3] or HR[u4] from below code for Handrank of the 5 or 377 | // 6 card hand 378 | // this puts the above handrank into the array 379 | HR[IDnum * 53 + 53] = DoEval(IDs[IDnum]); 380 | } 381 | 382 | printf("\rID - %d", IDnum); // show the progress -- counts to 612976 again 383 | } 384 | 385 | printf("\nNumber IDs = %d\nmaxHR = %d\n", numIDs, maxHR); // for warm fuzzys 386 | 387 | timer = clock() - timer; // end the timer 388 | 389 | printf("Training seconds = %.2f\n", (float)timer/CLOCKS_PER_SEC); 390 | 391 | // main() 392 | LARGE_INTEGER timings, endtimings; // for high precision timing 393 | 394 | timer = clock(); // now get current time for Testing! 395 | 396 | // another algorithm right off the thread 397 | 398 | int c0, c1, c2, c3, c4, c5, c6; 399 | int u0, u1, u2, u3, u4, u5; 400 | 401 | // QueryPerformanceCounter(&timings); 402 | // start High Precision clock 403 | for (c0 = 1; c0 < 53; c0++) { 404 | u0 = HR[53+c0]; 405 | for (c1 = c0+1; c1 < 53; c1++) { 406 | u1 = HR[u0+c1]; 407 | for (c2 = c1+1; c2 < 53; c2++) { 408 | u2 = HR[u1+c2]; 409 | for (c3 = c2+1; c3 < 53; c3++) { 410 | u3 = HR[u2+c3]; 411 | for (c4 = c3+1; c4 < 53; c4++) { 412 | u4 = HR[u3+c4]; 413 | for (c5 = c4+1; c5 < 53; c5++) { 414 | u5 = HR[u4+c5]; 415 | for (c6 = c5+1; c6 < 53; c6++) { 416 | handTypeSum[HR[u5+c6] >> 12]++; 417 | count++; 418 | } 419 | } 420 | } 421 | } 422 | } 423 | } 424 | } 425 | 426 | // QueryPerformanceCounter(&endtimings); 427 | // end the high precision clock 428 | 429 | timer = clock() - timer; // get the time in this 430 | 431 | for (int i = 0; i <= 9; i++) // display the results 432 | printf("\n%16s = %d", HandRanks[i], handTypeSum[i]); 433 | 434 | printf("\nTotal Hands = %d\n", count); 435 | 436 | // main() 437 | // int64 clocksused = (int64)endtimings.QuadPart - (int64) 438 | // timings.QuadPart; // calc clocks used from the High Precision clock 439 | 440 | // and display the clock results 441 | // printf("\nValidation seconds = %.4lf\nTotal HighPrecision Clocks = %I64d\nHighPrecision clocks per lookup = %lf\n", (double)timer/CLOCKS_PER_SEC, clocksused, (double) clocksused / 133784560.0) ; 442 | 443 | // output the array now that I have it!! 444 | FILE * fout = fopen("HandRanks.dat", "wb"); 445 | if (!fout) { 446 | printf("Problem creating the Output File!\n"); 447 | return 1; 448 | } 449 | fwrite(HR, sizeof(HR), 1, fout); // big write, but quick 450 | 451 | fclose(fout); 452 | 453 | return 0; 454 | } 455 | 456 | ///////////////////////////////// end code!! 457 | -------------------------------------------------------------------------------- /mtrand.cpp: -------------------------------------------------------------------------------- 1 | // mtrand.cpp, see include file mtrand.h for information 2 | 3 | #include "mtrand.h" 4 | // non-inline function definitions and static member definitions cannot 5 | // reside in header file because of the risk of multiple declarations 6 | 7 | // initialization of static private members 8 | unsigned long MTRand_int32::state[n] = {0x0UL}; 9 | int MTRand_int32::p = 0; 10 | bool MTRand_int32::init = false; 11 | 12 | void MTRand_int32::gen_state() { // generate new state vector 13 | for (int i = 0; i < (n - m); ++i) 14 | state[i] = state[i + m] ^ twiddle(state[i], state[i + 1]); 15 | for (int i = n - m; i < (n - 1); ++i) 16 | state[i] = state[i + m - n] ^ twiddle(state[i], state[i + 1]); 17 | state[n - 1] = state[m - 1] ^ twiddle(state[n - 1], state[0]); 18 | p = 0; // reset position 19 | } 20 | 21 | void MTRand_int32::seed(unsigned long s) { // init by 32 bit seed 22 | state[0] = s & 0xFFFFFFFFUL; // for > 32 bit machines 23 | for (int i = 1; i < n; ++i) { 24 | state[i] = 1812433253UL * (state[i - 1] ^ (state[i - 1] >> 30)) + i; 25 | // see Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier 26 | // in the previous versions, MSBs of the seed affect only MSBs of the array state 27 | // 2002/01/09 modified by Makoto Matsumoto 28 | state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines 29 | } 30 | p = n; // force gen_state() to be called for next random number 31 | } 32 | 33 | void MTRand_int32::seed(const unsigned long* array, int size) { // init by array 34 | seed(19650218UL); 35 | int i = 1, j = 0; 36 | for (int k = ((n > size) ? n : size); k; --k) { 37 | state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1664525UL)) 38 | + array[j] + j; // non linear 39 | state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines 40 | ++j; j %= size; 41 | if ((++i) == n) { state[0] = state[n - 1]; i = 1; } 42 | } 43 | for (int k = n - 1; k; --k) { 44 | state[i] = (state[i] ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1566083941UL)) - i; 45 | state[i] &= 0xFFFFFFFFUL; // for > 32 bit machines 46 | if ((++i) == n) { state[0] = state[n - 1]; i = 1; } 47 | } 48 | state[0] = 0x80000000UL; // MSB is 1; assuring non-zero initial array 49 | p = n; // force gen_state() to be called for next random number 50 | } 51 | -------------------------------------------------------------------------------- /mtrand.h: -------------------------------------------------------------------------------- 1 | // mtrand.h 2 | // C++ include file for MT19937, with initialization improved 2002/1/26. 3 | // Coded by Takuji Nishimura and Makoto Matsumoto. 4 | // Ported to C++ by Jasper Bedaux 2003/1/1 (see http://www.bedaux.net/mtrand/). 5 | // The generators returning floating point numbers are based on 6 | // a version by Isaku Wada, 2002/01/09 7 | // 8 | // Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 9 | // All rights reserved. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions 13 | // are met: 14 | // 15 | // 1. Redistributions of source code must retain the above copyright 16 | // notice, this list of conditions and the following disclaimer. 17 | // 18 | // 2. Redistributions in binary form must reproduce the above copyright 19 | // notice, this list of conditions and the following disclaimer in the 20 | // documentation and/or other materials provided with the distribution. 21 | // 22 | // 3. The names of its contributors may not be used to endorse or promote 23 | // products derived from this software without specific prior written 24 | // permission. 25 | // 26 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 30 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | // 38 | // Any feedback is very welcome. 39 | // http://www.math.keio.ac.jp/matumoto/emt.html 40 | // email: matumoto@math.keio.ac.jp 41 | // 42 | // Feedback about the C++ port should be sent to Jasper Bedaux, 43 | // see http://www.bedaux.net/mtrand/ for e-mail address and info. 44 | 45 | #ifndef MTRAND_H 46 | #define MTRAND_H 47 | 48 | class MTRand_int32 { // Mersenne Twister random number generator 49 | public: 50 | // default constructor: uses default seed only if this is the first instance 51 | MTRand_int32() { if (!init) seed(5489UL); init = true; } 52 | // constructor with 32 bit int as seed 53 | MTRand_int32(unsigned long s) { seed(s); init = true; } 54 | // constructor with array of size 32 bit ints as seed 55 | MTRand_int32(const unsigned long* array, int size) { seed(array, size); init = true; } 56 | // the two seed functions 57 | void seed(unsigned long); // seed with 32 bit integer 58 | void seed(const unsigned long*, int size); // seed with array 59 | // overload operator() to make this a generator (functor) 60 | unsigned long operator()() { return rand_int32(); } 61 | // 2007-02-11: made the destructor virtual; thanks "double more" for pointing this out 62 | virtual ~MTRand_int32() {} // destructor 63 | protected: // used by derived classes, otherwise not accessible; use the ()-operator 64 | unsigned long rand_int32(); // generate 32 bit random integer 65 | private: 66 | static const int n = 624, m = 397; // compile time constants 67 | // the variables below are static (no duplicates can exist) 68 | static unsigned long state[n]; // state vector array 69 | static int p; // position in state array 70 | static bool init; // true if init function is called 71 | // private functions used to generate the pseudo random numbers 72 | unsigned long twiddle(unsigned long, unsigned long); // used by gen_state() 73 | void gen_state(); // generate new state 74 | // make copy constructor and assignment operator unavailable, they don't make sense 75 | MTRand_int32(const MTRand_int32&); // copy constructor not defined 76 | void operator=(const MTRand_int32&); // assignment operator not defined 77 | }; 78 | 79 | // inline for speed, must therefore reside in header file 80 | inline unsigned long MTRand_int32::twiddle(unsigned long u, unsigned long v) { 81 | return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1) 82 | ^ ((v & 1UL) ? 0x9908B0DFUL : 0x0UL); 83 | } 84 | 85 | inline unsigned long MTRand_int32::rand_int32() { // generate 32 bit random int 86 | if (p == n) gen_state(); // new state vector needed 87 | // gen_state() is split off to be non-inline, because it is only called once 88 | // in every 624 calls and otherwise irand() would become too big to get inlined 89 | unsigned long x = state[p++]; 90 | x ^= (x >> 11); 91 | x ^= (x << 7) & 0x9D2C5680UL; 92 | x ^= (x << 15) & 0xEFC60000UL; 93 | return x ^ (x >> 18); 94 | } 95 | 96 | // generates double floating point numbers in the half-open interval [0, 1) 97 | class MTRand : public MTRand_int32 { 98 | public: 99 | MTRand() : MTRand_int32() {} 100 | MTRand(unsigned long seed) : MTRand_int32(seed) {} 101 | MTRand(const unsigned long* seed, int size) : MTRand_int32(seed, size) {} 102 | ~MTRand() {} 103 | double operator()() { 104 | return static_cast(rand_int32()) * (1. / 4294967296.); } // divided by 2^32 105 | private: 106 | MTRand(const MTRand&); // copy constructor not defined 107 | void operator=(const MTRand&); // assignment operator not defined 108 | }; 109 | 110 | // generates double floating point numbers in the closed interval [0, 1] 111 | class MTRand_closed : public MTRand_int32 { 112 | public: 113 | MTRand_closed() : MTRand_int32() {} 114 | MTRand_closed(unsigned long seed) : MTRand_int32(seed) {} 115 | MTRand_closed(const unsigned long* seed, int size) : MTRand_int32(seed, size) {} 116 | ~MTRand_closed() {} 117 | double operator()() { 118 | return static_cast(rand_int32()) * (1. / 4294967295.); } // divided by 2^32 - 1 119 | private: 120 | MTRand_closed(const MTRand_closed&); // copy constructor not defined 121 | void operator=(const MTRand_closed&); // assignment operator not defined 122 | }; 123 | 124 | // generates double floating point numbers in the open interval (0, 1) 125 | class MTRand_open : public MTRand_int32 { 126 | public: 127 | MTRand_open() : MTRand_int32() {} 128 | MTRand_open(unsigned long seed) : MTRand_int32(seed) {} 129 | MTRand_open(const unsigned long* seed, int size) : MTRand_int32(seed, size) {} 130 | ~MTRand_open() {} 131 | double operator()() { 132 | return (static_cast(rand_int32()) + .5) * (1. / 4294967296.); } // divided by 2^32 133 | private: 134 | MTRand_open(const MTRand_open&); // copy constructor not defined 135 | void operator=(const MTRand_open&); // assignment operator not defined 136 | }; 137 | 138 | // generates 53 bit resolution doubles in the half-open interval [0, 1) 139 | class MTRand53 : public MTRand_int32 { 140 | public: 141 | MTRand53() : MTRand_int32() {} 142 | MTRand53(unsigned long seed) : MTRand_int32(seed) {} 143 | MTRand53(const unsigned long* seed, int size) : MTRand_int32(seed, size) {} 144 | ~MTRand53() {} 145 | double operator()() { 146 | return (static_cast(rand_int32() >> 5) * 67108864. + 147 | static_cast(rand_int32() >> 6)) * (1. / 9007199254740992.); } 148 | 149 | // Convenience function: generate an integer between 0 and upperBound 150 | // Added by James Devlin 151 | long under(int upperBound) { return (long)((*this)() * upperBound); } 152 | 153 | private: 154 | MTRand53(const MTRand53&); // copy constructor not defined 155 | void operator=(const MTRand53&); // assignment operator not defined 156 | }; 157 | 158 | #endif // MTRAND_H 159 | -------------------------------------------------------------------------------- /poker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #define STRAIGHT_FLUSH 1 5 | #define FOUR_OF_A_KIND 2 6 | #define FULL_HOUSE 3 7 | #define FLUSH 4 8 | #define STRAIGHT 5 9 | #define THREE_OF_A_KIND 6 10 | #define TWO_PAIR 7 11 | #define ONE_PAIR 8 12 | #define HIGH_CARD 9 13 | 14 | #define RANK(x) ((x >> 8) & 0xF) 15 | 16 | static std::string value_str[] = { 17 | "", 18 | "Straight Flush", 19 | "Four of a Kind", 20 | "Full House", 21 | "Flush", 22 | "Straight", 23 | "Three of a Kind", 24 | "Two Pair", 25 | "One Pair", 26 | "High Card" 27 | }; 28 | 29 | #define CLUB 0x8000 30 | #define DIAMOND 0x4000 31 | #define HEART 0x2000 32 | #define SPADE 0x1000 33 | 34 | #define Deuce 0 35 | #define Trey 1 36 | #define Four 2 37 | #define Five 3 38 | #define Six 4 39 | #define Seven 5 40 | #define Eight 6 41 | #define Nine 7 42 | #define Ten 8 43 | #define Jack 9 44 | #define Queen 10 45 | #define King 11 46 | #define Ace 12 47 | 48 | // jmd declarations added 49 | void init_deck( int *deck ); 50 | int find_card( int rank, int suit, int *deck ); 51 | short eval_5hand( int *hand ); 52 | int eval_5hand_fast(int c1, int c2, int c3, int c4, int c5); 53 | int hand_rank( short val ); 54 | void print_hand( int *hand, int n ); 55 | void shuffle_deck( int *deck ); 56 | short eval_5cards( int c1, int c2, int c3, int c4, int c5 ); 57 | short eval_7hand( int *hand ); 58 | -------------------------------------------------------------------------------- /pokerlib.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "arrays.h" 3 | #include "poker.h" 4 | #include "mtrand.h" 5 | 6 | // Paul D. Senzee's Optimized Hand Evaluator 7 | // for Cactus Kev's Poker Hand Evaluator 8 | // 9 | // Replaces binary search with a perfect hash. 10 | // If you replace eval_5hand with eval_5hand_fast, the products[] and values[] arrays in 'arrays.h' are unnecessary. 11 | // With eval_5hand_fast, the 'allfive.c' test program runs about 2.7 times faster. 12 | // 13 | // (c) Paul D. Senzee. 14 | // Portions (in eval_5hand_fast) (c) Kevin L. Suffecool. 15 | // psenzee@yahoo.com 16 | // 17 | // Senzee 5 18 | // http://senzee.blogspot.com 19 | 20 | extern short flushes[]; 21 | extern short unique5[]; 22 | extern unsigned short hash_adjust[]; 23 | extern unsigned short hash_values[]; 24 | 25 | MTRand53 theRNG; 26 | 27 | unsigned find_fast(unsigned u) 28 | { 29 | unsigned a, b, r; 30 | u += 0xe91aaa35; 31 | u ^= u >> 16; 32 | u += u << 8; 33 | u ^= u >> 4; 34 | b = (u >> 8) & 0x1ff; 35 | a = (u + (u << 2)) >> 19; 36 | r = a ^ hash_adjust[b]; 37 | return r; 38 | } 39 | 40 | // 41 | // This routine initializes the deck. A deck of cards is 42 | // simply an integer array of length 52 (no jokers). This 43 | // array is populated with each card, using the following 44 | // scheme: 45 | // 46 | // An integer is made up of four bytes. The high-order 47 | // bytes are used to hold the rank bit pattern, whereas 48 | // the low-order bytes hold the suit/rank/prime value 49 | // of the card. 50 | // 51 | // +--------+--------+--------+--------+ 52 | // |xxxbbbbb|bbbbbbbb|cdhsrrrr|xxpppppp| 53 | // +--------+--------+--------+--------+ 54 | // 55 | // p = prime number of rank (deuce=2,trey=3,four=5,five=7,...,ace=41) 56 | // r = rank of card (deuce=0,trey=1,four=2,five=3,...,ace=12) 57 | // cdhs = suit of card 58 | // b = bit turned on depending on rank of card 59 | // 60 | // JMD: added "void" return type 61 | void init_deck( int *deck ) 62 | { 63 | int i, j, n = 0, suit = 0x8000; 64 | 65 | for ( i = 0; i < 4; i++, suit >>= 1 ) 66 | for ( j = 0; j < 13; j++, n++ ) 67 | deck[n] = primes[j] | (j << 8) | suit | (1 << (16+j)); 68 | } 69 | 70 | 71 | // This routine will search a deck for a specific card 72 | // (specified by rank/suit), and return the INDEX giving 73 | // the position of the found card. If it is not found, 74 | // then it returns -1 75 | // 76 | int 77 | find_card( int rank, int suit, int *deck ) 78 | { 79 | int i, c; 80 | 81 | for ( i = 0; i < 52; i++ ) 82 | { 83 | c = deck[i]; 84 | if ( (c & suit) && (RANK(c) == rank) ) 85 | return( i ); 86 | } 87 | return( -1 ); 88 | } 89 | 90 | 91 | // 92 | // This routine takes a deck and randomly mixes up 93 | // the order of the cards. 94 | // 95 | void shuffle_deck( int *deck ) 96 | { 97 | int i, n, temp[52]; 98 | 99 | for ( i = 0; i < 52; i++ ) 100 | temp[i] = deck[i]; 101 | 102 | for ( i = 0; i < 52; i++ ) 103 | { 104 | do { 105 | // JMD: drand48 is *nix. Replace with a 106 | // crossplat version. 107 | //n = (int)(51.9999999 * drand48()); 108 | n = theRNG.under(52); 109 | } while ( temp[n] == 0 ); 110 | deck[i] = temp[n]; 111 | temp[n] = 0; 112 | } 113 | } 114 | 115 | 116 | void print_hand( int *hand, int n ) 117 | { 118 | int i, r; 119 | char suit; 120 | static char *rank = "23456789TJQKA"; 121 | 122 | for ( i = 0; i < n; i++ ) 123 | { 124 | r = (*hand >> 8) & 0xF; 125 | if ( *hand & 0x8000 ) 126 | suit = 'c'; 127 | else if ( *hand & 0x4000 ) 128 | suit = 'd'; 129 | else if ( *hand & 0x2000 ) 130 | suit = 'h'; 131 | else 132 | suit = 's'; 133 | 134 | printf( "%c%c ", rank[r], suit ); 135 | hand++; 136 | } 137 | } 138 | 139 | 140 | int hand_rank( short val ) 141 | { 142 | if (val > 6185) return(HIGH_CARD); // 1277 high card 143 | if (val > 3325) return(ONE_PAIR); // 2860 one pair 144 | if (val > 2467) return(TWO_PAIR); // 858 two pair 145 | if (val > 1609) return(THREE_OF_A_KIND); // 858 three-kind 146 | if (val > 1599) return(STRAIGHT); // 10 straights 147 | if (val > 322) return(FLUSH); // 1277 flushes 148 | if (val > 166) return(FULL_HOUSE); // 156 full house 149 | if (val > 10) return(FOUR_OF_A_KIND); // 156 four-kind 150 | return(STRAIGHT_FLUSH); // 10 straight-flushes 151 | } 152 | 153 | 154 | int eval_5hand_fast(int c1, int c2, int c3, int c4, int c5) 155 | { 156 | int q = (c1 | c2 | c3 | c4 | c5) >> 16; 157 | short s; 158 | if (c1 & c2 & c3 & c4 & c5 & 0xf000) return flushes[q]; // check for flushes and straight flushes 159 | if ((s = unique5[q])) return s; // check for straights and high card hands 160 | return hash_values[find_fast((c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff))]; 161 | } 162 | 163 | 164 | //short 165 | //eval_5cards( int c1, int c2, int c3, int c4, int c5 ) 166 | //{ 167 | // int q; 168 | // short s; 169 | // 170 | // q = (c1|c2|c3|c4|c5) >> 16; 171 | // 172 | // /* check for Flushes and StraightFlushes 173 | // */ 174 | // if ( c1 & c2 & c3 & c4 & c5 & 0xF000 ) 175 | // return( flushes[q] ); 176 | // 177 | // /* check for Straights and HighCard hands 178 | // */ 179 | // s = unique5[q]; 180 | // if ( s ) return ( s ); 181 | // 182 | // /* let's do it the hard way 183 | // */ 184 | // q = (c1&0xFF) * (c2&0xFF) * (c3&0xFF) * (c4&0xFF) * (c5&0xFF); 185 | // q = findit( q ); 186 | // 187 | // return( values[q] ); 188 | //} 189 | 190 | extern unsigned short hash_adjust[] = 191 | { 192 | 0, 5628, 7017, 1298, 2918, 2442, 8070, 6383, 6383, 7425, 2442, 5628, 8044, 7425, 3155, 6383, 193 | 2918, 7452, 1533, 6849, 5586, 7452, 7452, 1533, 2209, 6029, 2794, 3509, 7992, 7733, 7452, 131, 194 | 6029, 4491, 1814, 7452, 6110, 3155, 7077, 6675, 532, 1334, 7555, 5325, 3056, 1403, 1403, 3969, 195 | 4491, 1403, 7592, 522, 8070, 1403, 0, 1905, 3584, 2918, 922, 3304, 6675, 0, 7622, 7017, 196 | 3210, 2139, 1403, 5225, 0, 3969, 7992, 5743, 5499, 5499, 5345, 7452, 522, 305, 3056, 7017, 197 | 7017, 2139, 1338, 3056, 7452, 1403, 6799, 3204, 3290, 4099, 1814, 2191, 4099, 5743, 1570, 1334, 198 | 7363, 1905, 0, 6799, 4400, 1480, 6029, 1905, 0, 7525, 2028, 2794, 131, 7646, 3155, 4986, 199 | 1858, 2442, 7992, 1607, 3584, 4986, 706, 6029, 5345, 7622, 6322, 5196, 1905, 6847, 218, 1785, 200 | 0, 4099, 2981, 6849, 4751, 3950, 7733, 3056, 5499, 4055, 6849, 1533, 131, 5196, 2918, 3879, 201 | 5325, 2794, 6029, 0, 0, 322, 7452, 6178, 2918, 2320, 6675, 3056, 6675, 1533, 6029, 1428, 202 | 2280, 2171, 6788, 7452, 3325, 107, 4262, 311, 5562, 7857, 6110, 2139, 4942, 4600, 1905, 0, 203 | 3083, 5345, 7452, 6675, 0, 6112, 4099, 7017, 1338, 6799, 2918, 1232, 3584, 522, 6029, 5325, 204 | 1403, 6759, 6849, 508, 6675, 2987, 7745, 6870, 896, 7452, 1232, 4400, 12, 2981, 3850, 4491, 205 | 6849, 0, 6675, 747, 4491, 7525, 6675, 7452, 7992, 6921, 7323, 6849, 3056, 1199, 2139, 6029, 206 | 6029, 190, 4351, 7891, 4400, 7134, 1533, 1194, 3950, 6675, 5345, 6383, 7622, 131, 1905, 2883, 207 | 6383, 1533, 5345, 2794, 4303, 1403, 0, 1338, 2794, 992, 4871, 6383, 4099, 2794, 3889, 6184, 208 | 3304, 1905, 6383, 3950, 3056, 522, 1810, 3975, 7622, 7452, 522, 6799, 5866, 7084, 7622, 6528, 209 | 2798, 7452, 1810, 7907, 642, 5345, 1905, 6849, 6675, 7745, 2918, 4751, 3229, 2139, 6029, 5207, 210 | 6601, 2139, 7452, 5890, 1428, 5628, 7622, 2139, 3146, 2400, 578, 941, 7672, 1814, 3210, 1533, 211 | 4491, 12, 2918, 1900, 7425, 2794, 2987, 3465, 1377, 3822, 3969, 3210, 859, 5499, 6878, 1377, 212 | 3056, 4027, 8065, 8065, 5207, 4400, 4303, 3210, 3210, 0, 6675, 357, 5628, 5512, 1905, 3452, 213 | 1403, 7646, 859, 6788, 3210, 2139, 378, 5663, 7733, 870, 0, 4491, 4813, 2110, 578, 2139, 214 | 3056, 4099, 1905, 1298, 4672, 2191, 3950, 5499, 3969, 4974, 6323, 6029, 7414, 6383, 0, 4974, 215 | 3210, 795, 4099, 131, 5345, 5345, 6576, 1810, 1621, 4400, 2918, 1905, 2442, 2679, 6322, 7452, 216 | 2110, 1403, 6383, 2653, 5132, 6856, 7841, 2794, 6110, 2028, 6675, 7425, 6999, 7441, 6029, 183, 217 | 6675, 4400, 859, 1403, 2794, 5985, 5345, 1533, 322, 4400, 1227, 5890, 4474, 4491, 3574, 8166, 218 | 6849, 7086, 5345, 5345, 5459, 3584, 6675, 3969, 7579, 8044, 2295, 2577, 1480, 5743, 3304, 5499, 219 | 330, 4303, 6863, 3822, 4600, 4751, 5628, 3822, 2918, 6675, 2400, 6663, 1403, 6849, 6029, 3145, 220 | 6110, 3210, 747, 3229, 3056, 2918, 7733, 330, 4055, 7322, 5628, 2987, 3056, 1905, 2903, 669, 221 | 5325, 2845, 4099, 5225, 6283, 4099, 5000, 642, 4055, 5345, 8034, 2918, 1041, 5769, 7051, 1538, 222 | 2918, 3366, 608, 4303, 3921, 0, 2918, 1905, 218, 6687, 5963, 859, 3083, 2987, 896, 5056, 223 | 1905, 2918, 4415, 7966, 7646, 2883, 5628, 7017, 8029, 6528, 4474, 6322, 5562, 6669, 4610, 7006 224 | }; 225 | 226 | extern unsigned short hash_values[] = 227 | { 228 | 148, 2934, 166, 5107, 4628, 166, 166, 166, 166, 3033, 166, 4692, 166, 5571, 2225, 166, 229 | 5340, 3423, 166, 3191, 1752, 166, 5212, 166, 166, 3520, 166, 166, 166, 1867, 166, 3313, 230 | 166, 3461, 166, 166, 3174, 1737, 5010, 5008, 166, 4344, 2868, 3877, 166, 4089, 166, 5041, 231 | 4748, 4073, 4066, 5298, 3502, 1812, 166, 5309, 166, 233, 3493, 166, 166, 3728, 5236, 4252, 232 | 4010, 2149, 166, 164, 4580, 3039, 4804, 3874, 166, 6170, 2812, 166, 4334, 166, 166, 166, 233 | 166, 166, 166, 1862, 224, 2131, 6081, 166, 2710, 166, 166, 166, 4765, 166, 1964, 5060, 234 | 166, 1897, 166, 3987, 166, 166, 5566, 2021, 166, 45, 166, 166, 3283, 3932, 166, 166, 235 | 3519, 166, 166, 291, 166, 166, 5132, 2800, 166, 166, 166, 5531, 4054, 166, 3509, 166, 236 | 166, 4908, 3028, 1756, 1910, 4671, 2729, 5224, 166, 121, 3327, 3317, 166, 181, 2371, 5541, 237 | 166, 1787, 2666, 5134, 5698, 166, 5480, 3870, 166, 3823, 166, 3165, 5343, 5123, 5089, 166, 238 | 2422, 3724, 166, 2735, 1953, 5724, 4444, 4871, 166, 166, 5001, 5512, 3133, 5171, 166, 2216, 239 | 166, 4877, 4542, 166, 166, 166, 5270, 166, 166, 166, 1922, 69, 3547, 166, 166, 166, 240 | 166, 166, 231, 4547, 5155, 3357, 3464, 166, 72, 3332, 166, 4392, 5971, 3896, 4451, 3173, 241 | 2569, 166, 4466, 2518, 1698, 2850, 5349, 166, 166, 4457, 5062, 166, 2202, 1650, 2191, 166, 242 | 1950, 2583, 166, 5293, 2032, 5893, 166, 3994, 5392, 3878, 96, 166, 166, 3195, 166, 4001, 243 | 1900, 2513, 6027, 166, 166, 166, 166, 5407, 166, 166, 2332, 5125, 5891, 3096, 3172, 166, 244 | 166, 3065, 166, 166, 4535, 166, 166, 166, 4553, 3131, 3693, 166, 2255, 2613, 166, 166, 245 | 166, 166, 2866, 166, 166, 166, 2940, 5333, 3199, 166, 2628, 4312, 166, 166, 1794, 4681, 246 | 2058, 3606, 166, 166, 3542, 2166, 4696, 2520, 166, 4739, 166, 2563, 166, 166, 3681, 166, 247 | 166, 166, 4127, 1967, 2972, 166, 5227, 166, 166, 5551, 4255, 56, 166, 5553, 3219, 4367, 248 | 166, 3218, 4749, 2886, 3695, 3711, 2228, 166, 166, 166, 2268, 5054, 3749, 4825, 166, 4933, 249 | 4992, 4530, 166, 4892, 3400, 166, 197, 166, 6078, 166, 166, 3971, 166, 166, 5357, 1852, 250 | 3377, 166, 5196, 3740, 5320, 166, 166, 3099, 166, 4562, 6061, 3294, 166, 166, 166, 166, 251 | 3266, 3627, 2567, 166, 228, 2773, 166, 166, 53, 1833, 2401, 124, 166, 4272, 3922, 5959, 252 | 2903, 3923, 166, 6155, 166, 166, 166, 166, 216, 166, 5247, 166, 5591, 166, 166, 82, 253 | 87, 4526, 166, 166, 5439, 166, 4935, 166, 3187, 1869, 166, 1764, 5500, 6023, 3356, 166, 254 | 3350, 2457, 2455, 166, 1637, 166, 3342, 166, 166, 3355, 5154, 166, 276, 166, 166, 166, 255 | 3371, 5969, 166, 1665, 166, 166, 166, 166, 166, 166, 166, 4092, 1712, 3122, 5086, 166, 256 | 166, 4906, 166, 2591, 166, 166, 166, 1894, 2997, 166, 4476, 4384, 166, 4747, 4109, 2655, 257 | 166, 5978, 1636, 4898, 166, 166, 166, 166, 166, 166, 166, 5207, 166, 166, 3712, 3876, 258 | 91, 5876, 3786, 5998, 166, 166, 166, 4391, 166, 166, 2832, 2220, 4435, 166, 166, 5796, 259 | 3156, 6112, 166, 1643, 1821, 3129, 166, 4200, 166, 5857, 166, 166, 2351, 5902, 1855, 5043, 260 | 166, 3167, 5191, 3996, 5718, 4876, 3071, 2965, 5735, 5930, 6149, 2345, 3297, 3822, 166, 166, 261 | 307, 6019, 1859, 2981, 4914, 3320, 6165, 2328, 140, 2372, 308, 166, 2280, 5081, 166, 3275, 262 | 166, 159, 2399, 2327, 5489, 4690, 6059, 4492, 4269, 6058, 166, 19, 166, 3323, 5708, 128, 263 | 4812, 2949, 166, 166, 2890, 2630, 5237, 166, 256, 3673, 4621, 5380, 166, 3353, 166, 1651, 264 | 2573, 1635, 4011, 3429, 3370, 3720, 166, 166, 6108, 3848, 5104, 2851, 1998, 166, 166, 5106, 265 | 20, 166, 2633, 166, 166, 166, 166, 5662, 125, 3651, 1731, 4702, 166, 3197, 166, 2947, 266 | 3046, 4196, 2185, 6100, 166, 2602, 2908, 2487, 166, 5232, 166, 4028, 5919, 166, 2680, 3608, 267 | 3252, 166, 4899, 166, 166, 166, 166, 2529, 166, 166, 166, 166, 166, 2534, 166, 2299, 268 | 4076, 166, 3643, 166, 3921, 166, 166, 166, 1939, 2124, 1829, 2436, 3892, 166, 3481, 271, 269 | 5307, 1697, 166, 166, 5098, 2906, 5545, 166, 5980, 3203, 166, 1903, 4626, 4674, 6118, 6097, 270 | 5926, 4136, 1677, 3232, 4720, 166, 166, 166, 229, 2012, 3620, 166, 3798, 166, 166, 2609, 271 | 3489, 3809, 166, 166, 166, 166, 166, 166, 166, 5826, 166, 166, 166, 4903, 166, 166, 272 | 166, 166, 6168, 166, 5052, 5044, 5644, 2375, 2677, 4012, 3062, 5831, 4752, 166, 4125, 2610, 273 | 2062, 3238, 292, 2533, 5872, 51, 166, 1947, 4225, 166, 2288, 4845, 166, 5788, 166, 5717, 274 | 166, 166, 5549, 5619, 166, 4165, 166, 2721, 2311, 5501, 4416, 4383, 166, 166, 3068, 5499, 275 | 5936, 166, 4204, 4766, 4688, 1870, 5220, 166, 166, 166, 166, 237, 2523, 6039, 3061, 2793, 276 | 3998, 166, 2545, 2309, 3144, 3679, 3969, 166, 166, 166, 4379, 3574, 205, 2808, 5822, 166, 277 | 166, 2188, 4823, 4990, 5561, 5711, 166, 5627, 6034, 5253, 3783, 5047, 4405, 166, 59, 1755, 278 | 3178, 318, 166, 4710, 2933, 3409, 6062, 2821, 166, 6099, 166, 4178, 166, 166, 4122, 36, 279 | 4779, 166, 166, 4323, 3073, 5410, 2101, 166, 166, 44, 5690, 166, 3265, 166, 5222, 5909, 280 | 1838, 166, 4755, 2215, 166, 4082, 166, 166, 3210, 5140, 3124, 5238, 166, 5913, 2321, 166, 281 | 2416, 5976, 3918, 5078, 4218, 5703, 4897, 6011, 5685, 2214, 166, 166, 6180, 5175, 1715, 166, 282 | 166, 3760, 4497, 1808, 4826, 166, 2540, 166, 166, 5513, 4971, 5915, 166, 166, 2525, 166, 283 | 4480, 42, 232, 2412, 2797, 3229, 5263, 2852, 5543, 2126, 3562, 166, 2872, 4695, 5985, 5136, 284 | 2714, 4262, 5473, 166, 4160, 4347, 166, 166, 166, 166, 5271, 166, 166, 5108, 166, 166, 285 | 166, 166, 5437, 4875, 3963, 4362, 5820, 5559, 4890, 4728, 166, 166, 2692, 166, 4870, 3591, 286 | 5472, 166, 2690, 166, 5854, 3817, 166, 280, 166, 166, 113, 4128, 3396, 166, 4264, 5058, 287 | 2283, 166, 2281, 4916, 5671, 166, 2708, 166, 166, 4589, 166, 166, 4689, 166, 1686, 166, 288 | 166, 166, 166, 166, 1774, 166, 166, 166, 5651, 3777, 2234, 166, 3864, 18, 3589, 4592, 289 | 4777, 166, 166, 5254, 4245, 166, 166, 166, 4368, 5172, 3522, 166, 4306, 153, 5230, 166, 290 | 5598, 5420, 311, 2414, 4159, 2985, 5137, 166, 2179, 1801, 166, 4595, 2083, 2020, 166, 3602, 291 | 2170, 4259, 3048, 166, 166, 4193, 2350, 166, 166, 2702, 166, 4521, 166, 166, 2496, 166, 292 | 4593, 2006, 166, 166, 2292, 4135, 166, 6069, 4623, 166, 166, 4827, 3995, 4291, 3243, 166, 293 | 166, 166, 5622, 166, 3539, 166, 166, 4915, 4373, 2479, 3775, 6008, 5838, 4321, 1612, 5530, 294 | 166, 3773, 4267, 4086, 3081, 2261, 166, 166, 4785, 4641, 5292, 166, 4820, 5612, 5556, 166, 295 | 166, 166, 4396, 6084, 3414, 166, 3331, 2380, 5921, 4315, 2340, 166, 5511, 166, 4713, 3754, 296 | 2912, 2553, 166, 3468, 5388, 166, 1932, 3540, 5834, 166, 166, 3186, 5258, 166, 4107, 166, 297 | 166, 166, 166, 166, 166, 166, 166, 2108, 12, 2368, 2789, 166, 166, 4148, 1878, 166, 298 | 166, 2324, 4179, 2945, 2531, 166, 166, 166, 4485, 3765, 2308, 166, 2754, 166, 6102, 166, 299 | 1921, 260, 2241, 166, 2592, 166, 166, 166, 4964, 166, 3055, 5261, 4943, 2916, 166, 201, 300 | 5728, 166, 5759, 4314, 4730, 6024, 166, 4926, 4762, 1834, 2055, 166, 40, 166, 5416, 166, 301 | 3722, 2360, 1928, 166, 4889, 4590, 5550, 3498, 166, 6003, 2029, 4106, 4346, 3758, 166, 2753, 302 | 103, 1891, 5067, 166, 3398, 2079, 5784, 3074, 3787, 166, 166, 3936, 166, 5766, 166, 4847, 303 | 3928, 5119, 166, 5181, 4602, 2605, 5712, 4523, 166, 166, 4717, 166, 2227, 2181, 166, 4678, 304 | 166, 166, 4901, 166, 4980, 166, 166, 166, 166, 5806, 2894, 5631, 4995, 2608, 166, 166, 305 | 166, 3917, 166, 3417, 166, 2795, 1655, 3189, 3364, 166, 4839, 3510, 4212, 5641, 6091, 138, 306 | 166, 166, 3343, 4620, 2722, 4566, 166, 3518, 3424, 166, 166, 1653, 166, 5057, 166, 5375, 307 | 4833, 166, 4273, 4348, 166, 166, 166, 4912, 166, 3662, 166, 4281, 166, 5169, 166, 5883, 308 | 2737, 2572, 4685, 4068, 166, 4214, 166, 166, 2409, 166, 166, 4571, 166, 5624, 5722, 5949, 309 | 166, 3675, 166, 166, 5109, 3428, 166, 166, 5446, 166, 3290, 166, 3309, 166, 166, 4776, 310 | 166, 166, 166, 166, 166, 166, 5617, 2860, 166, 166, 166, 166, 3629, 1741, 166, 166, 311 | 183, 4973, 3047, 2854, 75, 2035, 3652, 2159, 166, 4150, 6037, 3225, 4519, 1902, 2678, 2413, 312 | 1961, 166, 166, 166, 166, 4972, 1847, 166, 5636, 4017, 166, 3345, 166, 4520, 166, 2861, 313 | 166, 3092, 6060, 157, 2542, 2298, 4496, 166, 2607, 6110, 5707, 2314, 166, 166, 273, 166, 314 | 5952, 166, 4957, 322, 6065, 2272, 6140, 2438, 3458, 3287, 166, 166, 166, 166, 2684, 288, 315 | 3354, 166, 166, 3983, 1702, 166, 166, 166, 2393, 2435, 4202, 3308, 5805, 5085, 166, 166, 316 | 1938, 166, 166, 2171, 5892, 2337, 166, 4648, 3116, 2486, 4363, 3567, 166, 166, 2822, 2041, 317 | 166, 4703, 3956, 5192, 166, 3975, 5720, 3647, 2134, 5932, 166, 166, 5160, 263, 166, 166, 318 | 166, 4549, 166, 166, 1701, 3086, 166, 166, 4737, 166, 2252, 166, 170, 166, 166, 166, 319 | 2301, 5478, 166, 166, 5979, 3007, 166, 166, 166, 4104, 166, 2469, 2700, 166, 4998, 3376, 320 | 166, 1840, 166, 166, 4470, 166, 5235, 3930, 166, 166, 166, 6031, 166, 166, 166, 3827, 321 | 4700, 166, 166, 166, 166, 166, 166, 4103, 3976, 166, 166, 166, 166, 5027, 4322, 5130, 322 | 166, 4741, 2132, 4118, 3080, 4137, 166, 6179, 166, 166, 166, 166, 166, 6120, 4188, 166, 323 | 2251, 166, 3253, 166, 4887, 166, 4293, 5241, 166, 166, 166, 166, 166, 166, 5076, 166, 324 | 166, 4177, 166, 221, 166, 2757, 5377, 166, 43, 166, 166, 3180, 5540, 166, 213, 4541, 325 | 166, 166, 166, 166, 166, 1641, 166, 4578, 4639, 166, 166, 1683, 2139, 1689, 5249, 5773, 326 | 5226, 166, 2820, 166, 5516, 5045, 166, 4896, 5657, 5189, 166, 5770, 2725, 5148, 166, 166, 327 | 166, 2929, 166, 3479, 166, 166, 4564, 3752, 4305, 4232, 166, 5906, 1779, 166, 2709, 4941, 328 | 4342, 166, 4882, 166, 4277, 2322, 166, 4879, 1610, 3038, 166, 3762, 2054, 5652, 166, 4524, 329 | 3820, 4806, 166, 166, 104, 3416, 4869, 4243, 4854, 166, 4114, 166, 2121, 166, 3463, 3556, 330 | 166, 4795, 166, 2118, 3920, 166, 166, 4667, 5046, 166, 166, 2088, 4360, 5787, 2198, 4233, 331 | 5552, 3970, 3523, 2037, 5791, 166, 166, 4299, 2336, 166, 166, 166, 4173, 4588, 3626, 5187, 332 | 166, 3363, 4611, 294, 4962, 5243, 2719, 6022, 4976, 3559, 166, 2662, 5779, 6151, 166, 3527, 333 | 166, 5404, 6132, 1839, 166, 3090, 166, 2253, 166, 5441, 5518, 6049, 166, 166, 6136, 3026, 334 | 3474, 5960, 166, 3937, 4105, 166, 2348, 2039, 4738, 166, 5233, 3882, 3840, 166, 278, 190, 335 | 166, 5751, 4313, 166, 3855, 166, 166, 6171, 166, 166, 5381, 3941, 166, 166, 166, 166, 336 | 3334, 166, 2038, 6088, 166, 1918, 5037, 2325, 2378, 4894, 3514, 3715, 5168, 166, 166, 4083, 337 | 2873, 166, 166, 166, 2693, 166, 3543, 166, 2577, 3013, 166, 166, 4594, 2622, 166, 166, 338 | 166, 3401, 166, 166, 5447, 5328, 5547, 6133, 2335, 3739, 166, 166, 166, 166, 5614, 3492, 339 | 3610, 3466, 166, 5336, 4354, 166, 4662, 166, 166, 4283, 166, 166, 303, 5904, 166, 2717, 340 | 166, 166, 2276, 5564, 2386, 5661, 2040, 166, 1630, 4652, 166, 4840, 166, 110, 5329, 3979, 341 | 5734, 2550, 166, 166, 6007, 5999, 2978, 4771, 5360, 166, 4023, 166, 166, 5920, 4065, 166, 342 | 3880, 166, 5422, 1813, 166, 6166, 73, 166, 166, 3669, 5762, 5077, 166, 2953, 85, 166, 343 | 3517, 166, 116, 166, 2738, 3710, 166, 1634, 166, 166, 166, 2290, 3001, 166, 166, 3037, 344 | 2400, 3410, 166, 1791, 4231, 166, 3546, 5009, 5299, 2807, 166, 166, 1675, 1619, 2374, 3093, 345 | 5302, 3278, 2330, 5301, 2343, 2307, 3274, 5017, 2265, 3700, 2465, 166, 139, 4292, 166, 5056, 346 | 3952, 166, 4528, 2388, 1886, 166, 166, 3016, 3698, 5881, 166, 2379, 3223, 166, 166, 3847, 347 | 2407, 5493, 3183, 3307, 166, 265, 166, 2421, 6161, 2057, 5363, 3863, 2474, 166, 166, 5427, 348 | 166, 2140, 2955, 166, 3070, 4237, 5018, 5988, 5570, 275, 4862, 2357, 166, 195, 166, 2593, 349 | 6047, 166, 2878, 166, 166, 2781, 3004, 4180, 166, 5593, 166, 5973, 2544, 5064, 166, 4324, 350 | 4701, 166, 3084, 166, 166, 5372, 4725, 166, 5650, 166, 166, 2786, 166, 3781, 3583, 3682, 351 | 1850, 4420, 3296, 5173, 4461, 166, 166, 166, 2984, 166, 93, 166, 166, 4336, 5943, 2922, 352 | 3300, 166, 4843, 166, 166, 166, 166, 2094, 166, 2939, 166, 4656, 166, 5146, 166, 166, 353 | 166, 166, 2104, 3977, 4660, 5312, 166, 1865, 166, 5487, 5558, 3380, 166, 1957, 3162, 3281, 354 | 166, 3588, 3268, 2099, 166, 166, 2319, 4913, 4187, 5503, 5782, 150, 166, 52, 5450, 166, 355 | 166, 166, 2941, 5877, 166, 4031, 5393, 166, 3931, 4166, 3135, 3445, 166, 5053, 5430, 4836, 356 | 166, 5315, 3389, 4636, 166, 166, 3441, 166, 166, 3767, 2961, 166, 4761, 4604, 3179, 166, 357 | 166, 4751, 2148, 2015, 166, 123, 5013, 166, 2936, 166, 2063, 166, 5823, 166, 5096, 166, 358 | 166, 4198, 166, 166, 166, 3845, 166, 166, 238, 166, 2703, 3541, 166, 4813, 166, 4477, 359 | 2349, 4197, 5996, 3324, 4789, 3063, 166, 166, 5504, 5273, 2805, 13, 166, 5601, 5402, 4119, 360 | 5206, 166, 166, 4251, 3704, 4176, 1963, 2882, 166, 202, 3125, 3318, 112, 166, 3362, 4835, 361 | 3420, 3974, 5099, 166, 4433, 166, 166, 166, 1766, 2663, 166, 166, 4683, 166, 166, 5485, 362 | 47, 5101, 5341, 5765, 3390, 1648, 4341, 3945, 6045, 1645, 166, 5578, 2594, 166, 166, 3772, 363 | 166, 166, 3196, 3603, 166, 5399, 166, 5075, 166, 5911, 4632, 4781, 5313, 270, 166, 2346, 364 | 166, 166, 166, 1986, 166, 166, 4958, 166, 166, 166, 4048, 166, 3076, 166, 166, 4891, 365 | 166, 166, 57, 166, 220, 166, 166, 166, 4117, 166, 166, 166, 166, 5194, 2658, 166, 366 | 166, 2942, 6071, 4182, 166, 2976, 5816, 166, 166, 166, 166, 3985, 4211, 2514, 166, 166, 367 | 166, 2504, 3446, 1711, 166, 166, 2107, 5190, 166, 34, 166, 3912, 5382, 3003, 166, 166, 368 | 166, 2999, 2404, 4734, 4455, 2087, 166, 2405, 156, 166, 2830, 3303, 296, 3295, 2067, 4268, 369 | 166, 166, 5642, 166, 166, 1901, 166, 5133, 166, 166, 166, 166, 3176, 2973, 4677, 166, 370 | 166, 6164, 3000, 2396, 2734, 5697, 5989, 166, 2823, 5265, 5852, 166, 166, 2623, 2625, 2287, 371 | 4844, 1758, 166, 166, 166, 166, 166, 6073, 166, 5379, 2389, 5279, 2444, 5515, 166, 4038, 372 | 166, 4948, 5640, 166, 166, 3572, 4258, 166, 166, 166, 5204, 166, 4603, 5797, 166, 166, 373 | 166, 1725, 4600, 166, 166, 5498, 166, 4152, 166, 172, 4758, 166, 2598, 2489, 2076, 4366, 374 | 2568, 166, 4352, 3782, 166, 166, 3059, 3946, 5138, 5727, 4484, 5694, 166, 3796, 166, 166, 375 | 166, 166, 5334, 1778, 2245, 166, 4517, 4419, 2250, 182, 5856, 166, 2835, 4495, 1858, 2033, 376 | 6014, 6086, 3211, 166, 166, 154, 2145, 166, 129, 3661, 2661, 5860, 6143, 2640, 3890, 6160, 377 | 166, 166, 2747, 166, 166, 2291, 282, 2476, 166, 166, 3825, 166, 1925, 166, 4489, 166, 378 | 166, 166, 4034, 166, 166, 166, 166, 166, 166, 122, 4708, 4919, 2373, 2453, 5419, 5954, 379 | 297, 5290, 166, 1978, 166, 4932, 3501, 166, 3085, 3386, 166, 5405, 4512, 166, 3209, 5740, 380 | 4020, 5495, 5815, 314, 166, 3190, 4824, 166, 166, 3448, 207, 1623, 6096, 5878, 166, 1836, 381 | 166, 166, 2728, 166, 5278, 3419, 3012, 5618, 5266, 3078, 166, 166, 2244, 166, 4569, 6068, 382 | 166, 3336, 166, 5677, 6052, 5079, 166, 5453, 5245, 5799, 166, 1982, 166, 5958, 4619, 5821, 383 | 166, 5285, 284, 1631, 5710, 6070, 5365, 2189, 3242, 166, 2752, 5483, 5297, 6150, 5522, 166, 384 | 1815, 166, 166, 166, 5801, 166, 166, 5398, 166, 166, 166, 2967, 2515, 3169, 166, 166, 385 | 2562, 166, 1617, 2069, 166, 166, 6154, 166, 3721, 166, 5327, 166, 166, 166, 5592, 166, 386 | 166, 2286, 1716, 3903, 166, 2395, 286, 3587, 6146, 3286, 4186, 5882, 5894, 5737, 6032, 5879, 387 | 2761, 4829, 3788, 166, 166, 3233, 5356, 5693, 166, 2429, 2449, 141, 3444, 5186, 166, 166, 388 | 3477, 4080, 4584, 166, 166, 3670, 1851, 3824, 4337, 3886, 2792, 166, 5867, 166, 166, 3557, 389 | 3147, 166, 166, 2200, 166, 2505, 166, 4310, 4865, 5656, 5992, 5672, 166, 5199, 135, 3023, 390 | 2994, 4472, 166, 166, 166, 2019, 4319, 3472, 166, 166, 166, 29, 206, 3944, 3027, 5804, 391 | 4731, 5449, 166, 2825, 3310, 166, 6172, 5202, 166, 2516, 3644, 4557, 166, 166, 166, 166, 392 | 2671, 4427, 3432, 3276, 5584, 5536, 4645, 3202, 166, 2612, 166, 4249, 2425, 3259, 4622, 166, 393 | 2411, 4303, 4206, 166, 166, 166, 3734, 6063, 118, 166, 166, 3641, 166, 166, 166, 4937, 394 | 1871, 3421, 2208, 166, 166, 166, 166, 4881, 166, 166, 166, 166, 3298, 166, 61, 166, 395 | 166, 166, 3293, 6145, 71, 3619, 166, 166, 3383, 1624, 320, 2187, 4113, 166, 166, 166, 396 | 166, 166, 5080, 2344, 5625, 2358, 1621, 4230, 5579, 5359, 295, 4248, 5267, 3883, 6124, 187, 397 | 5112, 2122, 166, 166, 166, 5142, 6004, 166, 5322, 6175, 3639, 3182, 4425, 166, 175, 166, 398 | 166, 166, 5778, 3939, 3484, 166, 166, 5832, 5248, 5935, 4467, 5858, 166, 5038, 166, 166, 399 | 3102, 166, 4880, 166, 166, 166, 166, 3418, 1666, 5338, 3680, 5291, 4441, 3385, 166, 5733, 400 | 4503, 2774, 166, 2631, 4153, 166, 2000, 166, 166, 5345, 166, 166, 4298, 1804, 4707, 166, 401 | 1613, 1952, 2111, 166, 166, 166, 166, 166, 2897, 166, 166, 4044, 166, 166, 166, 166, 402 | 2863, 5475, 166, 166, 166, 1704, 166, 3609, 2782, 2018, 166, 5361, 166, 3694, 3733, 166, 403 | 2785, 1969, 166, 166, 2834, 1868, 3779, 1877, 60, 166, 4143, 3902, 166, 4361, 3188, 2498, 404 | 6009, 166, 115, 166, 3138, 166, 4575, 6080, 133, 2030, 166, 166, 166, 2306, 2136, 3043, 405 | 3447, 2142, 166, 3799, 1646, 5269, 3640, 166, 2674, 5502, 166, 5467, 166, 5069, 166, 166, 406 | 4654, 4581, 5274, 5036, 4364, 166, 3115, 166, 2128, 4544, 5433, 2086, 2584, 4413, 166, 166, 407 | 5385, 166, 234, 166, 1625, 166, 166, 166, 5139, 2511, 4974, 2766, 166, 166, 166, 2095, 408 | 3990, 217, 166, 2988, 4061, 166, 209, 4883, 166, 166, 166, 166, 166, 4326, 166, 5465, 409 | 2859, 166, 2887, 166, 2231, 166, 1658, 166, 2246, 166, 1844, 166, 166, 3087, 2871, 3872, 410 | 1660, 48, 166, 166, 3622, 166, 1709, 166, 166, 6177, 6173, 166, 3569, 166, 166, 166, 411 | 241, 3660, 3631, 166, 166, 5319, 5141, 174, 166, 166, 4412, 166, 5145, 166, 1919, 166, 412 | 5276, 166, 2385, 166, 1618, 166, 166, 2501, 166, 166, 1734, 5966, 3145, 166, 1690, 4025, 413 | 1664, 4559, 2433, 2392, 3552, 4006, 1896, 166, 166, 2546, 4450, 5396, 4221, 4046, 166, 166, 414 | 2642, 166, 4448, 166, 2784, 3480, 4807, 166, 166, 3534, 166, 166, 5272, 166, 166, 2831, 415 | 4263, 166, 166, 166, 166, 4414, 5628, 3486, 166, 3748, 166, 4598, 3719, 3598, 3611, 166, 416 | 4792, 5059, 4110, 166, 2656, 166, 166, 84, 5429, 166, 166, 166, 281, 1955, 166, 166, 417 | 166, 3616, 4997, 166, 166, 166, 166, 3230, 166, 166, 166, 166, 166, 166, 77, 166, 418 | 166, 166, 1800, 166, 4236, 166, 166, 166, 166, 166, 5757, 2530, 1662, 166, 4607, 1659, 419 | 166, 1685, 3341, 166, 1699, 4058, 3407, 1854, 4417, 3034, 166, 166, 166, 166, 5568, 166, 420 | 3206, 166, 5529, 166, 166, 166, 2116, 3487, 144, 166, 166, 166, 5523, 5373, 5321, 166, 421 | 6064, 2921, 166, 1696, 2473, 166, 166, 3716, 5689, 166, 4608, 3879, 166, 166, 166, 2156, 422 | 166, 4358, 2446, 166, 3958, 166, 5520, 4340, 4848, 166, 3285, 166, 2665, 166, 3459, 1905, 423 | 5115, 68, 5730, 166, 3127, 5029, 4370, 166, 3753, 166, 3674, 6025, 4490, 166, 4183, 166, 424 | 94, 166, 166, 4051, 3766, 3140, 4907, 3857, 166, 166, 4596, 166, 3888, 3040, 2507, 5643, 425 | 166, 166, 4311, 2618, 5582, 166, 166, 3678, 166, 1988, 166, 166, 4464, 166, 166, 166, 426 | 166, 4278, 3677, 2173, 5256, 166, 166, 5162, 166, 5178, 1644, 5094, 166, 2557, 5506, 166, 427 | 166, 166, 4927, 5348, 1797, 166, 166, 39, 166, 3866, 3655, 236, 5403, 2175, 3361, 166, 428 | 1976, 5993, 226, 166, 4643, 166, 5339, 4098, 2653, 4969, 166, 3346, 4984, 4635, 166, 166, 429 | 166, 166, 4981, 188, 166, 166, 28, 4088, 166, 166, 166, 25, 3663, 2696, 166, 4679, 430 | 5114, 5802, 166, 166, 166, 166, 166, 3810, 5749, 166, 1673, 4276, 166, 3756, 4184, 166, 431 | 5630, 166, 166, 166, 4531, 212, 5663, 166, 166, 2746, 166, 5386, 3618, 3594, 1887, 166, 432 | 166, 5443, 166, 1726, 4094, 5065, 4756, 166, 166, 5308, 5225, 2081, 166, 166, 3064, 166, 433 | 166, 1981, 3637, 4355, 1626, 166, 166, 4686, 166, 5793, 180, 5066, 2938, 3819, 4904, 3601, 434 | 166, 166, 2495, 5025, 5768, 2621, 4650, 3041, 166, 5897, 3633, 166, 166, 4375, 166, 5714, 435 | 1667, 3273, 3950, 1668, 166, 5855, 166, 2364, 166, 1881, 166, 2646, 5460, 166, 2770, 4951, 436 | 5414, 166, 4442, 2113, 5726, 298, 5934, 2053, 166, 166, 4053, 166, 166, 4514, 4697, 166, 437 | 166, 5198, 2707, 166, 5605, 166, 166, 5218, 2596, 166, 2110, 166, 1806, 2160, 166, 166, 438 | 2212, 166, 3636, 166, 166, 4377, 4021, 3707, 4502, 166, 4195, 166, 166, 166, 4108, 3725, 439 | 3676, 166, 2084, 166, 166, 166, 166, 4216, 166, 166, 6156, 166, 2896, 166, 166, 166, 440 | 166, 166, 166, 3826, 2870, 3793, 166, 166, 5927, 166, 2759, 166, 4613, 2297, 5638, 166, 441 | 2842, 5031, 4793, 5184, 166, 166, 2008, 166, 257, 2881, 117, 6051, 3044, 4079, 2833, 166, 442 | 6117, 166, 3236, 5469, 166, 166, 2874, 6076, 166, 1799, 80, 41, 166, 1864, 166, 5709, 443 | 1611, 5026, 5176, 168, 3269, 4081, 166, 166, 1970, 4550, 166, 4250, 4101, 4565, 5950, 5845, 444 | 97, 4064, 166, 5394, 4374, 4343, 166, 166, 4658, 3248, 166, 208, 1735, 4047, 2843, 166, 445 | 166, 166, 166, 2794, 166, 166, 5844, 166, 166, 3094, 2177, 5436, 3646, 166, 3564, 4682, 446 | 166, 5948, 5835, 162, 2059, 5151, 2034, 1926, 5941, 5903, 5177, 166, 166, 166, 4801, 3439, 447 | 1780, 166, 166, 3280, 3434, 166, 166, 4498, 5565, 4043, 166, 4432, 4722, 3959, 166, 3746, 448 | 166, 166, 177, 166, 166, 2748, 166, 4483, 166, 166, 4144, 166, 166, 166, 166, 2066, 449 | 2915, 166, 2049, 2130, 4684, 166, 49, 3506, 5391, 166, 2590, 6103, 1714, 2410, 3053, 3837, 450 | 4301, 166, 3255, 2644, 166, 166, 4014, 166, 2475, 4788, 2876, 166, 166, 166, 166, 166, 451 | 166, 4140, 166, 166, 321, 166, 1966, 166, 166, 2855, 3111, 3800, 166, 4446, 2551, 166, 452 | 166, 166, 2824, 166, 166, 166, 2164, 3010, 2226, 166, 4857, 166, 2582, 5118, 4582, 5917, 453 | 166, 166, 3338, 3482, 3328, 166, 4817, 166, 5371, 3830, 166, 3009, 1633, 3329, 4052, 166, 454 | 3701, 4983, 4500, 4487, 4878, 166, 166, 5482, 3544, 166, 3057, 2026, 4398, 2847, 3532, 3262, 455 | 3399, 166, 166, 166, 4478, 4167, 166, 3411, 2599, 5362, 166, 2711, 166, 166, 166, 166, 456 | 3452, 2522, 5586, 5548, 3279, 2538, 166, 166, 166, 4161, 166, 2123, 166, 166, 2660, 166, 457 | 166, 1706, 166, 15, 3537, 5051, 5869, 166, 3025, 166, 4447, 3744, 120, 166, 166, 166, 458 | 204, 2810, 166, 5124, 2376, 5306, 166, 166, 4493, 166, 166, 166, 5289, 6046, 166, 2762, 459 | 2541, 1857, 2467, 5163, 166, 166, 166, 166, 5830, 166, 2172, 3359, 166, 2928, 166, 166, 460 | 166, 6129, 166, 5445, 166, 166, 5924, 6144, 166, 102, 166, 166, 1678, 166, 4491, 5705, 461 | 166, 1753, 166, 3873, 5725, 4145, 1909, 166, 2155, 166, 166, 1848, 3315, 1874, 166, 4945, 462 | 2524, 166, 3263, 2362, 1785, 166, 166, 166, 152, 2102, 5723, 5131, 5754, 4032, 4029, 166, 463 | 4295, 3391, 166, 166, 166, 5282, 1747, 3159, 2235, 5583, 1786, 3630, 6111, 2974, 4797, 3623, 464 | 166, 2071, 4929, 166, 2603, 3964, 3378, 166, 166, 2654, 151, 3940, 4527, 4518, 166, 2430, 465 | 1884, 3812, 166, 2867, 166, 166, 166, 2756, 5418, 166, 2354, 4606, 166, 2153, 166, 4855, 466 | 166, 166, 1720, 166, 3213, 3926, 166, 5158, 4349, 166, 4828, 166, 166, 2031, 166, 2300, 467 | 166, 166, 166, 2211, 4954, 3121, 4754, 2485, 166, 166, 166, 3593, 166, 2718, 5317, 2765, 468 | 5120, 166, 2527, 166, 1994, 5947, 166, 166, 166, 6085, 2302, 100, 79, 2982, 3705, 2180, 469 | 2043, 166, 1872, 1671, 166, 3729, 166, 4944, 3665, 2217, 2119, 166, 5615, 166, 1620, 166, 470 | 166, 166, 166, 35, 3913, 2760, 166, 3688, 3672, 4042, 166, 166, 5117, 4227, 166, 4445, 471 | 2458, 3803, 4554, 4988, 166, 166, 3141, 3491, 166, 166, 166, 166, 5095, 4668, 5567, 166, 472 | 166, 2885, 1790, 2996, 166, 166, 166, 166, 3737, 166, 2470, 166, 166, 4339, 166, 166, 473 | 166, 4920, 166, 166, 3697, 5471, 166, 166, 3538, 4558, 3467, 5262, 5609, 3858, 166, 166, 474 | 5007, 2780, 2791, 2236, 5668, 3134, 166, 166, 5776, 3470, 3291, 166, 2532, 166, 166, 166, 475 | 3805, 264, 166, 3227, 166, 166, 166, 2334, 166, 5087, 101, 166, 3634, 58, 2813, 166, 476 | 166, 166, 3222, 4704, 4488, 4508, 5459, 2117, 5873, 166, 1828, 166, 166, 166, 166, 166, 477 | 2105, 166, 5613, 5761, 2920, 3098, 166, 166, 3277, 166, 166, 166, 166, 83, 166, 166, 478 | 166, 3967, 166, 5574, 166, 4985, 30, 3426, 166, 179, 3014, 4015, 246, 2556, 4449, 3723, 479 | 5611, 3436, 166, 4240, 3642, 166, 4536, 2048, 5810, 166, 1971, 166, 5557, 5323, 5022, 191, 480 | 5492, 166, 4837, 4426, 2537, 2271, 3177, 5674, 166, 2796, 1995, 166, 3906, 166, 4403, 3862, 481 | 4716, 2406, 3948, 4670, 4309, 166, 2575, 5358, 2951, 166, 3666, 3612, 5577, 4579, 4743, 166, 482 | 6072, 6036, 4563, 2586, 166, 5836, 166, 166, 5752, 166, 3563, 166, 2909, 3251, 92, 166, 483 | 4711, 4149, 166, 166, 3052, 5122, 2904, 2635, 1990, 166, 166, 166, 166, 166, 166, 166, 484 | 166, 4213, 166, 3103, 3142, 2683, 6105, 2209, 3175, 4215, 166, 166, 166, 166, 166, 166, 485 | 166, 5303, 4075, 5374, 166, 4174, 4154, 1895, 4538, 2764, 166, 5817, 6113, 4033, 166, 6090, 486 | 166, 2990, 166, 3164, 166, 166, 166, 247, 166, 6083, 3412, 166, 5738, 166, 3599, 166, 487 | 1904, 2162, 2547, 3960, 166, 166, 3154, 55, 166, 5991, 4921, 2879, 166, 166, 5347, 166, 488 | 166, 166, 2712, 4787, 166, 1908, 166, 166, 166, 3184, 166, 166, 166, 4572, 3846, 3657, 489 | 166, 166, 5481, 166, 166, 3397, 1856, 4978, 166, 3900, 3570, 3802, 166, 166, 2075, 4408, 490 | 166, 6079, 2313, 166, 166, 5756, 166, 166, 2070, 166, 166, 3137, 166, 166, 3686, 166, 491 | 166, 166, 166, 67, 5019, 166, 1742, 166, 5354, 166, 5149, 166, 2931, 4946, 6006, 166, 492 | 166, 2865, 4902, 3029, 1722, 3449, 166, 1987, 166, 62, 5626, 166, 166, 166, 2670, 1657, 493 | 5599, 3056, 166, 3791, 5020, 166, 1979, 4437, 1899, 166, 166, 196, 2636, 166, 143, 3475, 494 | 4317, 2512, 2415, 5033, 5024, 2112, 2864, 3551, 166, 1688, 33, 4585, 3648, 4399, 166, 166, 495 | 166, 166, 166, 1824, 166, 166, 166, 166, 166, 166, 4513, 166, 2478, 4407, 166, 166, 496 | 2492, 4130, 4318, 2980, 5746, 166, 2606, 4063, 4123, 166, 255, 166, 166, 4680, 166, 3586, 497 | 5975, 3935, 166, 5528, 166, 3158, 166, 166, 2614, 5035, 166, 3488, 3214, 166, 166, 166, 498 | 5413, 3713, 166, 5875, 4329, 5250, 166, 166, 3741, 166, 54, 1885, 3839, 166, 4924, 166, 499 | 166, 166, 4158, 166, 166, 2152, 1661, 166, 166, 4327, 166, 3933, 166, 5666, 166, 166, 500 | 2580, 166, 3404, 4111, 2862, 4438, 166, 166, 4072, 166, 166, 3938, 2958, 4302, 166, 3851, 501 | 166, 268, 166, 166, 1975, 222, 3204, 3438, 4616, 166, 4275, 3101, 2648, 3989, 5215, 166, 502 | 4229, 166, 5440, 166, 5093, 2639, 166, 166, 4439, 166, 2316, 4239, 166, 166, 166, 166, 503 | 166, 1817, 4486, 166, 3272, 166, 166, 4085, 2078, 2902, 166, 166, 166, 4381, 1853, 3054, 504 | 166, 166, 5005, 2669, 166, 2856, 2706, 166, 166, 166, 4185, 166, 1748, 166, 166, 166, 505 | 5771, 166, 166, 3915, 166, 166, 2205, 6122, 166, 166, 1632, 5400, 166, 2477, 4740, 166, 506 | 166, 166, 1802, 166, 2472, 3953, 166, 1849, 2604, 3780, 2560, 4786, 2566, 3576, 166, 4768, 507 | 166, 1951, 251, 5068, 166, 166, 166, 2619, 166, 166, 166, 5432, 166, 166, 5260, 5758, 508 | 3908, 166, 4141, 166, 5777, 166, 166, 166, 166, 166, 3961, 5143, 166, 3889, 3747, 3743, 509 | 166, 2818, 166, 166, 166, 3867, 166, 166, 3742, 4763, 2948, 5533, 166, 3966, 3555, 3843, 510 | 3503, 6005, 166, 4687, 2790, 4479, 5828, 3769, 5688, 166, 166, 166, 166, 3109, 166, 166, 511 | 166, 166, 4574, 81, 166, 166, 4576, 3369, 166, 166, 166, 4207, 166, 5072, 2210, 166, 512 | 184, 166, 4673, 166, 166, 166, 166, 166, 166, 1628, 3590, 1916, 4784, 4970, 166, 1832, 513 | 166, 166, 3584, 3384, 166, 166, 2880, 1783, 166, 166, 166, 166, 6115, 6121, 2157, 5428, 514 | 5859, 4861, 5635, 4331, 5839, 4223, 313, 166, 166, 6152, 2168, 166, 4112, 6089, 6012, 166, 515 | 5294, 3207, 166, 166, 4884, 166, 4655, 166, 166, 166, 1743, 166, 4077, 166, 4631, 166, 516 | 166, 2957, 1945, 4936, 166, 166, 5389, 166, 166, 5955, 166, 166, 1639, 2207, 4129, 166, 517 | 3582, 5560, 6147, 3088, 166, 166, 4529, 5259, 3118, 166, 3106, 2853, 166, 1845, 5660, 166, 518 | 3325, 3973, 2461, 2163, 166, 3083, 4190, 166, 166, 5505, 166, 166, 3226, 5507, 109, 6141, 519 | 3991, 166, 4939, 166, 166, 5889, 3986, 166, 3664, 4353, 2056, 166, 5071, 166, 166, 4376, 520 | 166, 1958, 2028, 166, 166, 1793, 166, 5252, 3536, 166, 166, 3525, 3580, 166, 166, 166, 521 | 1782, 5174, 2011, 1826, 3352, 3231, 166, 166, 4986, 2068, 2801, 166, 2500, 166, 5061, 166, 522 | 2263, 2632, 1993, 166, 2715, 4424, 166, 166, 6042, 4661, 166, 5074, 5479, 4822, 166, 166, 523 | 166, 166, 5600, 5853, 166, 1907, 166, 166, 166, 3808, 166, 5997, 5032, 4605, 166, 1732, 524 | 166, 166, 166, 3015, 5454, 166, 166, 166, 3806, 5444, 2238, 1946, 166, 166, 3221, 4922, 525 | 166, 6092, 166, 166, 4007, 166, 3425, 4282, 2571, 166, 1749, 166, 166, 38, 4744, 4900, 526 | 4257, 214, 5687, 166, 2490, 2979, 2924, 166, 4714, 219, 5344, 3836, 3302, 78, 1984, 2986, 527 | 2960, 166, 2869, 3507, 3335, 4967, 2892, 2723, 4849, 5070, 166, 166, 4629, 3815, 166, 4453, 528 | 4760, 166, 3224, 130, 166, 166, 166, 166, 166, 3408, 2494, 2691, 166, 4325, 2932, 5165, 529 | 5573, 166, 4769, 166, 5411, 5637, 2050, 166, 166, 2305, 166, 166, 4834, 24, 4693, 3554, 530 | 2491, 1738, 166, 166, 166, 23, 2758, 3072, 2564, 4800, 5537, 3545, 4133, 166, 166, 166, 531 | 5982, 166, 203, 166, 166, 290, 185, 166, 3774, 1929, 3379, 166, 166, 166, 166, 3002, 532 | 166, 3738, 166, 166, 3344, 4942, 5353, 2777, 2839, 4712, 1830, 2664, 166, 5884, 3516, 166, 533 | 5494, 4169, 2391, 3319, 166, 166, 5918, 2597, 166, 4821, 2787, 5719, 166, 166, 166, 1687, 534 | 6148, 3257, 254, 166, 5180, 6153, 5964, 306, 166, 6123, 166, 5208, 166, 3163, 5938, 1736, 535 | 166, 2502, 4910, 166, 166, 2549, 166, 2900, 3632, 3270, 166, 2082, 5953, 166, 107, 5750, 536 | 166, 166, 166, 5527, 1751, 4168, 2950, 166, 2659, 166, 4189, 1943, 2595, 166, 4191, 166, 537 | 166, 166, 166, 2998, 2296, 5221, 3617, 166, 5435, 2451, 2009, 3005, 2242, 3768, 3658, 166, 538 | 166, 166, 166, 166, 2481, 2256, 166, 166, 4074, 166, 3120, 166, 4409, 1759, 166, 166, 539 | 1679, 3659, 3499, 5219, 4501, 3082, 2047, 166, 166, 166, 4560, 2768, 5251, 166, 166, 166, 540 | 2437, 3993, 3215, 2447, 166, 166, 166, 2993, 4963, 166, 3045, 166, 166, 166, 166, 166, 541 | 166, 166, 5521, 166, 166, 4868, 166, 3895, 166, 6131, 3949, 3306, 3785, 166, 166, 4895, 542 | 4831, 166, 1772, 166, 166, 5928, 166, 2137, 4805, 2462, 310, 2667, 3561, 166, 166, 2312, 543 | 4931, 5255, 166, 166, 166, 5670, 166, 2285, 166, 4672, 5310, 166, 2103, 2174, 166, 166, 544 | 166, 166, 5417, 166, 4726, 4203, 166, 166, 166, 5581, 166, 5665, 166, 166, 5747, 166, 545 | 166, 2509, 1973, 2749, 5463, 166, 166, 4567, 5014, 166, 3322, 3051, 166, 4090, 166, 3709, 546 | 3887, 3478, 166, 166, 166, 166, 3565, 3934, 166, 32, 166, 166, 166, 2239, 166, 3947, 547 | 3849, 166, 2022, 166, 2169, 166, 4691, 98, 166, 3804, 4155, 1640, 4002, 166, 2138, 1739, 548 | 3730, 5970, 2274, 4873, 3119, 166, 4925, 3577, 3699, 4049, 3982, 166, 5161, 1744, 166, 166, 549 | 166, 5704, 4979, 2686, 5383, 5744, 2289, 166, 166, 166, 3927, 2539, 166, 166, 166, 2585, 550 | 166, 4723, 3755, 4509, 166, 4961, 2194, 2535, 166, 176, 166, 4494, 166, 4171, 166, 266, 551 | 166, 3454, 5369, 166, 166, 5899, 5284, 166, 3607, 3566, 5514, 166, 1843, 166, 3997, 4599, 552 | 2743, 166, 2857, 2497, 2751, 166, 166, 166, 3511, 5742, 166, 166, 166, 4504, 166, 166, 553 | 166, 5082, 4401, 166, 166, 5431, 166, 166, 1949, 4539, 166, 166, 4852, 166, 166, 3457, 554 | 166, 3433, 4669, 166, 1692, 2454, 3258, 6159, 166, 166, 166, 166, 166, 2788, 4350, 3249, 555 | 3816, 4893, 166, 4846, 166, 4993, 1708, 4138, 166, 2895, 2891, 166, 1860, 166, 2480, 1927, 556 | 3853, 166, 166, 166, 5100, 166, 3143, 5159, 166, 4286, 5182, 5246, 4975, 166, 2905, 166, 557 | 4917, 5102, 2044, 6016, 5673, 2005, 5090, 166, 4634, 3333, 166, 5702, 3413, 1762, 6094, 4284, 558 | 4431, 2641, 166, 4463, 5691, 166, 166, 3442, 3473, 4192, 2046, 166, 3838, 166, 3217, 3349, 559 | 166, 2243, 166, 3490, 166, 166, 166, 5922, 166, 166, 166, 4885, 1798, 2884, 2750, 5004, 560 | 2741, 166, 166, 5649, 166, 4410, 166, 166, 3382, 166, 166, 1913, 1703, 5532, 3770, 166, 561 | 5116, 2645, 2634, 4357, 5901, 166, 166, 5538, 166, 166, 166, 6028, 166, 166, 5840, 4102, 562 | 2704, 2091, 5287, 166, 4757, 2282, 166, 2650, 3528, 64, 253, 3732, 166, 166, 166, 166, 563 | 166, 3465, 166, 166, 166, 5848, 3110, 111, 166, 166, 3403, 2926, 6030, 3366, 1948, 4430, 564 | 5509, 3250, 3972, 2587, 3579, 166, 6048, 250, 5275, 4242, 2615, 3112, 3558, 166, 166, 2342, 565 | 166, 5157, 1917, 2733, 5647, 1934, 5675, 166, 3981, 2923, 5213, 5326, 37, 166, 5288, 3069, 566 | 166, 1923, 5755, 166, 166, 166, 1888, 166, 6041, 5895, 5376, 3727, 3901, 166, 5589, 166, 567 | 166, 4609, 166, 166, 166, 4706, 166, 4482, 1622, 166, 171, 166, 166, 4646, 4151, 2755, 568 | 4614, 166, 2072, 5409, 4469, 1647, 4434, 4633, 1915, 166, 3615, 4808, 166, 3388, 166, 5280, 569 | 2731, 166, 166, 2417, 166, 14, 166, 4533, 5126, 166, 2778, 3022, 166, 166, 166, 4830, 570 | 4764, 166, 166, 166, 4982, 166, 4265, 166, 2466, 5678, 147, 1883, 166, 166, 166, 114, 571 | 4000, 2427, 3597, 166, 4853, 5981, 166, 2023, 2519, 166, 1937, 2221, 4676, 166, 4522, 5716, 572 | 166, 2432, 5731, 166, 6020, 6163, 4351, 2442, 4380, 166, 4390, 1882, 6139, 4246, 262, 166, 573 | 1676, 5781, 2352, 1956, 200, 166, 166, 5800, 6184, 166, 2355, 149, 5962, 5524, 4238, 166, 574 | 5150, 166, 5888, 2423, 166, 5739, 3192, 4142, 166, 166, 166, 3201, 161, 4460, 2459, 158, 575 | 166, 166, 166, 166, 2689, 166, 166, 166, 166, 1889, 166, 166, 3374, 166, 70, 166, 576 | 2772, 166, 2995, 166, 2384, 4989, 166, 3299, 166, 166, 166, 166, 3614, 3645, 3415, 3160, 577 | 1727, 3735, 5201, 1693, 3531, 166, 166, 1776, 3871, 166, 166, 166, 166, 86, 3553, 166, 578 | 166, 166, 3392, 166, 166, 2232, 166, 4977, 2333, 3394, 2875, 2027, 5736, 166, 1719, 166, 579 | 4952, 2061, 2150, 5526, 166, 4637, 166, 4333, 166, 166, 4733, 4809, 3911, 166, 3460, 166, 580 | 5355, 3126, 4181, 4436, 300, 166, 3841, 166, 4770, 126, 5654, 166, 166, 166, 1730, 166, 581 | 166, 166, 5610, 166, 6002, 2197, 3807, 6109, 166, 166, 166, 166, 166, 5395, 4004, 166, 582 | 46, 166, 166, 2570, 4736, 5318, 4247, 166, 166, 166, 2293, 3031, 4591, 166, 245, 166, 583 | 5510, 1616, 3117, 4163, 166, 166, 4759, 3462, 4819, 4947, 166, 3128, 5946, 2278, 2969, 166, 584 | 166, 5183, 166, 166, 1729, 173, 2448, 166, 230, 2971, 166, 166, 5397, 166, 4093, 3348, 585 | 1866, 4280, 166, 6067, 3794, 166, 166, 166, 4729, 166, 3456, 166, 2394, 166, 4953, 166, 586 | 166, 2258, 4863, 166, 166, 4060, 166, 5468, 305, 166, 6134, 166, 166, 2326, 166, 3453, 587 | 2167, 2845, 166, 166, 166, 5597, 166, 166, 166, 166, 5462, 2809, 5994, 2899, 166, 166, 588 | 166, 5153, 166, 166, 1638, 166, 166, 4938, 3795, 166, 3842, 166, 166, 166, 2769, 3194, 589 | 166, 4745, 5508, 5604, 3910, 166, 166, 4147, 3239, 166, 166, 3548, 3859, 2092, 166, 2705, 590 | 166, 166, 3625, 4131, 166, 3513, 166, 166, 2987, 4555, 3107, 166, 166, 166, 166, 5713, 591 | 4698, 3079, 166, 5342, 166, 166, 2673, 2517, 2745, 1795, 166, 166, 166, 166, 166, 166, 592 | 2463, 166, 166, 2445, 5425, 6138, 166, 2687, 3254, 5871, 166, 2387, 4300, 166, 166, 3529, 593 | 1996, 166, 2369, 3818, 6126, 1615, 2643, 65, 4297, 166, 5324, 3311, 3852, 166, 3868, 4199, 594 | 3978, 166, 166, 166, 5466, 166, 166, 244, 166, 5929, 6157, 2390, 5639, 2267, 2073, 4610, 595 | 5774, 2521, 4556, 166, 4545, 4307, 2426, 2450, 166, 5783, 4968, 6176, 4156, 166, 166, 4126, 596 | 3549, 166, 3581, 5701, 3234, 166, 4013, 1879, 166, 6104, 5874, 166, 166, 3485, 4279, 2528, 597 | 5576, 166, 3992, 166, 3980, 4934, 166, 2176, 4228, 5164, 3784, 1933, 4120, 5055, 166, 166, 598 | 5015, 166, 166, 166, 2310, 1754, 166, 6087, 166, 166, 4548, 5268, 2930, 166, 3656, 166, 599 | 3042, 5229, 166, 4016, 2195, 166, 166, 166, 199, 1745, 3717, 166, 166, 74, 2668, 252, 600 | 4124, 4657, 5223, 166, 2186, 3628, 166, 166, 166, 4222, 3114, 2841, 5103, 3171, 5135, 166, 601 | 166, 2273, 166, 3899, 5332, 5842, 3575, 2579, 2431, 2464, 2229, 3604, 4561, 2977, 2815, 166, 602 | 3916, 166, 5825, 166, 1694, 166, 4030, 166, 5841, 166, 3881, 1831, 166, 5525, 3011, 166, 603 | 5535, 5217, 316, 4116, 166, 166, 2204, 166, 3136, 3650, 166, 5813, 1875, 4511, 4475, 166, 604 | 1999, 166, 2277, 166, 3024, 5484, 5546, 166, 3988, 5676, 166, 2213, 2264, 5214, 166, 4940, 605 | 5974, 166, 4750, 6077, 166, 1652, 3148, 166, 166, 166, 166, 2554, 166, 6167, 5257, 5300, 606 | 166, 166, 166, 166, 5408, 166, 166, 3402, 2141, 166, 4663, 5633, 3312, 166, 2814, 4930, 607 | 1959, 166, 166, 166, 3861, 166, 166, 302, 2624, 166, 166, 166, 1629, 1724, 166, 3909, 608 | 5281, 166, 2001, 4395, 5352, 4428, 2694, 4850, 166, 166, 5242, 5910, 166, 166, 166, 166, 609 | 166, 3212, 166, 2045, 166, 166, 166, 166, 166, 166, 3017, 4960, 4456, 166, 5616, 6093, 610 | 2151, 166, 166, 166, 315, 3381, 166, 166, 166, 4330, 166, 6158, 4721, 6075, 166, 166, 611 | 166, 4543, 2303, 166, 166, 3301, 166, 5000, 3929, 2543, 3437, 166, 166, 166, 3422, 166, 612 | 5987, 5729, 2428, 166, 4035, 5588, 3714, 3834, 5264, 5743, 166, 3305, 4886, 6107, 5156, 166, 613 | 166, 166, 166, 166, 1672, 5849, 5827, 5049, 6101, 2178, 2420, 3289, 166, 166, 4274, 6017, 614 | 2257, 166, 4172, 3451, 2367, 2382, 166, 2964, 4918, 3241, 2347, 6082, 99, 2383, 166, 4454, 615 | 163, 2460, 165, 304, 1818, 5580, 166, 312, 5790, 293, 5794, 5519, 5083, 3360, 5748, 166, 616 | 3750, 5034, 166, 166, 166, 1863, 3168, 166, 166, 166, 5111, 166, 166, 166, 166, 2183, 617 | 4510, 166, 166, 3495, 4382, 4235, 4462, 166, 4056, 5885, 17, 5028, 1614, 6038, 166, 2488, 618 | 5632, 3089, 166, 1940, 66, 4039, 3999, 235, 166, 166, 3829, 3954, 166, 2365, 269, 166, 619 | 166, 166, 166, 166, 166, 4418, 1796, 4709, 2004, 166, 3596, 5786, 166, 2819, 4624, 3152, 620 | 2968, 2838, 166, 5575, 1767, 5603, 166, 4386, 5890, 166, 1768, 4201, 3560, 166, 166, 166, 621 | 2184, 2262, 2966, 2716, 1765, 2611, 2983, 166, 4164, 4084, 142, 5314, 166, 166, 4071, 166, 622 | 2578, 2849, 3600, 166, 166, 166, 166, 5401, 4814, 3431, 166, 5088, 5084, 198, 166, 3578, 623 | 3764, 166, 2097, 166, 166, 5390, 4443, 166, 3166, 166, 4816, 166, 166, 166, 166, 3130, 624 | 5963, 1788, 2129, 1837, 4100, 6128, 166, 4586, 5945, 4772, 166, 5741, 3151, 3247, 5645, 4507, 625 | 5833, 3904, 6013, 2506, 3050, 4175, 1705, 3019, 166, 5942, 166, 2418, 3430, 2230, 5745, 166, 626 | 2093, 166, 166, 166, 166, 4666, 3246, 192, 2010, 4003, 3533, 5851, 166, 3621, 3684, 3066, 627 | 166, 166, 166, 5073, 3856, 166, 166, 2224, 166, 2637, 4270, 166, 166, 5679, 166, 5792, 628 | 5850, 166, 2589, 3060, 2196, 3476, 3150, 2025, 166, 166, 166, 2657, 166, 3685, 3790, 5587, 629 | 2817, 3692, 166, 166, 166, 2359, 2260, 5896, 2158, 119, 2816, 5753, 166, 2739, 5772, 166, 630 | 2919, 2147, 1985, 4271, 4838, 4991, 166, 166, 166, 5244, 166, 319, 166, 166, 2779, 4732, 631 | 4994, 5424, 166, 166, 3968, 3049, 3393, 4473, 4959, 5967, 5864, 5170, 4209, 166, 4810, 4815, 632 | 4205, 2339, 5023, 2279, 5050, 166, 5837, 132, 166, 166, 166, 2247, 21, 4775, 166, 166, 633 | 5286, 166, 4170, 4099, 4803, 5767, 166, 166, 166, 5811, 2240, 5699, 2499, 166, 4802, 166, 634 | 5785, 166, 166, 166, 3181, 3435, 166, 3339, 166, 5669, 3865, 2249, 5002, 166, 4694, 5461, 635 | 4753, 166, 3157, 166, 1960, 166, 166, 166, 2440, 166, 5818, 5534, 2439, 1717, 166, 3789, 636 | 2959, 166, 2943, 166, 2576, 166, 2002, 2007, 1819, 3256, 4402, 5311, 3832, 160, 166, 166, 637 | 2803, 166, 3264, 166, 5863, 166, 2017, 166, 2798, 166, 166, 166, 166, 5607, 4965, 166, 638 | 166, 166, 4537, 4378, 5944, 3494, 5457, 5602, 1942, 5900, 5780, 4411, 5147, 166, 4966, 2115, 639 | 155, 2827, 1980, 5063, 166, 285, 5912, 3304, 2963, 5179, 3220, 166, 166, 166, 2190, 3708, 640 | 5476, 1944, 2366, 3893, 166, 166, 166, 3759, 166, 5434, 2740, 1707, 4244, 5426, 166, 166, 641 | 166, 3155, 166, 4285, 166, 166, 166, 166, 5721, 166, 3833, 6001, 301, 166, 166, 2574, 642 | 186, 2724, 166, 1873, 3667, 166, 5216, 166, 2935, 2100, 4987, 166, 2284, 166, 166, 2911, 643 | 3828, 4009, 166, 2065, 166, 5496, 6130, 5563, 4387, 166, 3771, 3469, 2989, 2222, 4577, 3965, 644 | 4296, 2975, 3813, 3240, 166, 4780, 4481, 3387, 2338, 166, 6183, 166, 166, 166, 166, 166, 645 | 2675, 1761, 2600, 5167, 3170, 4773, 2165, 5166, 166, 2223, 4642, 166, 166, 4540, 166, 166, 646 | 166, 3897, 166, 2483, 1809, 5477, 3844, 4067, 2508, 2275, 166, 166, 166, 166, 166, 3497, 647 | 5458, 166, 249, 2956, 166, 4651, 166, 283, 166, 166, 4955, 4062, 2315, 2304, 3261, 2361, 648 | 4791, 4389, 1997, 166, 3455, 166, 166, 166, 166, 166, 166, 4746, 5695, 5296, 105, 1841, 649 | 3368, 166, 166, 166, 5228, 166, 3496, 4423, 2024, 3907, 4774, 166, 166, 166, 166, 166, 650 | 2294, 2193, 166, 166, 166, 166, 166, 166, 166, 166, 4393, 166, 166, 2127, 166, 4573, 651 | 166, 5350, 166, 5016, 3372, 166, 5653, 166, 5972, 4719, 166, 166, 166, 166, 166, 5370, 652 | 166, 6142, 166, 166, 3691, 2828, 166, 2601, 166, 2937, 2060, 3654, 3097, 2341, 5325, 4568, 653 | 4096, 2776, 166, 2946, 166, 166, 166, 5843, 1777, 5295, 2837, 4261, 4397, 5006, 5808, 4866, 654 | 166, 1713, 5732, 2954, 166, 166, 27, 166, 4308, 5629, 2652, 2434, 4474, 166, 4928, 166, 655 | 4727, 3811, 166, 166, 5234, 166, 6010, 166, 4911, 166, 4570, 166, 6000, 3450, 5304, 3919, 656 | 166, 166, 4008, 3942, 166, 272, 2363, 2064, 3595, 3505, 166, 166, 3957, 1695, 2452, 4659, 657 | 166, 1792, 166, 131, 5968, 166, 3731, 3905, 4115, 166, 166, 2468, 166, 2727, 166, 3526, 658 | 4724, 166, 4388, 3149, 5539, 5092, 4440, 6162, 166, 166, 193, 4429, 2493, 166, 166, 3683, 659 | 166, 6029, 166, 277, 166, 166, 166, 5240, 2408, 166, 309, 2561, 210, 166, 5200, 166, 660 | 166, 166, 1930, 5692, 2697, 166, 166, 166, 3330, 5331, 3860, 166, 166, 4335, 166, 50, 661 | 3605, 4289, 1763, 166, 166, 166, 166, 3521, 166, 166, 166, 3668, 166, 166, 166, 166, 662 | 166, 3271, 1656, 166, 166, 4782, 166, 2962, 166, 5907, 166, 3245, 3375, 2944, 5933, 166, 663 | 166, 5406, 5655, 3139, 5423, 166, 4359, 5231, 2548, 166, 3831, 2858, 5488, 166, 5824, 166, 664 | 166, 166, 3885, 4372, 166, 166, 4024, 166, 4811, 2970, 166, 4219, 211, 166, 3471, 166, 665 | 166, 166, 166, 3854, 166, 3358, 2877, 166, 166, 5205, 2804, 166, 166, 166, 4452, 166, 666 | 166, 166, 166, 3776, 166, 166, 3075, 4208, 166, 5623, 1974, 166, 2647, 166, 3235, 166, 667 | 166, 166, 5211, 166, 166, 4304, 2206, 166, 4157, 2182, 166, 1816, 2626, 166, 2893, 2248, 668 | 166, 166, 166, 166, 1983, 5648, 166, 194, 166, 2106, 4328, 166, 4742, 166, 166, 5572, 669 | 2329, 3314, 166, 6181, 166, 166, 26, 166, 6026, 166, 166, 2114, 1669, 4735, 166, 166, 670 | 4256, 166, 1861, 166, 5470, 2317, 166, 4404, 2482, 166, 5305, 4415, 5986, 4949, 5412, 166, 671 | 1728, 166, 1898, 166, 166, 4909, 1989, 166, 166, 166, 2836, 2051, 274, 166, 2799, 166, 672 | 5865, 1663, 4705, 5121, 2555, 166, 4316, 4287, 1880, 1825, 166, 3689, 166, 1733, 5012, 166, 673 | 166, 2237, 4471, 1682, 2910, 166, 5366, 166, 166, 166, 166, 4532, 166, 2802, 166, 166, 674 | 166, 4057, 2471, 166, 2889, 166, 166, 4026, 5682, 3091, 166, 1977, 166, 2901, 6137, 5658, 675 | 88, 2318, 1965, 166, 5914, 166, 166, 4468, 1822, 166, 6050, 5956, 2201, 166, 4644, 2918, 676 | 166, 3703, 166, 166, 3524, 4220, 2913, 4210, 166, 166, 2090, 166, 1906, 1911, 166, 166, 677 | 3671, 2370, 166, 2552, 166, 3763, 2259, 1924, 166, 5940, 166, 166, 166, 3185, 3821, 4069, 678 | 261, 2381, 3244, 166, 166, 5715, 166, 2052, 5905, 166, 2403, 166, 3030, 2199, 166, 3550, 679 | 166, 166, 1846, 166, 166, 95, 166, 289, 3208, 2559, 5195, 5091, 1654, 166, 1781, 1892, 680 | 166, 4516, 2629, 166, 1700, 3067, 166, 166, 166, 2080, 1680, 166, 166, 166, 5700, 166, 681 | 1820, 5491, 166, 4226, 166, 166, 166, 166, 4653, 166, 3508, 227, 5364, 166, 2098, 166, 682 | 299, 166, 5795, 166, 166, 166, 166, 3690, 4134, 5517, 4534, 5042, 4874, 5798, 4234, 166, 683 | 166, 166, 166, 3702, 166, 166, 3638, 3108, 3850, 166, 166, 166, 16, 166, 1775, 166, 684 | 4022, 166, 223, 4095, 166, 5127, 4266, 166, 189, 166, 166, 5203, 166, 1805, 3884, 3778, 685 | 166, 166, 2146, 4818, 166, 2848, 3440, 4506, 5886, 3006, 218, 166, 2377, 166, 4091, 5925, 686 | 166, 4320, 166, 2701, 3036, 166, 166, 166, 4715, 166, 3801, 166, 3161, 166, 2077, 166, 687 | 4254, 3032, 243, 1814, 166, 166, 166, 166, 166, 166, 166, 166, 1835, 166, 4394, 166, 688 | 5769, 4923, 166, 2917, 166, 166, 178, 166, 166, 1723, 166, 5887, 166, 4956, 2952, 166, 689 | 4665, 3925, 3443, 3123, 166, 166, 166, 166, 166, 166, 5144, 166, 4288, 2074, 2192, 5442, 690 | 6043, 1746, 2016, 5995, 2203, 166, 5686, 5659, 3193, 166, 4055, 166, 166, 2233, 3571, 5809, 691 | 5984, 2323, 166, 166, 1740, 89, 4356, 6053, 6106, 3282, 4796, 166, 6116, 6056, 2353, 2829, 692 | 166, 5807, 2042, 166, 166, 166, 1670, 5937, 4465, 5646, 166, 5562, 3008, 166, 2419, 3736, 693 | 166, 4132, 169, 166, 166, 166, 2402, 166, 166, 1968, 2398, 166, 1684, 1827, 4551, 2679, 694 | 3875, 166, 5585, 3835, 2295, 166, 1991, 1803, 2992, 166, 166, 5847, 2649, 166, 76, 5415, 695 | 166, 2269, 2397, 5387, 5337, 4422, 166, 2672, 4832, 4617, 166, 166, 166, 166, 4552, 166, 696 | 4612, 1750, 166, 1931, 166, 1691, 2424, 4194, 6018, 166, 166, 4458, 4856, 166, 2089, 3814, 697 | 166, 2844, 166, 3592, 166, 4867, 5128, 166, 2685, 166, 166, 2616, 1972, 2617, 3943, 4664, 698 | 166, 4999, 166, 166, 145, 3635, 166, 166, 4851, 166, 3483, 5039, 166, 3649, 3924, 166, 699 | 166, 166, 3105, 4260, 166, 6098, 166, 3568, 267, 2456, 3653, 2096, 166, 166, 166, 3512, 700 | 166, 3405, 166, 3504, 166, 166, 166, 4005, 2144, 1769, 166, 5474, 1920, 5554, 215, 2443, 701 | 3351, 166, 5961, 166, 166, 166, 166, 242, 2331, 166, 166, 5931, 166, 166, 5862, 166, 702 | 1710, 166, 166, 166, 3321, 166, 4139, 166, 166, 3515, 2732, 2510, 5544, 166, 166, 2783, 703 | 166, 166, 166, 4018, 4649, 5789, 166, 166, 166, 166, 166, 2726, 6074, 166, 166, 166, 704 | 5684, 166, 166, 3395, 166, 3100, 166, 5763, 3757, 1992, 166, 3198, 2003, 166, 166, 4675, 705 | 166, 1893, 5621, 166, 2270, 166, 166, 166, 5421, 5590, 5664, 4045, 166, 3687, 4406, 2699, 706 | 1811, 167, 4036, 5384, 166, 166, 4601, 1823, 4041, 239, 1954, 166, 146, 166, 166, 3077, 707 | 5152, 5814, 1649, 5681, 166, 5868, 166, 166, 3792, 4860, 166, 5335, 5110, 1718, 166, 166, 708 | 166, 166, 3718, 3365, 2826, 166, 166, 5021, 4783, 166, 5569, 5812, 166, 166, 1876, 166, 709 | 3260, 166, 1789, 5667, 4224, 166, 166, 4385, 166, 166, 2620, 166, 4162, 2883, 2143, 5497, 710 | 166, 166, 5316, 5680, 166, 166, 248, 4050, 166, 6021, 166, 2898, 4618, 166, 166, 166, 711 | 166, 166, 5368, 166, 5378, 1842, 1914, 3696, 3962, 166, 4345, 2581, 1773, 2109, 166, 4371, 712 | 166, 166, 3761, 5277, 5870, 3146, 166, 166, 166, 5764, 127, 3058, 4059, 4718, 166, 5097, 713 | 5040, 5351, 3205, 166, 166, 4996, 2991, 2014, 166, 5846, 2558, 2688, 5595, 4027, 3347, 2125, 714 | 5696, 5608, 166, 166, 3228, 3745, 5775, 166, 1757, 4647, 166, 5977, 3020, 166, 240, 2565, 715 | 166, 4459, 166, 3367, 166, 166, 166, 3104, 166, 166, 166, 166, 166, 166, 259, 5486, 716 | 2846, 166, 166, 166, 4778, 2713, 166, 3955, 5683, 2682, 2914, 5898, 166, 166, 166, 4400, 717 | 317, 166, 5185, 3021, 5983, 4332, 3891, 166, 3095, 5003, 166, 166, 166, 5367, 166, 279, 718 | 1784, 4019, 2736, 4905, 2651, 5346, 166, 4841, 166, 5606, 166, 166, 2806, 166, 5239, 166, 719 | 166, 3237, 5490, 166, 225, 166, 166, 2254, 166, 2742, 4587, 22, 166, 166, 166, 5555, 720 | 166, 108, 2927, 2218, 166, 2120, 166, 5452, 4087, 4369, 166, 166, 166, 166, 166, 4583, 721 | 4338, 6035, 2840, 4365, 3624, 11, 1770, 166, 4630, 166, 3216, 166, 166, 166, 4638, 4699, 722 | 3535, 2536, 4627, 166, 166, 5760, 1935, 166, 166, 5210, 166, 2219, 2484, 4597, 5193, 4799, 723 | 3706, 166, 166, 166, 166, 3337, 3113, 5951, 4294, 166, 4040, 3200, 4217, 5861, 2767, 3530, 724 | 4499, 2775, 4121, 134, 5939, 5880, 5908, 3869, 166, 166, 3316, 6095, 2441, 3288, 166, 3751, 725 | 4794, 166, 166, 5803, 6169, 2356, 6182, 6135, 6127, 166, 3018, 166, 1674, 166, 166, 4097, 726 | 166, 5923, 287, 5965, 5129, 166, 4078, 166, 166, 6114, 6015, 5990, 3573, 166, 4146, 2681, 727 | 90, 6055, 4864, 166, 166, 6119, 3284, 6054, 5456, 5113, 6125, 166, 6057, 166, 3292, 166, 728 | 166, 166, 166, 166, 6185, 5105, 1760, 166, 166, 166, 2720, 166, 2695, 5448, 166, 1936, 729 | 166, 1807, 3406, 166, 166, 2161, 1642, 166, 5030, 166, 2036, 5451, 3427, 166, 166, 166, 730 | 166, 3797, 166, 1627, 166, 4515, 166, 166, 166, 4241, 166, 166, 166, 2771, 166, 31, 731 | 5197, 2638, 3035, 166, 166, 3914, 166, 166, 4546, 166, 166, 166, 4253, 3500, 166, 166, 732 | 2526, 166, 2698, 166, 3726, 2744, 137, 166, 166, 2676, 166, 5594, 166, 166, 166, 4842, 733 | 166, 63, 2888, 3585, 4798, 166, 5011, 166, 5634, 5464, 166, 166, 5620, 3894, 4070, 166, 734 | 2730, 166, 166, 1810, 2503, 5957, 1721, 6066, 5188, 166, 166, 1890, 4505, 1771, 5455, 166, 735 | 3132, 3984, 166, 166, 2811, 1962, 166, 166, 4872, 106, 3898, 3267, 166, 2085, 166, 4950, 736 | 6040, 4525, 6044, 5866, 3613, 2907, 4615, 2135, 258, 166, 1681, 1941, 4888, 166, 4859, 6178, 737 | 6174, 4858, 5209, 1912, 3340, 166, 4640, 5706, 166, 2763, 3153, 3951, 166, 5542, 5596, 5819, 738 | 5330, 5048, 4037, 166, 6033, 4625, 3326, 2013, 5283, 136, 3373, 2154, 166, 166, 166, 4421, 739 | 166, 5438, 2627, 2266, 2320, 166, 2588, 4790, 4290, 166, 4767, 5829, 2925, 5916, 2133, 166 740 | }; 741 | 742 | 743 | 744 | 745 | short eval_5hand( int *hand ) 746 | { 747 | int c1, c2, c3, c4, c5; 748 | 749 | c1 = *hand++; 750 | c2 = *hand++; 751 | c3 = *hand++; 752 | c4 = *hand++; 753 | c5 = *hand; 754 | 755 | return( eval_5hand_fast(c1,c2,c3,c4,c5) ); 756 | } 757 | 758 | 759 | // This is a non-optimized method of determining the 760 | // best five-card hand possible out of seven cards. 761 | // I am working on a faster algorithm. 762 | // 763 | short 764 | eval_7hand( int *hand ) 765 | { 766 | int i, j, q, best = 9999, subhand[5]; 767 | 768 | for ( i = 0; i < 21; i++ ) 769 | { 770 | for ( j = 0; j < 5; j++ ) 771 | subhand[j] = hand[ perm7[i][j] ]; 772 | q = eval_5hand( subhand ); 773 | if ( q < best ) 774 | best = q; 775 | } 776 | return( best ); 777 | } 778 | 779 | -------------------------------------------------------------------------------- /rankhand.out.txt: -------------------------------------------------------------------------------- 1 | 2 | card:r2 sC 1 > 2c 3 | card:r2 sD 2 > 2d 4 | card:r2 sH 3 > 2h 5 | card:r2 sS 4 > 2s 6 | card:r3 sC 5 > 3c 7 | card:r3 sD 6 > 3d 8 | card:r3 sH 7 > 3h 9 | card:r3 sS 8 > 3s 10 | card:r4 sC 9 > 4c 11 | card:r4 sD 10 > 4d 12 | card:r4 sH 11 > 4h 13 | card:r4 sS 12 > 4s 14 | card:r5 sC 13 > 5c 15 | card:r5 sD 14 > 5d 16 | card:r5 sH 15 > 5h 17 | card:r5 sS 16 > 5s 18 | card:r6 sC 17 > 6c 19 | card:r6 sD 18 > 6d 20 | card:r6 sH 19 > 6h 21 | card:r6 sS 20 > 6s 22 | card:r7 sC 21 > 7c 23 | card:r7 sD 22 > 7d 24 | card:r7 sH 23 > 7h 25 | card:r7 sS 24 > 7s 26 | card:r8 sC 25 > 8c 27 | card:r8 sD 26 > 8d 28 | card:r8 sH 27 > 8h 29 | card:r8 sS 28 > 8s 30 | card:r9 sC 29 > 9c 31 | card:r9 sD 30 > 9d 32 | card:r9 sH 31 > 9h 33 | card:r9 sS 32 > 9s 34 | card:rT sC 33 > Tc 35 | card:rT sD 34 > Td 36 | card:rT sH 35 > Th 37 | card:rT sS 36 > Ts 38 | card:rJ sC 37 > Jc 39 | card:rJ sD 38 > Jd 40 | card:rJ sH 39 > Jh 41 | card:rJ sS 40 > Js 42 | card:rQ sC 41 > Qc 43 | card:rQ sD 42 > Qd 44 | card:rQ sH 43 > Qh 45 | card:rQ sS 44 > Qs 46 | card:rK sC 45 > Kc 47 | card:rK sD 46 > Kd 48 | card:rK sH 47 > Kh 49 | card:rK sS 48 > Ks 50 | card:rA sC 49 > Ac 51 | card:rA sD 50 > Ad 52 | card:rA sH 51 > Ah 53 | card:rA sS 52 > As 54 | got here 55 | 1: 2c db[ 53 + 1 ] -> 106 56 | 2: 2d db[ 106 + 2 ] -> 2862 57 | 3: 2h db[ 2862 + 3 ] -> 73140 58 | 4: 2s db[ 73140 + 4 ] -> 1244440 59 | 5: 3c db[ 1244440 + 5 ] -> 5720184 (eqQuads) 60 | 6: 3d db[ 5720184 + 6 ] -> 13808355 (eqQuads) 61 | 7: 3h db[ 13808355 + 7 ] -> 32769 (eqQuads) 62 | 63 | 2c 2d 2h 2s 3c 3d 3h | eq: eqQuads #1 64 | 65 | 66 | 1: 2c db[ 53 + 1 ] -> 106 67 | 2: 3c db[ 106 + 5 ] -> 3021 68 | 3: 4c db[ 3021 + 9 ] -> 81090 69 | 4: 5c db[ 81090 + 13 ] -> 1581149 70 | 5: 6c db[ 1581149 + 17 ] -> 6820464 (eqStraightFlush) 71 | 6: 7c db[ 6820464 + 21 ] -> 16594035 (eqStraightFlush) 72 | 7: 8c db[ 16594035 + 25 ] -> 36868 (eqStraightFlush) 73 | 74 | 2c 3c 4c 5c 6c 7c 8c | eq: eqStraightFlush #4 75 | 76 | 1: 4c db[ 53 + 9 ] -> 530 77 | 2: 8c db[ 530 + 25 ] -> 23797 78 | 3: Ac db[ 23797 + 49 ] -> 571552 79 | 4: 3d db[ 571552 + 6 ] -> 2582160 80 | 5: Qd db[ 2582160 + 42 ] -> 8815490 (eqHighCard) 81 | 6: 2h db[ 8815490 + 3 ] -> 14786523 (eqHighCard) 82 | 7: 5h db[ 14786523 + 15 ] -> 20481 (eqStraight) 83 | 84 | 4c 8c Ac 3d Qd 2h 5h | eq: eqStraight #1 85 | 86 | 1: Ts db[ 53 + 36 ] -> 1961 87 | 2: Js db[ 1961 + 40 ] -> 66091 88 | 3: As db[ 66091 + 52 ] -> 1211209 89 | 4: Qs db[ 1211209 + 44 ] -> 5687006 90 | 5: Ks db[ 5687006 + 48 ] -> 13794575 (eqStraightFlush) 91 | 92 | TsJs AsQs Ks | eq: eqStraightFlush #10 93 | 94 | 1: As db[ 53 + 52 ] -> 2809 95 | 2: Ac db[ 2809 + 49 ] -> 72928 96 | 3: Ad db[ 72928 + 50 ] -> 1244281 97 | 4: Ah db[ 1244281 + 51 ] -> 5720131 98 | 5: 2s db[ 5720131 + 4 ] -> 6756334 (eqQuads) 99 | 6: 2h db[ 6756334 + 3 ] -> 14055653 (eqQuads) 100 | 7: Jc db[ 14055653 + 37 ] -> 32922 (eqQuads) 101 | 102 | AsAc AdAh 2s2h Jc | eq: eqQuads #154 103 | 104 | 1: 7s db[ 53 + 24 ] -> 1325 105 | 2: 5d db[ 1325 + 14 ] -> 34344 106 | 3: 4s db[ 34344 + 12 ] -> 682004 107 | 4: 3h db[ 682004 + 7 ] -> 2600392 108 | 5: 2d db[ 2600392 + 2 ] -> 6035905 (eqHighCard) 109 | 6: 2c db[ 6035905 + 1 ] -> 13883244 (eqPair) 110 | 7: 2s db[ 13883244 + 4 ] -> 16393 (eqTrips) 111 | 112 | 7s5d 4s3h 2d2c 2s | eq: eqTrips #9 113 | 114 | 115 | -------------------------------------------------------------------------------- /rankhand.pas: -------------------------------------------------------------------------------- 1 | // 2 | // object pascal program showing how to decode hand rankings 3 | // using the HandRanks.dat file generated by generate_table.cpp. 4 | // 5 | // compile with http://freepascal.org/ (and possibly delphi) 6 | // 7 | // --------------------------------------------------------------- 8 | // 9 | // (c)2014 michal j wallace 10 | // 11 | // This software is provided 'as-is', without any express or implied 12 | // warranty. In no event will the authors be held liable for any damages 13 | // arising from the use of this software. 14 | // 15 | // Permission is granted to anyone to use this software for any 16 | // purpose, including commercial applications, and to alter it and 17 | // redistribute it freely, subject to the following restrictions: 18 | // 19 | // 20 | // - The origin of this software must not be misrepresented; you must 21 | // not claim that you wrote the original software. If you use this 22 | // software in a product, an acknowledgment in the product documentation 23 | // would be appreciated but is not required. 24 | // 25 | // - Altered source versions must be plainly marked as such, and must 26 | // not be misrepresented as being the original software. 27 | // 28 | // - This notice may not be removed or altered from any source 29 | // distribution. 30 | 31 | {$mode delphi} 32 | program rankhand; 33 | uses sysutils; 34 | 35 | type 36 | THandVal = UInt32; 37 | THandDb = array[0..32487833] of THandVal; 38 | TRank = (r2,r3,r4,r5,r6,r7,r8,r9,rT,rJ,rQ,rK,rA); 39 | TSuit = (sC,sD,sH,sS); 40 | TCardNum = 0..53; 41 | TDeck = array[TCardNum] of UInt32; 42 | TCardCode = UInt32; 43 | TCodes = array of TCardCode; 44 | TCardNums = array of TCardNum; 45 | TEqClass = (eqUnknown{0}, eqHighCard{1}, eqPair{2}, eqTwoPair{3}, 46 | eqTrips{4}, eqStraight{5}, eqFlush{6}, eqFullHouse{7}, 47 | eqQuads{8}, eqStraightFlush{9}); 48 | 49 | const 50 | kPrimes : array[TRank] of UInt32 = (2,3,5,7,11,13,17,19,23,29,31,37,41); 51 | kSuitBit : array[TSuit] of UInt32 = ($8000,$4000,$2000,$1000); 52 | kRank : array[TRank] of char = ('2','3','4','5','6','7', 53 | '8','9','T','J','Q','K','A'); 54 | kSuit : array[TSuit] of char = ('c','d','h','s'); 55 | 56 | var 57 | gDeck : TDeck; 58 | 59 | 60 | function cnum2rank(c:TCardNum):TRank; 61 | begin result := TRank((c-1) div 4) 62 | end; 63 | 64 | function cnum2suit(c:TCardNum):TSuit; 65 | begin result := TSuit((c-1) mod 4) 66 | end; 67 | 68 | function cnum2str(c:TCardNum):string; 69 | begin result := kRank[cnum2rank(c)] + kSuit[cnum2suit(c)] 70 | end; 71 | 72 | function code2rank(c:TCardCode):TRank; 73 | begin result := TRank($0000f and (c shr 8)-1) 74 | end; 75 | 76 | function code2suit(c:TCardCode):TSuit; 77 | begin 78 | for result in TSuit do 79 | if (c and kSuitBit[result])<>0 then exit; 80 | end; 81 | 82 | function code2str(c:TCardCode):string; 83 | begin result := kRank[code2rank(c)] + kSuit[code2suit(c)] 84 | end; 85 | 86 | function codes2str(codes:TCodes):string; 87 | var c:TCardCode; 88 | begin 89 | result := ''; for c in codes do result += code2str(c); 90 | end; 91 | 92 | 93 | 94 | function rs2code(r:TRank; s:TSuit): TCardCode; 95 | var ri : UInt32; 96 | begin 97 | ri := UInt32(ord(r))+1; 98 | result := kPrimes[r] or (ri shl 8) or 99 | kSuitBit[s] or (1 shl (16+ri)); 100 | end; 101 | 102 | 103 | procedure init_deck(var deck : TDeck); 104 | var n:UInt32=1; s:TSuit; r:TRank; 105 | begin 106 | for r in TRank do for s in TSuit do begin 107 | deck[n] := rs2code(r,s); 108 | //writeln(': ', n:2, ' = "', cnum2str(n), '" : ', 109 | // deck[n]:8, ' = "', code2str(deck[n]),'"'); 110 | inc(n); 111 | end; 112 | end; 113 | 114 | function rs2CNum(deck:TDeck; rank:TRank; suit:TSuit):TCardNum; 115 | var i : UInt32; c:TCardCode; 116 | begin 117 | i := 1; result := 0; c := rs2code(rank,suit); 118 | while (i <= high(deck)) and (result = 0) do begin 119 | if deck[i] = c then result := i; 120 | inc(i); 121 | end; 122 | end; 123 | 124 | 125 | function strToCardNums(hand:string):TCardNums; 126 | var ch : char; rank:TRank=r2; 127 | procedure emit(suit : TSuit); 128 | begin 129 | SetLength(result, length(result)+1); 130 | result[length(result)-1] := rs2CNum(gDeck,rank,suit); 131 | end; 132 | begin 133 | for ch in hand do 134 | case ch of 135 | 'A' : rank := rA; 'K': rank := rK; 'Q': rank := rQ; 'J': rank := rJ; 136 | 'T' : rank := rT; '9': rank := r9; '8': rank := r8; '7': rank := r7; 137 | '6' : rank := r6; '5': rank := r5; '4': rank := r4; '3': rank := r3; 138 | '2' : rank := r2; ' ':; 139 | 'c' : emit(sC); 'd': emit(sD); 'h': emit(sH); 's': emit(sS); 140 | end; 141 | end; 142 | 143 | 144 | 145 | function eqClass(v:THandVal):TEqClass; 146 | begin result := TEqClass($0F and byte(v shr 12)); 147 | end; 148 | 149 | function evalCardNumHand(var db:THandDb; cnums:TCardNums):THandVal; 150 | var cnum : TCardNum; i:byte=0; 151 | begin 152 | result := 53; 153 | for cnum in cnums do begin 154 | inc(i); 155 | write(i:5,': ',cnum2str(cnum), 156 | ' db[', result:9, ' + ', cnum:3, ' ] -> '); 157 | result := db[result + cnum]; 158 | write(result:9); 159 | if i = 7 then write(' (', eqClass(result), ')') 160 | else if i >= 5 then write(' (', eqClass(db[result]), ')'); 161 | writeln; 162 | end; 163 | if length(cnums) in [5,6] then result := db[result]; 164 | end; 165 | 166 | function evalHand(var db:THandDb; hand:string):THandVal; 167 | begin result := evalCardNumHand(db, strToCardNums(hand)) 168 | end; 169 | 170 | 171 | procedure writeRank(var db:THandDb; hand:string); 172 | var val : THandVal; 173 | begin 174 | val := evalHand(db, hand); 175 | writeln; 176 | writeln(hand : 22, ' | eq: ', eqClass(val), ' #', (val and $0fff)); 177 | writeln; 178 | end; 179 | 180 | 181 | var 182 | db : THandDb; 183 | dbFile : file of UInt32; 184 | nRead : UInt32; 185 | rank : Trank; suit:TSuit; 186 | cnum : TCardNum; 187 | begin 188 | init_deck(gDeck); 189 | Assign(dbFile, 'HandRanks.dat'); Reset(dbFile); 190 | BlockRead(dbFile, db, sizeof(db) div 4, nRead); 191 | writeln; 192 | for rank in Trank do for suit in TSuit do begin 193 | cnum := rs2CNum(gDeck,rank,suit); 194 | write('card:', rank,' ',suit,' ', cnum:3,' > '); 195 | writeln(cnum2str(cnum)); 196 | end; 197 | writeln('got here'); 198 | writeRank(db, '2c 2d 2h 2s 3c 3d 3h'); 199 | writeln; 200 | assert(evalHand(db, '2c 2d 2h 2s 3c 3d 3h') = 32769); 201 | writeRank(db, '2c 3c 4c 5c 6c 7c 8c'); 202 | writeRank(db, '4c 8c Ac 3d Qd 2h 5h'); 203 | writeRank(db, 'TsJs AsQs Ks'); 204 | writeRank(db, 'AsAc AdAh 2s2h Jc'); 205 | writeRank(db, '7s5d 4s3h 2d2c 2s'); 206 | writeln; 207 | Close(dbFile); 208 | end. 209 | -------------------------------------------------------------------------------- /test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define DWORD int32_t 5 | 6 | // The handranks lookup table- loaded from HANDRANKS.DAT. 7 | int HR[32487834]; 8 | 9 | // This function isn't currently used, but shows how you lookup 10 | // a 7-card poker hand. pCards should be a pointer to an array 11 | // of 7 integers each with value between 1 and 52 inclusive. 12 | int LookupHand(int* pCards) 13 | { 14 | int p = HR[53 + *pCards++]; 15 | p = HR[p + *pCards++]; 16 | p = HR[p + *pCards++]; 17 | p = HR[p + *pCards++]; 18 | p = HR[p + *pCards++]; 19 | p = HR[p + *pCards++]; 20 | return HR[p + *pCards++]; 21 | } 22 | 23 | void LookupSingleHands() 24 | { 25 | printf("Looking up individual hands...\n\n"); 26 | 27 | // Create a 7-card poker hand (each card gets a value between 1 and 52) 28 | int cards[] = { 2, 6, 12, 14, 23, 26, 29 }; 29 | int retVal = LookupHand(cards); 30 | printf("Category: %d\n", retVal >> 12); 31 | printf("Salt: %d\n", retVal & 0x00000FFF); 32 | } 33 | 34 | 35 | void EnumerateAll7CardHands() 36 | { 37 | // Now let's enumerate every possible 7-card poker hand 38 | int u0, u1, u2, u3, u4, u5; 39 | int c0, c1, c2, c3, c4, c5, c6; 40 | int handTypeSum[10]; // Frequency of hand category (flush, 2 pair, etc) 41 | int count = 0; // total number of hands enumerated 42 | memset(handTypeSum, 0, sizeof(handTypeSum)); // do init.. 43 | 44 | printf("Enumerating and evaluating all 133,784,560 possible 7-card poker hands...\n\n"); 45 | 46 | // On your mark, get set, go... 47 | //DWORD dwTime = GetTickCount(); 48 | 49 | for (c0 = 1; c0 < 47; c0++) { 50 | u0 = HR[53+c0]; 51 | for (c1 = c0+1; c1 < 48; c1++) { 52 | u1 = HR[u0+c1]; 53 | for (c2 = c1+1; c2 < 49; c2++) { 54 | u2 = HR[u1+c2]; 55 | for (c3 = c2+1; c3 < 50; c3++) { 56 | u3 = HR[u2+c3]; 57 | for (c4 = c3+1; c4 < 51; c4++) { 58 | u4 = HR[u3+c4]; 59 | for (c5 = c4+1; c5 < 52; c5++) { 60 | u5 = HR[u4+c5]; 61 | for (c6 = c5+1; c6 < 53; c6++) { 62 | 63 | handTypeSum[HR[u5+c6] >> 12]++; 64 | 65 | // JMD: The above line of code is equivalent to: 66 | //int finalValue = HR[u5+c6]; 67 | //int handCategory = finalValue >> 12; 68 | //handTypeSum[handCategory]++; 69 | 70 | count++; 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | //dwTime = GetTickCount() - dwTime; 80 | 81 | printf("BAD: %d\n", handTypeSum[0]); 82 | printf("High Card: %d\n", handTypeSum[1]); 83 | printf("One Pair: %d\n", handTypeSum[2]); 84 | printf("Two Pair: %d\n", handTypeSum[3]); 85 | printf("Trips: %d\n", handTypeSum[4]); 86 | printf("Straight: %d\n", handTypeSum[5]); 87 | printf("Flush: %d\n", handTypeSum[6]); 88 | printf("Full House: %d\n", handTypeSum[7]); 89 | printf("Quads: %d\n", handTypeSum[8]); 90 | printf("Straight Flush: %d\n", handTypeSum[9]); 91 | 92 | // Perform sanity checks.. make sure numbers are where they should be 93 | int testCount = 0; 94 | for (int index = 0; index < 10; index++) 95 | testCount += handTypeSum[index]; 96 | if (testCount != count || count != 133784560 || handTypeSum[0] != 0) 97 | { 98 | printf("\nERROR!\nERROR!\nERROR!"); 99 | return; 100 | } 101 | 102 | printf("\nEnumerated %d hands.\n", count); 103 | } 104 | 105 | 106 | int main(int argc, char* argv[]) { 107 | 108 | printf("Testing the Two Plus Two 7-Card Evaluator\n"); 109 | printf("-----------------------------------------\n\n"); 110 | 111 | // Load the HandRanks.DAT file and map it into the HR array 112 | printf("Loading HandRanks.DAT file..."); 113 | memset(HR, 0, sizeof(HR)); 114 | FILE * fin = fopen("HandRanks.dat", "rb"); 115 | if (!fin) 116 | return false; 117 | size_t bytesread = fread(HR, sizeof(HR), 1, fin); // get the HandRank Array 118 | fclose(fin); 119 | printf("complete.\n\n"); 120 | 121 | // Enumerate all 133,784,560 possible 7-card poker hands... 122 | EnumerateAll7CardHands(); 123 | LookupSingleHands(); 124 | 125 | return 0; 126 | } 127 | 128 | --------------------------------------------------------------------------------