python - How to find the number of ways to get 21 in Blackjack? -


some assumptions:

  1. one deck of 52 cards used
  2. picture cards count 10
  3. aces count 1 or 11
  4. 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

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -