AutomaticMonkey
AutomaticMonkey
  • Threads: 9
  • Posts: 383
Joined: Sep 30, 2024
March 23rd, 2025 at 2:41:13 AM permalink
When doing my AP coding, I always found defining and identifying straights (the poker kind) to be onerous and resource consuming. Moving cards around, reordering, testing, using the ace as either high or low.

But I came up with an idea today to link the rank of each card to a distinct prime number. There are only so many different straights that can occur for any number of cards. By multiplying the primes associated with each rank, if the product is equal to the product representing some straight I know a straight is what it is, and because of the commutative property of multiplication I don't need to do any reordering of the cards, doesn't matter. In this way for every combination of cards (but not permutation) the product of these primes will be unique.

So I assigned the values 2,3,5,7... 41 to the cards ranks 2 to Ace. This is four card straights I'm solving, so my constants from straights A-4 to J-A are: 1230, 210, 1155, 5005, 17017, 46189, 96577, 215441, 392863, 765049, 1363783

Then my code, worked into a combinatorial analysis program, looks like:

strproduct = c(l1).prime * c(l2).prime * c(l3).prime * c(l4).prime

Select Case strproduct
Case Is = 1230, 210, 1155, 5005, 17017, 46189, 96577, 215441, 392863, 765049, 1363783
straight = 1
End Select


Much to my delight, I discovered this same method can be used to identify pairs, trips, all kinds of things that could require long and confusing code to implement depending on the game.

Did I invent this? If not, does somebody here who actually is a coder or mathematician know where I can do some more reading on the method?
odiousgambit
odiousgambit
  • Threads: 328
  • Posts: 9870
Joined: Nov 9, 2009
March 23rd, 2025 at 5:23:33 AM permalink
interesting

beware of turning into that doctor who was playing poker in "The Cincinnati Kid" ... ha ha [not sure how many would get that reference]

as far as straights, I found it useful to add 4 to the low end of a possible straight when I didn't have it all memorized, still useful sometimes. In other words, 6+4=10, but not 11, so among a set of numbers none lower than 6, a straight to the 10 [but not to 11, a Jack] is possible

7 to J, 8 to Q, 9 to K, and 10 to A is all thoroughly memorized, they are too important not to
the next time Dame Fortune toys with your heart, your soul and your wallet, raise your glass and praise her thus: “Thanks for nothing, you cold-hearted, evil, damnable, nefarious, low-life, malicious monster from Hell!”   She is, after all, stone deaf. ... Arnold Snyder
aceside
aceside
  • Threads: 2
  • Posts: 647
Joined: May 14, 2021
March 23rd, 2025 at 6:14:21 AM permalink
RE Monkey:

“ By multiplying the primes associated with each rank, if the product is equal to”

Let me use the hand A234 as an example to consider. These cards are represented by a prime number each:

A=41,
2=2,
3=3,
4=5.

41x2x3x5=1,230, which is greater than 2x3x5x7=210. This means that the hand A234 is higher in rank than the hand 2345. There is a problem here.

A234 is also higher in rank than 3456. How about you define the rank order first and then representation second?
Mental
Mental
  • Threads: 17
  • Posts: 1555
Joined: Dec 10, 2018
Thanked by
AutomaticMonkey
March 23rd, 2025 at 7:55:52 AM permalink
Quote: AutomaticMonkey

When doing my AP coding, I always found defining and identifying straights (the poker kind) to be onerous and resource consuming. Moving cards around, reordering, testing, using the ace as either high or low.

But I came up with an idea today to link the rank of each card to a distinct prime number. There are only so many different straights that can occur for any number of cards. By multiplying the primes associated with each rank, if the product is equal to the product representing some straight I know a straight is what it is, and because of the commutative property of multiplication I don't need to do any reordering of the cards, doesn't matter. In this way for every combination of cards (but not permutation) the product of these primes will be unique.

So I assigned the values 2,3,5,7... 41 to the cards ranks 2 to Ace. This is four card straights I'm solving, so my constants from straights A-4 to J-A are: 1230, 210, 1155, 5005, 17017, 46189, 96577, 215441, 392863, 765049, 1363783

Then my code, worked into a combinatorial analysis program, looks like:


strproduct = c(l1).prime * c(l2).prime * c(l3).prime * c(l4).prime

Select Case strproduct
Case Is = 1230, 210, 1155, 5005, 17017, 46189, 96577, 215441, 392863, 765049, 1363783
straight = 1
End Select


Much to my delight, I discovered this same method can be used to identify pairs, trips, all kinds of things that could require long and confusing code to implement depending on the game.

Did I invent this? If not, does somebody here who actually is a coder or mathematician know where I can do some more reading on the method?
link to original post


What you are doing is creating a unique hash value for each hand. The use of hash functions arose from the work of Hans Peter Luhn in 1953 at IBM. The idea of using prime numbers to improve hash function distribution and reduce collisions emerged from the work of other IBM researchers shortly thereafter.

I wrote a VP program in the 1990s using a primes hash function for 5-card hands. Thie resulting hash table was too large for the computer I had at the time. I knew TomSki had improved the Dancer / Daly VP analyzer using a perfect hash. A little research showed that the Wizard was also using a perfect hash. His hash function hashed to a continuous sequence of numbers, which means the hash gets you to a much smaller range of values than your primes method. That is, you can hash all unique 5-card hands into values 0-2598959 (52 choose 5). You can use this value to index a 2598960 size array to get the poker rank of any hand. I implemented my own hash that got the same hash values as the Wizard, but slightly more efficiently. Wizard's article lead me to work by VPGenius that described the Serpinski triangle method of doing VP calculations extremely efficiently. I think that the VPGenius web site is no longer available.

https://en.wikipedia.org/wiki/Perfect_hash_function

I don't know whether Mike or JB did most of the code development for the WOO site. Have a look at:
https://wizardofodds.com/article/programming-video-poker-code/
Gambling is a math contest where the score is tracked in dollars. Try not to get a negative score.
ThatDonGuy
ThatDonGuy
  • Threads: 125
  • Posts: 6928
Joined: Jun 22, 2011
March 23rd, 2025 at 9:33:05 AM permalink
One problem I can see is, how do you identify a pair of deuces?
You can't just take the remainder modulo 4 and see if it is zero, as you have also "identified" every two pair of deuces and something else, every full house where deuces is on either side, plus three deuces and four deuces, as a pair of deuces.

Your method does have some merit - in fact, you can go one step further:
Start with 11, 13, 17,... for the ranks, then multiply each spade by 2, each heart by 3, each club by 5, and each diamond by 7; every hand whose product is a multiple of 2^5, 3^5, 5^5, or 7^5 is a flush.
AutomaticMonkey
AutomaticMonkey
  • Threads: 9
  • Posts: 383
Joined: Sep 30, 2024
March 23rd, 2025 at 11:33:40 AM permalink
Quote: ThatDonGuy

One problem I can see is, how do you identify a pair of deuces?
You can't just take the remainder modulo 4 and see if it is zero, as you have also "identified" every two pair of deuces and something else, every full house where deuces is on either side, plus three deuces and four deuces, as a pair of deuces.

Your method does have some merit - in fact, you can go one step further:
Start with 11, 13, 17,... for the ranks, then multiply each spade by 2, each heart by 3, each club by 5, and each diamond by 7; every hand whose product is a multiple of 2^5, 3^5, 5^5, or 7^5 is a flush.
link to original post



For pairs and trips I just added more steps. This is how I did the trips:


tripstest1 = c(l2).prime * c(l3).prime * c(l4).prime
tripstest2 = c(l1).prime * c(l3).prime * c(l4).prime
tripstest3 = c(l1).prime * c(l2).prime * c(l4).prime
tripstest4 = c(l1).prime * c(l2).prime * c(l3).prime

'cubes of primes are: 8,27,125,343,1331,2197,4913,6859,12167,24389,29791,50653,68921

Select Case tripstest1
Case Is = 8, 27, 125, 343, 1331, 2197, 4913, 6859, 12167, 24389, 29791, 50653, 68921
trips = 1
pay = 15
GoTo esceval
End Select

Select Case tripstest2
Case Is = 8, 27, 125, 343, 1331, 2197, 4913, 6859, 12167, 24389, 29791, 50653, 68921
trips = 1
pay = 15
GoTo esceval
End Select

Select Case tripstest3
Case Is = 8, 27, 125, 343, 1331, 2197, 4913, 6859, 12167, 24389, 29791, 50653, 68921
trips = 1
pay = 15
GoTo esceval
End Select

Select Case tripstest4
Case Is = 8, 27, 125, 343, 1331, 2197, 4913, 6859, 12167, 24389, 29791, 50653, 68921
trips = 1
pay = 15
GoTo esceval
End Select


It looks for the 4 different permutations corresponding to any 4-card combination that is trips, pays them, then escapes the evaluation and steps to the next number in the CA if it finds them. I'm not sure if this was any faster than brute-forcing it with logic, but it is easier to debug and modify.

To distinguish trips from quads, I just did the quads first with ordinary logic, and escaped if I found them, so the trips part of the code would never be executed if there were quads.


If c(l1).rank = c(l2).rank And c(l1).rank = c(l3).rank And c(l1).rank = c(l4).rank Then
quads = 1
pay = 75
GoTo esceval
End If


This was all for a bet that pays for a poker hand, but no competitive poker hands involved, so there is no need to rank straights, trips etc., either you have them or you don't.

Yes I see where this could be applied to a 52-card model too, or 53 cards for pai gow. Maybe I could use -1 for the joker.
aceside
aceside
  • Threads: 2
  • Posts: 647
Joined: May 14, 2021
March 23rd, 2025 at 2:32:20 PM permalink
Quote: ThatDonGuy


Start with 11, 13, 17,... for the ranks, then multiply each spade by 2, each heart by 3, each club by 5, and each diamond by 7; every hand whose product is a multiple of 2^5, 3^5, 5^5, or 7^5 is a flush.
link to original post


Let me use a five-card poker hand to test your theory first. We consider this hand of 23567 of spades.

11x13x19x23x29x2=3,624,478,
Which is not a multiple any of these 2^5, 3^5, 5^5, 7^5.

Because
3624478/32=113,264.938
3624478/243=14,915.547
3624478/3125=1,159.833
3624478/16807=215.653.

What say you?
ThatDonGuy
ThatDonGuy
  • Threads: 125
  • Posts: 6928
Joined: Jun 22, 2011
March 23rd, 2025 at 4:02:46 PM permalink
Quote: aceside

Quote: ThatDonGuy


Start with 11, 13, 17,... for the ranks, then multiply each spade by 2, each heart by 3, each club by 5, and each diamond by 7; every hand whose product is a multiple of 2^5, 3^5, 5^5, or 7^5 is a flush.
link to original post


Let me use a five-card poker hand to test your theory first. We consider this hand of 23567 of spades.

11x13x19x23x29x2=3,624,478,
Which is not a multiple any of these 2^5, 3^5, 5^5, 7^5.

Because
3624478/32=113,264.938
3624478/243=14,915.547
3624478/3125=1,159.833
3624478/16807=215.653.

What say you?
link to original post


Each card has to be multiplied by 2 if it is a spade.
2 of spades is 11 x 2 = 22; 2 of hearts is 11 x 3 = 33; 2 of clubs is 11 x 5 = 55; 2 of diamonds is 11 x 7 = 77
Similarly, 3 of spades is 13 x 2 = 26, 5 of spades is 19 x 2 = 38, 6 of spades is 23 x 2 = 46, and 7 of spades is 29 x 2 = 58
The product is 11 x 13 x 19 x 23 x 29 x 2^5.
  • Jump to: