SHOE_SIZE = 6
STAND_ON_SOFT_SEVENTEEN = True
def blackjack_score(hand):
soft = sum(hand) < 12 and 1 in hand
return sum(hand) + (10 if soft else 0), soft
def busted(hand):
return blackjack_score(hand)[0] > 21
def stand(hand):
score, soft = blackjack_score(hand)
return score > 17 or (score == 17 and (STAND_ON_SOFT_SEVENTEEN or not soft))
def hand_probability(hand):
total_cards = 52 * SHOE_SIZE
value_counts = [SHOE_SIZE * rank for rank in [0,4,4,4,4,4,4,4,4,4,16]]
numerator = 1
denominator = 1
for card in hand:
numerator *= value_counts[card]
denominator *= total_cards
value_counts[card] -= 1
total_cards -= 1
return numerator/denominator
cards = list(range(1,11))
initial_hands = [(c,d) for c in cards for d in cards]
hits = []
stands = []
busts = []
for hand in initial_hands:
if stand(hand):
stands.append(hand)
else:
hits.append(hand)
while(hits):
old_hand = hits.pop()
for card in cards:
new_hand = old_hand + (card,)
if busted(new_hand):
busts.append(new_hand)
elif stand(new_hand):
stands.append(new_hand)
else:
hits.append(new_hand)
print(sum(hand_probability(hand) for hand in stands))
print(sum(hand_probability(hand) for hand in busts))
print(len(stands))
print(len(busts))
U0hPRV9TSVpFID0gNgpTVEFORF9PTl9TT0ZUX1NFVkVOVEVFTiA9IFRydWUKCmRlZiBibGFja2phY2tfc2NvcmUoaGFuZCk6Cglzb2Z0ID0gc3VtKGhhbmQpIDwgMTIgYW5kIDEgaW4gaGFuZAoJcmV0dXJuIHN1bShoYW5kKSArICgxMCBpZiBzb2Z0IGVsc2UgMCksIHNvZnQKCmRlZiBidXN0ZWQoaGFuZCk6CglyZXR1cm4gYmxhY2tqYWNrX3Njb3JlKGhhbmQpWzBdID4gMjEKCmRlZiBzdGFuZChoYW5kKToKCXNjb3JlLCBzb2Z0ID0gYmxhY2tqYWNrX3Njb3JlKGhhbmQpCglyZXR1cm4gc2NvcmUgPiAxNyBvciAoc2NvcmUgPT0gMTcgYW5kIChTVEFORF9PTl9TT0ZUX1NFVkVOVEVFTiBvciBub3Qgc29mdCkpCgpkZWYgaGFuZF9wcm9iYWJpbGl0eShoYW5kKToKCXRvdGFsX2NhcmRzID0gNTIgKiBTSE9FX1NJWkUKCXZhbHVlX2NvdW50cyA9IFtTSE9FX1NJWkUgKiByYW5rIGZvciByYW5rIGluIFswLDQsNCw0LDQsNCw0LDQsNCw0LDE2XV0KCW51bWVyYXRvciA9IDEKCWRlbm9taW5hdG9yID0gMQoJZm9yIGNhcmQgaW4gaGFuZDoKCQludW1lcmF0b3IgKj0gdmFsdWVfY291bnRzW2NhcmRdCgkJZGVub21pbmF0b3IgKj0gdG90YWxfY2FyZHMKCQl2YWx1ZV9jb3VudHNbY2FyZF0gLT0gMQoJCXRvdGFsX2NhcmRzIC09IDEKCXJldHVybiBudW1lcmF0b3IvZGVub21pbmF0b3IKCmNhcmRzID0gbGlzdChyYW5nZSgxLDExKSkKCmluaXRpYWxfaGFuZHMgPSBbKGMsZCkgZm9yIGMgaW4gY2FyZHMgZm9yIGQgaW4gY2FyZHNdCmhpdHMgPSBbXQpzdGFuZHMgPSBbXQpidXN0cyA9IFtdCgpmb3IgaGFuZCBpbiBpbml0aWFsX2hhbmRzOgoJaWYgc3RhbmQoaGFuZCk6CgkJc3RhbmRzLmFwcGVuZChoYW5kKQoJZWxzZToKCQloaXRzLmFwcGVuZChoYW5kKQoKd2hpbGUoaGl0cyk6CglvbGRfaGFuZCA9IGhpdHMucG9wKCkKCWZvciBjYXJkIGluIGNhcmRzOgoJCW5ld19oYW5kID0gb2xkX2hhbmQgKyAoY2FyZCwpCgkJaWYgYnVzdGVkKG5ld19oYW5kKToKCQkJYnVzdHMuYXBwZW5kKG5ld19oYW5kKQoJCWVsaWYgc3RhbmQobmV3X2hhbmQpOgoJCQlzdGFuZHMuYXBwZW5kKG5ld19oYW5kKQoJCWVsc2U6CgkJCWhpdHMuYXBwZW5kKG5ld19oYW5kKQoKcHJpbnQoc3VtKGhhbmRfcHJvYmFiaWxpdHkoaGFuZCkgZm9yIGhhbmQgaW4gc3RhbmRzKSkKcHJpbnQoc3VtKGhhbmRfcHJvYmFiaWxpdHkoaGFuZCkgZm9yIGhhbmQgaW4gYnVzdHMpKQpwcmludChsZW4oc3RhbmRzKSkKcHJpbnQobGVuKGJ1c3RzKSk=