Solve problem 493.
This commit is contained in:
63
python/e493.py
Normal file
63
python/e493.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
BALLS_PER_COLOR = 10
|
||||
N_COLORS = 7
|
||||
TO_DRAW = 20
|
||||
|
||||
|
||||
@lru_cache(maxsize=10**9)
|
||||
def count(urn, to_draw):
|
||||
if to_draw == 0:
|
||||
distinct_colors = sum([1 if c != BALLS_PER_COLOR else 0 for c in urn])
|
||||
return distinct_colors
|
||||
|
||||
remaining_balls = sum(urn)
|
||||
expected = 0
|
||||
for color_i, color_remaining in enumerate(urn):
|
||||
if color_remaining == 0:
|
||||
continue
|
||||
new_urn = list(urn)
|
||||
new_urn[color_i] -= 1
|
||||
expected_for_color = count(tuple(sorted(new_urn)), to_draw - 1)
|
||||
probability = color_remaining / remaining_balls
|
||||
expected += (probability * expected_for_color)
|
||||
return expected
|
||||
|
||||
|
||||
def binomial_coefficient(n, k):
|
||||
if k < 0 or k > n:
|
||||
return 0
|
||||
if k == 0 or k == n:
|
||||
return 1
|
||||
k = min(k, n - k)
|
||||
result = 1
|
||||
for i in range(k):
|
||||
result *= n - i
|
||||
result //= i + 1
|
||||
return result
|
||||
|
||||
|
||||
def math():
|
||||
# Find probability that a given color is chose in TO_DRAW draws.
|
||||
combs_without_color = binomial_coefficient((N_COLORS - 1) * BALLS_PER_COLOR, TO_DRAW)
|
||||
combs_with_color = binomial_coefficient(N_COLORS * BALLS_PER_COLOR, TO_DRAW)
|
||||
p_single_color = 1 - (combs_without_color / combs_with_color)
|
||||
# Then, expected colors is that probability times the number of colors.
|
||||
return p_single_color * N_COLORS
|
||||
|
||||
|
||||
def euler_493():
|
||||
urn = [BALLS_PER_COLOR for _ in range(N_COLORS)]
|
||||
c = count(tuple(urn), TO_DRAW)
|
||||
c = round(c, 9)
|
||||
m = round(math(), 9)
|
||||
assert c == m
|
||||
return c
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
solution = euler_493()
|
||||
print("e493.py: " + str(solution))
|
||||
# assert(solution == 0)
|
||||
|
||||
Reference in New Issue
Block a user