December 2, 2025
Tonight I have prepared sautéed potatoes. It's pretty simple: cut the potatoes in rough cubes, ideally of the same size, and throw them in a pan that contains enough oil (or better, duck fat). Then you just need to sauté them while they cook on a relatively high heat. Salt, pepper, and there you have it, crispy sautéed potatoes.
As I was cooking my potatoes, I asked myself: how many times should I toss them?
Let's try to estimate this. We have potatoes with four sides. Every time I toss the potatoes, each cube lands randomly on one of its sides with equal probabilities, assuming my tossing technique is good enough. We'll assume that a potato cube is well cooked only after each of its four sides has been against the pan.
Let's first look at a single potato cube: what's the probability that it is well cooked after tosses? It's a combinatorial problem, let's break it down:
The final result is This follows the inclusion-exclusion principle.
Of course potato cubes have 6 faces, not 4, oops. Luckily, this gave us an intuition of the inclusion-exclusion principle. The generalization of the above result for faces is given by:
The probability tends exponentially to 1 as increases, as illustrated in the following figure:
Probability that a potato has touched all 6 sides after t tosses.
As expected, under 6 tosses, the probability that the potato is well cooked is zero, because it cannot have been on 6 faces. The figure shows that after 27 tosses, there is already more than 95% probability that the potato cube has visited all 6 faces. I don't have only one potato piece, but of them (say 40). The number of well cooked potatoes follows a binomial distribution, with success probability .
Median number of well cooked potatoes out of \(N=40\), against the number of tosses. Error bars indicate the 5 to 95% quantiles.
In my pan, most of the 40 potatoes will be well cooked after about 30 tosses. It's hard work, but totally worth it.
Of course many of the approximations I made are impractical, and this shouldn't serve as a 3 Michelin star level cooking guide. But this little exercise made me discover the inclusion-exclusion principle, and next time I'll count how many tosses I naturally do.
The figures were produced with these two scripts:
#!/usr/bin/env python
import argparse
import matplotlib.pyplot as plt
import math
import numpy as np
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--out', type=str, default=None, help='output plot')
args = parser.parse_args()
out = args.out
m = 6 # number of faces
t = np.arange(0, 50)
Pt = np.zeros(len(t))
for k in range(m+1):
Pt += (-1)**k * math.comb(m, k) * ((m-k)/m)**t
Pt = np.clip(Pt, 0, 1)
for t_, Pt_ in zip(t, Pt):
print(t_, Pt_)
fig, ax = plt.subplots()
ax.plot(t, Pt, '-o', clip_on=False)
ax.set_xlabel(r'$t$')
ax.set_ylabel(r'$P_6(t)$')
plt.tight_layout()
if out is None:
plt.show()
else:
plt.savefig(out)
if __name__ == '__main__':
main()
#!/usr/bin/env python
import argparse
import matplotlib.pyplot as plt
import math
import numpy as np
from scipy.stats import binom
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--out', type=str, default=None, help='output plot')
args = parser.parse_args()
out = args.out
m = 6 # number of faces
N = 40
t = np.arange(0, 50)
Pt = np.zeros(len(t))
for k in range(m+1):
Pt += (-1)**k * math.comb(m, k) * ((m-k)/m)**t
Pt = np.clip(Pt, 0, 1)
median = binom.median(N, Pt)
lo = binom.ppf(0.05, N, Pt)
hi = binom.ppf(0.95, N, Pt)
fig, ax = plt.subplots()
ax.errorbar(t, median, yerr=np.stack((median-lo, hi-median)), capsize=3, fmt='-o', clip_on=False)
ax.set_xlabel(r'Number of tosses $t$')
ax.set_ylabel(r'Number of well cooked potatoes $k$ out of $N={}$'.format(N))
plt.tight_layout()
if out is None:
plt.show()
else:
plt.savefig(out)
if __name__ == '__main__':
main()