## Riddler Express

My condo complex has a single elevator that serves four stories: the garage $(G)$, the first floor $(1)$, the second floor $(2)$ and the third floor $(3)$. Unfortunately, the elevator is malfunctioning and stopping at every single floor, no matter what. The elevator always goes $G, 1, 2, 3, 2, 1, G, 1, 2,$ etc.

I want to board the elevator on a random floor (with all four floors being equally likely). As I round the corner to approach the elevator, I hear that its doors have closed, but I have no further information about which floor it’s on or whether the elevator is going up or down. The doors might have just closed on my floor, for all I know.

On average, how many stops will the elevator make until it opens on my floor (including the stop on your floor)? For example, if I am waiting on the second floor, and I heard the doors closing on the garage level, then the elevator would open on my floor in two stops.

Extra credit: Instead of four floors, suppose my condo had $N$ floors. On average, how many stops will the elevator make until it opens on my floor?

## Computational Solution

From the simulation below, we see that the average number of stops when there are $\textbf{four}$ floors is $\textbf{2.83}$.

from itertools import cycle
from random import choice, randint

def avg_stops(n = 4, runs = 100000):
rotate = lambda l, n: l[-n:] + l[:-n]
floors, elevator_cycle = list(range(n)), list(range(n)) + list(range(n-2,0,-1))
total_stops = 0
for _ in range(runs):
my_floor, start = choice(floors), randint(0, len(elevator_cycle)-1)
for f in cycle(rotate(elevator_cycle, start)):
total_stops += 1
if f == my_floor:
break

print(avg_stops())


## Riddler Classic

You are the coach at Riddler Fencing Academy, where your three students are squaring off against a neighboring squad. Each of your students has a different probability of winning any given point in a match. The strongest fencer has a $75$ percent chance of winning each point. The weakest has only a $25$ percent chance of winning each point. The remaining fencer has a $50$ percent probability of winning each point.

The match will be a relay. First, one of your students will face off against an opponent. As soon as one of them reaches a score of $15$, they are both swapped out. Then, a different student of yours faces a different opponent, continuing from wherever the score left off. When one team reaches $30$ (not necessarily from the same team that first reached $15$), both fencers are swapped out. The remaining two fencers continue the relay until one team reaches $45$ points.

As the coach, you can choose the order in which your three students occupy the three positions in the relay: going first, second or third. How will you order them? And then what will be your team’s chances of winning the relay?

## Computational Solution

From the simulation below, we see that the probability of the permutation $\textbf{weakest, medium, strongest}$ winning is the highest at $\approx\textbf{93%}$.

from itertools import permutations
from random import random

def winning_probabilities(runs = 100000):
win_prob = {'w':0.25,'s':0.75, 'm':0.5}
probs = []
for p1,p2,p3 in permutations(win_prob.keys()):
total_wins = 0
for _ in range(runs):
s1, s2 = 0, 0
while (s1 < 15 and s2 < 15):
if (random() < win_prob[p1]):
s1 += 1
else:
s2 += 1
while (s1 < 30 and s2 < 30):
if (random() < win_prob[p2]):
s1 += 1
else:
s2 += 1
while (s1 < 45 and s2 < 45):
if (random() < win_prob[p3]):
s1 += 1
else:
s2 += 1
if s1 == 45:
total_wins += 1
probs.append((p1,p2,p3,total_wins/runs))
return probs

for p1,p2,p3,prob in winning_probabilities():
print(f"Probability of the permutation {(p1,p2,p3)} winning is {prob}")