# JUNTO Practice: Probability, NCAA Basketball Pool

Discussed on July 28, 2020.

From "Twenty problems in probability":

There are 64 teams who play single elimination tournament, hence 6 rounds, and you have to predict all the winners in all 63 games. Your score is then computed as follows, 32 points for correctly predicting the final winner, 16 points for each correct finalist, and so on, down to 1 point for every correctly predicted winner for the first round. (The maximum number of points you can get is thus 192.) Knowing nothing about any team, you flip fair coins to decide every one of your 63 bets. Compute the expected number of points.

Please provide an answer and a justification.

## Solutions

Click to see:

### Oscar Martinez

I believe that the expected number of points is 31.5.

`import numpy as np from numba import jit @jit def play_tourney(teams=64): rounds = int(np.log(teams / 2) / np.log(2)) bracket = [np.arange(teams)] remaining_teams = teams for i in range(rounds + 1): remaining_teams = remaining_teams // 2 match_arr = np.random.randint( 0, 2, (remaining_teams) ) + (np.arange(remaining_teams) * 2) match_arr = bracket[i][match_arr] bracket.append(match_arr) return bracket[1:] vec_play_tourney = np.vectorize(play_tourney) @jit def score(results, bets, max_points=32): points = 0 for i, r in enumerate(results): points += np.sum(r == bets[i]) * ( max_points // r.shape[0] ) return points vec_score = np.vectorize(score) @jit def simulate(simulations, teams=64, max_points=32): points = 0 for i in range(simulations): bets = play_tourney(teams) results = play_tourney(teams) points += score(results, bets, max_points) return points / simulations print(simulate(10000))`

```
31.2232
```

### John Lekberg

I believe that the expected number of points is about 31.5.

I created a Python function that simulates the betting and took the mean of 1,000,000 samples:

`import numpy as np N_TEAM = 64 N_ROUND = 6 ROUND_POINTS = np.array( [ 2 ** n for n in range(N_ROUND) for _ in range(2 ** (N_ROUND - (n + 1))) ] ) def random_outcome(N): """Sample the random variable 'the outcomes of the single-elimination tournament'. """ teams = np.repeat([np.arange(N_TEAM)], N, axis=0) rounds = [] for _ in range(N_ROUND): dim = list(teams.shape) dim[1] //= 2 # group_offset = np.arange(dim[1]) * 2 win_offset = np.random.randint(2, size=dim) win_index = group_offset + win_offset teams = np.take_along_axis(teams, win_index, axis=1) # rounds.append(teams) return np.concatenate(rounds, axis=1) def random_total_points(N): """Sample the random variable 'the total number of points from randomly betting'. """ bet = random_outcome(N) result = random_outcome(N) correct = bet == result total_points = correct @ ROUND_POINTS return total_points random_total_points(1_000_000).mean()`

```
31.519703
```

### Daniel Bassett

I believe that the expected number of points is about 31.55.

`import numpy as np def simulate(n): i = 0 results = [0 for i in range(n)] while i < len(results): round1 = np.random.choice( [0, 1], size=(32,), p=[63.0 / 64, 1.0 / 64] ) round2 = np.random.choice( [0, 2], size=(16,), p=[31.0 / 32, 1.0 / 32] ) round3 = np.random.choice( [0, 4], size=(8,), p=[15.0 / 16, 1.0 / 16] ) round4 = np.random.choice( [0, 8], size=(4,), p=[7.0 / 8, 1.0 / 8] ) round5 = np.random.choice( [0, 16], size=(2,), p=[3.0 / 4, 1.0 / 4] ) round6 = np.random.choice([0, 32], size=(1,)) tournament = [ sum(round1), sum(round2), sum(round3), sum(round4), sum(round5), sum(round6), ] results[i] = sum(tournament) i += 1 return sum(results) / len(results) print(simulate(100000))`

```
31.55746
```