I asked a question on math.stackexchange.com, and recieved a great answer. This is my attempt to implement the insighful solution (link to question)

After some thought and reading comments on math stackexchange, i decided to implement the recursive solution rather than the linear algebra one for now


In [1]:
from __future__ import division
from copy import deepcopy

def hit_hand(score, soft, value):
    '''given a hand and a card, returns the new hand
    
    arguments: 
    score: the current score of the hand (int)
    soft: whether or not the score is soft (boolean)
    value: the value of the card to add to the hand
    
    returns (score, soft): the score and whether or not the score is soft of the resulting hand
    '''
    if soft and score + value > 21:
        score = score - 10 + value
        soft = False
    elif value == 1 and score + 11 <= 21:
        score += 11
        soft = True
    else:
        score += value
    return (score, soft)


def p_bust(hand, shoe, p=0.0):
    '''given a hand and a shoe, returns the probability of busting
    assumes dealer stands on soft 17
    
    arguments:
    hand: tuple containing score and whether score is soft (tuple)
    shoe: the number of cards of each value left to draw (list)
    
    keyword_arguments:
    p: aggregator for probability of busting (default=0.0)
    
    returns p: probability of busting (float)
    '''
    score, soft = hand
    if score <= 16:
        for card in range(10):
            if shoe[card] > 0:
                score_after_hitting, soft = hit_hand(score, soft, card + 1)
                if score_after_hitting >= 22:
                    p += shoe[card]/sum(shoe)
                elif score_after_hitting <= 16:
                    new_shoe = deepcopy(shoe)
                    new_shoe[card] -= 1
                    p += shoe[card]/sum(shoe) * p_bust((score_after_hitting, soft), new_shoe)
    return p


def possible_hands(showing, shoe):
    ''' generates a list of all possible hands and the probability 
    of seeing that hand given a shoe and an upcard
    
    arguments:
    showing: the value of the card that is showing
    shoe: the number of cards of each value left to draw (list)
    
    returns [((score, scoft) p), ...]: list of the hands (tuple of the score and whether it is soft) and probability of hand
    '''
    hands = []
    for card in range(10):
        p_card = shoe[card] / sum(shoe)
        new_shoe = shoe_minus_card(shoe, card)
        if showing == 1:
            hands.append((hit_hand(11, True, card + 1), new_shoe, p_card))
        else:
            hands.append((hit_hand(showing, False, card + 1), new_shoe, p_card))
    return hands

def shoe_minus_card(shoe, card):
    new_shoe = deepcopy(shoe)
    new_shoe[card] -= 1
    return new_shoe

master_shoe = [4*6 for _ in range (9)] + [4*4*6]

for card in range(10):
    shoe = shoe_minus_card(master_shoe, card)
    print 'Probability of bust showing %d: %f' % (card + 1, sum([p_bust(hand, new_shoe)*p_card for hand, new_shoe, p_card in possible_hands(card + 1, shoe)]))


Probability of bust showing 1: 0.185319
Probability of bust showing 2: 0.351725
Probability of bust showing 3: 0.375495
Probability of bust showing 4: 0.399843
Probability of bust showing 5: 0.426344
Probability of bust showing 6: 0.416197
Probability of bust showing 7: 0.257623
Probability of bust showing 8: 0.241649
Probability of bust showing 9: 0.229242
Probability of bust showing 10: 0.212471

True probabilities:

Dealer's
up Card
Dealer's Final Total
17 18 19 20 21 BJ Bust
Ace 0.130017 0.130822 0.130594 0.13091 0.0535035 0.308682 0.115473
2 0.139656 0.134389 0.13002 0.124019 0.118413 0 0.353504
3 0.134296 0.130539 0.125226 0.120817 0.114928 0 0.374194
4 0.130556 0.124062 0.121272 0.116441 0.111866 0 0.395805
5 0.121843 0.122437 0.117575 0.111793 0.107945 0 0.418406
6 0.165707 0.106194 0.106431 0.101551 0.0972756 0 0.422842
7 0.369208 0.137931 0.078428 0.0786816 0.0738158 0 0.261936
8 0.12894 0.359955 0.128723 0.0692189 0.0694701 0 0.243693
9 0.12031 0.117348 0.351854 0.120368 0.0608772 0 0.229242
10 0.111914 0.111669 0.111945 0.340014 0.0348174 0.0771704 0.212471
All 0.145245 0.139258 0.133685 0.179527 0.0728741 0.0474895 0.281921