Skip to content

Commit 68ff97e

Browse files
author
Eduardo
committed
Extends Floyd algorithm for preselected subsets
1 parent 54e227f commit 68ff97e

File tree

3 files changed

+61
-144
lines changed

3 files changed

+61
-144
lines changed

inc/ep/Floyd.h

+12
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,16 @@ inline uint64_t floydSample(Rng &&g) {
2222
return rv;
2323
}
2424

25+
inline uint64_t deposit(uint64_t preselected, uint64_t extra) {
26+
auto depositSelector = ~preselected;
27+
auto deposited = __builtin_ia32_pdep_di(extra, depositSelector);
28+
return preselected | deposited;
29+
}
30+
31+
template<int N, int K, typename Rng>
32+
inline uint64_t floydSample(Rng &&g, uint64_t preselected) {
33+
auto normal = floydSample<N, K>(std::forward<Rng>(g));
34+
return deposit(preselected, normal);
35+
}
36+
2537
}

src/benchmarks.cpp

+36-31
Original file line numberDiff line numberDiff line change
@@ -273,45 +273,50 @@ benchmarks
273273
auto base = driver(gen, count, empty);
274274
indicators(base, base);
275275
std::cout.flush();
276-
auto v1 = driver(gen, count, v1fun);
277-
std::cout << " |1 ";
278-
indicators(v1, base);
279-
std::cout.flush();
280-
operation = [](uint64_t c) { return colorBlindRank(c); };
281-
auto v2 = driver(gen, count, v1fun);
282-
std::cout << " |cb ";
283-
indicators(v2, base);
284-
std::cout.flush();
285-
operation = [](uint64_t c) -> int { return flush(c); };
286-
auto v3 = driver(gen, count, v1fun);
287-
std::cout << " |f ";
288-
indicators(v3, base);
289-
std::cout.flush();
290-
operation = [](uint64_t c) -> int { return whole(c); };
291-
auto v4 = driver(gen, count, v1fun);
292-
std::cout << " |w ";
293-
indicators(v4, base);
294-
std::cout.flush();
276+
277+
if(1 == argc) {
278+
auto v1 = driver(gen, count, v1fun);
279+
std::cout << " |1 ";
280+
indicators(v1, base);
281+
std::cout.flush();
282+
operation = [](uint64_t c) { return colorBlindRank(c); };
283+
auto v2 = driver(gen, count, v1fun);
284+
std::cout << " |cb ";
285+
indicators(v2, base);
286+
std::cout.flush();
287+
operation = [](uint64_t c) -> int { return flush(c); };
288+
auto v3 = driver(gen, count, v1fun);
289+
std::cout << " |f ";
290+
indicators(v3, base);
291+
std::cout.flush();
292+
operation = [](uint64_t c) -> int { return whole(c); };
293+
auto v4 = driver(gen, count, v1fun);
294+
std::cout << " |w ";
295+
indicators(v4, base);
296+
std::cout.flush();
297+
}
295298

296299
operation = [](uint64_t c) -> int {
297-
ep::SWARRank ranks(c); ep::SWARSuit ss = ep::convert(ranks);
298-
ep::CSet cs = { ss, ranks };
299-
return ep::handRank(cs).code;
300+
//ep::SWARRank ranks(c); ep::SWARSuit ss = ep::convert(ranks);
301+
//ep::CSet cs = { ss, ranks };
302+
return ep::handRank(c).code;
300303
};
301304
auto v5 = driver(gen, count, v1fun);
302305
std::cout << " |h ";
303306
indicators(v5, base);
304307
std::cout.flush();
305308

306-
operation = [](uint64_t c) -> int {
307-
/*ep::SWARRank ranks(c); ep::SWARSuit ss = ep::convert(ranks);
308-
ep::CSet cs = { ss, ranks };
309-
return ep::naive::handRank(cs);*/
310-
return wholeCheat(c);
311-
};
312-
auto v6 = driver(gen, count, v1fun);
313-
std::cout << " |c ";
314-
indicators(v6, base);
309+
if(1 == argc) {
310+
operation = [](uint64_t c) -> int {
311+
/*ep::SWARRank ranks(c); ep::SWARSuit ss = ep::convert(ranks);
312+
ep::CSet cs = { ss, ranks };
313+
return ep::naive::handRank(cs);*/
314+
return wholeCheat(c);
315+
};
316+
auto v6 = driver(gen, count, v1fun);
317+
std::cout << " |c ";
318+
indicators(v6, base);
319+
}
315320

316321
std::cout << ' ' << toakPlusPairs << ' ' << std::hex << sideEffect << ' ' <<
317322
xorCheck << std::endl;

src/main.cpp

+13-113
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "ep/Poker_io.h"
2-
#include "obsolete/Poker.h"
32
#include "ep/Poker.h"
3+
#include "ep/Floyd.h"
44

55
#ifdef TESTS
66
#define CATCH_CONFIG_MAIN
@@ -14,7 +14,18 @@ constexpr uint64_t royalFlush() {
1414
return hA | hK | hQ | hJ | hT;
1515
}
1616

17-
int whole(uint64_t);
17+
TEST_CASE("Bit operations", "[bit]") {
18+
auto sevenNibbles = ep::core::makeBitmask<4, uint64_t>(7);
19+
auto octals = 01234567ull;
20+
auto deposited = __builtin_ia32_pdep_di(octals, sevenNibbles);
21+
REQUIRE(0x1234567 == deposited);
22+
23+
auto alreadySet = 0xC63; // 1 1 0 0 .0 1 1 0 .0 0 1 1
24+
auto interleave = 0x2A; // 1a0b.1c0d1e0f
25+
auto expected = 0xEEB; // 1 1 1a0b.1c1 1 0d.1e0f1 1
26+
auto byEp = ep::deposit(alreadySet, interleave);
27+
REQUIRE(expected == byEp);
28+
}
1829

1930
TEST_CASE("Poker operations", "[basic]") {
2031
using namespace ep::abbreviations;
@@ -129,114 +140,3 @@ TEST_CASE("Hands", "[basic]") {
129140
REQUIRE(ep::HandRank(ep::HIGH_CARDS, 0, rK | rQ | rJ | rT | r8) == r);
130141
}
131142
}
132-
133-
TEST_CASE("Simple operations", "[basic]") {
134-
ep::SWARRank royal(royalFlush());
135-
SECTION("Fundamental") {
136-
using namespace ep::abbreviations;
137-
auto asSuits = ep::convert(royal);
138-
auto expected = 0x1Full << (16 + 8);
139-
REQUIRE(expected == asSuits.value());
140-
141-
auto others = h3 | royalFlush() | sK; // has six hearts, a pair of kings
142-
auto expected2 = expected | (1 << 17) | (1 << 11);
143-
ep::SWARRank ranks(others);
144-
auto sevenCards = ep::convert(ranks);
145-
REQUIRE(sevenCards.value() == expected2);
146-
147-
ep::CSet hand = { sevenCards, ranks };
148-
auto suitCounts = hand.suitCounts();
149-
auto suit6 = suitCounts.greaterEqual<6>();
150-
REQUIRE(suit6);
151-
bool hearts6 = sH == suit6.best();
152-
REQUIRE(int(sH) == suit6.best());
153-
154-
auto rankCounts = hand.rankCounts();
155-
auto rank2 = rankCounts.greaterEqual<2>();
156-
REQUIRE(rank2);
157-
REQUIRE(rK == rank2.best());
158-
auto swarSuits = ep::convert(ranks);
159-
auto bySuitBits = rA | rK | rQ | rJ | rT | r3;
160-
bySuitBits <<= 16;
161-
bySuitBits |= rK;
162-
REQUIRE(bySuitBits == swarSuits.value());
163-
}
164-
SECTION("Poker hands") {
165-
auto swarSuits = ep::convert(royal);
166-
auto ranks = swarSuits.at(ep::abbreviations::sH);
167-
auto straight = ep::straights(ranks);
168-
REQUIRE(straight);
169-
auto Ace = 1 << ep::abbreviations::rA;
170-
REQUIRE(Ace == straight);
171-
using namespace ep::abbreviations;
172-
auto from2 = rA | r2 | r3 | r4 | r5;
173-
REQUIRE((1 << r5) == ep::straights(from2));
174-
auto joint = from2 | ranks;
175-
auto AceOr5 = Ace | r5;
176-
REQUIRE(AceOr5 == ep::straights(joint));
177-
178-
ep::CSet cs = { swarSuits, royal };
179-
auto sf = ep::handRank(cs);
180-
REQUIRE(ep::STRAIGHT_FLUSH == sf.hand);
181-
REQUIRE(Ace == sf.high);
182-
cs.include(r3, sH);
183-
sf = ep::handRank(cs);
184-
REQUIRE(Ace == sf.high);
185-
REQUIRE(0 == sf.low);
186-
187-
auto foakBits = h3 | s3 | c3 | d3 | hT | d9 | s8;
188-
auto foakRanks = ep::SWARRank(foakBits);
189-
ep::CSet foakHand = { ep::convert(foakRanks), foakRanks };
190-
auto foakResult = handRank(foakHand);
191-
REQUIRE(ep::FOUR_OF_A_KIND == foakResult.hand);
192-
REQUIRE(1 << r3 == foakResult.high);
193-
REQUIRE(1 << rT == foakResult.low);
194-
195-
REQUIRE(foakResult.code < sf.code);
196-
197-
auto fullHouseBits = h3 | c3 | d3 | sA | hA | h2 | d2;
198-
auto fhr = ep::SWARRank(fullHouseBits);
199-
ep::CSet fhh = { ep::convert(fhr), fhr };
200-
auto fhhr = handRank(fhh);
201-
REQUIRE(ep::FULL_HOUSE == fhhr.hand);
202-
REQUIRE((0 | r3) == fhhr.high);
203-
REQUIRE((0 | rA) == fhhr.low);
204-
205-
auto fhr2 = ep::SWARRank(fullHouseBits | dA);
206-
ep::CSet fullHouseDoubleThreeOfAKind= { ep::convert(fhr2), fhr2 };
207-
auto dtfh = ep::handRank(fullHouseDoubleThreeOfAKind);
208-
REQUIRE(ep::FULL_HOUSE == dtfh.hand);
209-
REQUIRE((0 | rA) == dtfh.high);
210-
REQUIRE((0 | r3) == dtfh.low);
211-
REQUIRE(fhhr.code < dtfh.code);
212-
213-
auto fivesOverKingThree = ep::SWARRank(s5 | h5 | d5 | sK | c3 | h2);
214-
ep::CSet toak = { ep::convert(fivesOverKingThree), fivesOverKingThree };
215-
auto toakHR = ep::handRank(toak);
216-
REQUIRE(ep::THREE_OF_A_KIND == toakHR.hand);
217-
REQUIRE((0 | r5) == toakHR.high);
218-
REQUIRE((rK | r3) == toakHR.low); // successfully ignores the h2
219-
220-
auto tensAndSixesWithEightHigh = ep::SWARRank(sT | dT | c6 | s6 | h8 | s2);
221-
ep::CSet twoPairs = { ep::convert(tensAndSixesWithEightHigh), tensAndSixesWithEightHigh };
222-
auto twoPHR = ep::handRank(twoPairs);
223-
REQUIRE(ep::TWO_PAIRS == twoPHR.hand);
224-
REQUIRE((rT | r6) == twoPHR.high);
225-
REQUIRE((0 | r8) == twoPHR.low);
226-
227-
auto threesOverKQJ = ep::SWARRank(hK | dQ | cJ | s3 | d3 | s2);
228-
ep::CSet pair = { ep::convert(threesOverKQJ), threesOverKQJ };
229-
auto pairHR = ep::handRank(pair);
230-
REQUIRE(ep::PAIR == pairHR.hand);
231-
REQUIRE((0 | r3) == pairHR.high);
232-
REQUIRE((rK | rQ | rJ) == pairHR.low);
233-
234-
auto KT874 = ep::SWARRank(hK | dT | c8 | c7 | c4 | d3 | s2);
235-
ep::CSet kingHigh = { ep::convert(KT874), KT874 };
236-
auto kingHighT874 = ep::handRank(kingHigh);
237-
REQUIRE(ep::HIGH_CARDS == kingHighT874.hand);
238-
REQUIRE((rK | rT | r8 | r7 | r4) == kingHighT874.high);
239-
REQUIRE(0 == kingHighT874.low);
240-
}
241-
}
242-

0 commit comments

Comments
 (0)