python - How to find the number of ways to get 21 in Blackjack? -
some assumptions:
- one deck of 52 cards used
- picture cards count 10
- aces count 1 or 11
- the order not important (ie. ace + queen same queen + ace)
i thought sequentially try possible combinations , see ones add 21, there way many ways mix cards (52! ways). approach not take account order not important nor account fact there 4 maximum types of 1 card (spade, club, diamond, heart).
now thinking of problem this:
we have 11 "slots". each of these slots can have 53 possible things inside them: 1 of 52 cards or no card @ all. reason 11 slots because 11 cards maximum amount of cards can dealt , still add 21; more 11 cards have add more 21.
then "leftmost" slot incremented 1 , 11 slots checked see if add 21 (0 represent no card in slot). if not, next slot right incremented, , next, , on.
once first 4 slots contain same "card" (after 4 increments, first 4 slots 1), fifth slot not number since there 4 numbers of type. fifth slot become next lowest number in remaining available cards; in case of 4 1s, fifth slot become 2 , on.
how approach this?
before worrying suits , different cards value 10
lets figure out how many different value combinations resulting 21
there are. example 5, 5, 10, 1
1 such combination. following function takes in limit
target value, start
indicates lowest value can picked , used
list of picked values:
def combinations(limit, start, used): # base case if limit == 0: return 1 # start iteration lowest card picked far # we're going pick cards 3 & 7 in order 3,7 res = 0 in range(start, min(12, limit + 1)): # aces @ index 1 no matter if value 11 or 1 used index = if != 11 else 1 # there 16 cards value of 10 (t, j, q, k) , 4 every # other value available = 16 if index == 10 else 4 if used[index] < available: # mark card used , go through combinations starting # current card , limit lowered value used[index] += 1 res += combinations(limit - i, i, used) used[index] -= 1 return res print combinations(21, 1, [0] * 11) # 416
since we're interested different card combinations instead of different value combinations base case in above should modified return number of different card combinations can used generate value combination. luckily that's quite easy task, binomial coefficient can used figure out how many different combinations of k
items can picked n
items.
once number of different card combinations each value in used
known can multiplied each other final result. example of 5, 5, 10, 1
value 5
results bcoef(4, 2) == 6
, value 10
bcoef(16, 1) == 16
, value 1
bcoef(4, 1) == 4
. other values bcoef(x, 0)
results 1
. multiplying values results 6 * 16 * 4 == 384
returned:
import operator math import factorial def bcoef(n, k): return factorial(n) / (factorial(k) * factorial(n - k)) def combinations(limit, start, used): if limit == 0: combs = (bcoef(4 if != 10 else 16, x) i, x in enumerate(used)) res = reduce(operator.mul, combs, 1) return res res = 0 in range(start, min(12, limit + 1)): index = if != 11 else 1 available = 16 if index == 10 else 4 if used[index] < available: used[index] += 1 res += combinations(limit - i, i, used) used[index] -= 1 return res print combinations(21, 1, [0] * 11) # 186184
Comments
Post a Comment