Created
June 28, 2021 13:26
-
-
Save sjdv1982/d18046b0e2727cd6223aa30b0286827f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
11 cards, 55 points in total | |
S = current score | |
K = cards remaining | |
score increase = (chance to draw a non-joker * average value of non-joker) - (chance to draw a joker * S) | |
= (K-1)/K * (55-S)/(K-1) - 1/K * S | |
= (55-S)/K - S/K | |
= (55 - 2S)/K | |
=> score increase is larger than zero if S < 28, regardless of K | |
""" | |
# Define a pattern that describes which cards have been drawn (yes/no from card 1 to card 10) | |
import numpy as np | |
pos_weights = np.array([2**n for n in range(10)],int) | |
pos_weights = pos_weights[::-1] | |
def pattern_to_position(pattern): | |
return (pos_weights * pattern).sum() | |
score_weights = np.arange(1, 11,dtype=int) | |
def pattern_to_score(pattern): | |
return (score_weights * pattern).sum() | |
# All possible patterns | |
import itertools | |
patterns = list(itertools.product([0,1], repeat=10)) | |
patterns = np.array(patterns, dtype=bool) | |
# Store the prob of reaching a pattern | |
probs = np.zeros(len(patterns)) | |
probs[0] = 1 # we start at the all-zero pattern | |
# If we draw a card (without drawing the joker), the position *increases*. | |
# We keep track of prob, the probability of reaching the current pattern. | |
# We know the probability of drawing each card, and multiply this with prob | |
# Now we iterate over the patterns *in order*, starting with the lowest position (all zeros) | |
# This means that when we reach a pattern, we have processed already all patterns that reach this pattern | |
# So prob will have reached its final value already. | |
expected_value = 0 | |
for pos in range(len(patterns)): | |
pattern = patterns[pos] | |
assert pattern_to_position(pattern) == pos, (pattern, pos, pattern_to_position(pattern)) | |
prob = probs[pos] | |
score = pattern_to_score(pattern) | |
if score >= 28: # we walk away | |
expected_value += prob * score | |
# print("%2.2d" % (pos+1), "%2.2d" % score, "%-7.3g" % prob, "%-7.3g" % (prob * score), pattern) | |
continue | |
else: # we continue | |
# print("%2.2d" % (pos+1), "%2.2d" % score, "%-7.3g" % prob, None, " ", pattern) | |
pass | |
remaining_cards = 11 - pattern.sum() | |
draw_prob = 1/remaining_cards | |
new_prob = prob * draw_prob | |
for n in range(10): | |
if pattern[n]: | |
continue | |
new_pattern = pattern.copy() | |
new_pattern[n] = 1 | |
new_position = pattern_to_position(new_pattern) | |
probs[new_position] += new_prob | |
print("Expected value", expected_value) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment