All Euler problems
Project Euler

Under the Rainbow

70 colored balls are placed in an urn, 10 for each of the seven rainbow colors. What is the expected number of distinct colors in 20 randomly picked balls? Give your answer with nine digits after t...

Source sync Apr 19, 2026
Problem #0493
Level Level 06
Solved By 6,110
Languages C++, Python
Answer 6.818741802
Length 232 words
probabilitymodular_arithmeticbrute_force

Problem Statement

This archive keeps the full statement, math, and original media on the page.

\(70\) coloured balls are placed in an urn, \(10\) for each of the seven rainbow colours.

What is the expected number of distinct colours in \(20\) randomly picked balls?

Give your answer with nine digits after the decimal point (\(a.bcdefghij\)).

Problem 493: Under the Rainbow

Mathematical Foundation

Theorem 1 (Linearity of expectation for indicator variables). Let X=i=1nXiX = \sum_{i=1}^{n} X_i where each XiX_i is an indicator random variable. Then E[X]=i=1nP(Xi=1)E[X] = \sum_{i=1}^{n} P(X_i = 1), regardless of dependence among the XiX_i.

Proof. By the linearity of expectation, E[X]=E[i=1nXi]=i=1nE[Xi]E[X] = E\left[\sum_{i=1}^{n} X_i\right] = \sum_{i=1}^{n} E[X_i]. Since Xi{0,1}X_i \in \{0, 1\}, E[Xi]=P(Xi=1)E[X_i] = P(X_i = 1). \square

Theorem 2 (Expected distinct colors). Let DD be the number of distinct colors among 20 balls drawn without replacement from an urn of 70 balls (10 of each of 7 colors). Then

E[D]=7(1(6020)(7020)).E[D] = 7\left(1 - \frac{\binom{60}{20}}{\binom{70}{20}}\right).

Proof. For each color i{1,,7}i \in \{1, \ldots, 7\}, define Xi=1[color i is present in the draw]X_i = \mathbf{1}[\text{color } i \text{ is present in the draw}]. Then D=i=17XiD = \sum_{i=1}^{7} X_i. By Theorem 1:

E[D]=i=17P(Xi=1)=7P(X1=1)E[D] = \sum_{i=1}^{7} P(X_i = 1) = 7 \cdot P(X_1 = 1)

by symmetry (all colors are interchangeable). The complement is:

P(X1=0)=P(all 20 balls from the other 6 colors)=(6020)(7020)P(X_1 = 0) = P(\text{all 20 balls from the other 6 colors}) = \frac{\binom{60}{20}}{\binom{70}{20}}

since there are (6020)\binom{60}{20} ways to choose 20 balls from the 60 non-color-1 balls, out of (7020)\binom{70}{20} total ways. Hence P(X1=1)=1(6020)/(7020)P(X_1 = 1) = 1 - \binom{60}{20}/\binom{70}{20}, and the result follows. \square

Lemma 1 (Product formula for the ratio). The binomial ratio simplifies as:

(6020)(7020)=60!/(20!40!)70!/(20!50!)=60!50!70!40!=k=0950k70k.\frac{\binom{60}{20}}{\binom{70}{20}} = \frac{60! / (20! \cdot 40!)}{70! / (20! \cdot 50!)} = \frac{60! \cdot 50!}{70! \cdot 40!} = \prod_{k=0}^{9} \frac{50 - k}{70 - k}.

Proof. We have (6020)/(7020)=60!40!50!70!\binom{60}{20}/\binom{70}{20} = \frac{60!}{40!} \cdot \frac{50!}{70!}. Writing this as a ratio of falling factorials:

605941706951=j=4160jj=5170j.\frac{60 \cdot 59 \cdots 41}{70 \cdot 69 \cdots 51} = \frac{\prod_{j=41}^{60} j}{\prod_{j=51}^{70} j}.

The numerator has factors 41,42,,50,51,,6041, 42, \ldots, 50, 51, \ldots, 60 and the denominator has 51,52,,7051, 52, \ldots, 70. The common factors 51,,6051, \ldots, 60 cancel, leaving k=09(50k)/k=09(70k)\prod_{k=0}^{9}(50 - k)/\prod_{k=0}^{9}(70 - k). \square

Editorial

We enumerate the admissible parameter range, discard candidates that violate the derived bounds or arithmetic constraints, and update the final set or total whenever a candidate passes the acceptance test.

Pseudocode

ratio = 1
For k from 0 to 9:
    ratio *= (50 - k) / (70 - k)
answer = 7 * (1 - ratio)
output answer rounded to 9 decimal places

Complexity Analysis

  • Time: O(1)O(1) — a fixed product of 10 terms and one subtraction/multiplication.
  • Space: O(1)O(1).

Answer

6.818741802\boxed{6.818741802}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_493/solution.cpp
#include <bits/stdc++.h>
using namespace std;

int main(){
    // E[distinct colors] = 7 * (1 - C(60,20)/C(70,20))
    // C(60,20)/C(70,20) = prod_{k=0}^{9} (50-k)/(70-k)

    // Use exact rational arithmetic with long doubles or fractions
    // For precision, compute with exact fractions using __int128 or just careful doubles

    // Actually, let's use exact rational computation
    // Numerator: 50*49*48*47*46*45*44*43*42*41
    // Denominator: 70*69*68*67*66*65*64*63*62*61

    // These fit in unsigned long long
    // num = 50*49*48*47*46*45*44*43*42*41
    // den = 70*69*68*67*66*65*64*63*62*61

    // For exact decimal, use high-precision approach
    // But we can use long double which has ~18 digits of precision

    long double ratio = 1.0L;
    for(int k = 0; k < 10; k++){
        ratio *= (long double)(50 - k) / (long double)(70 - k);
    }

    long double answer = 7.0L * (1.0L - ratio);

    cout << fixed << setprecision(9) << answer << endl;

    return 0;
}