Library · The Fiddler: Solutions · Chapter 147

Can You Set a Winning Baseball Lineup?

Revised Report an error

You manage the New York Frets and are rearranging the batting order. Eight of your nine batters are pure contact hitters. Each of them hits a single one time in three, moving every runner on base forward exactly one base; the team is so slow that nobody scores from first or second on a single, only from third. The other two times in three he is out, and the runners stay where they are. Your ninth batter is a slugger, who hits a home run one time in ten and strikes out otherwise. Where in the lineup should the slugger bat to score the most runs, on average, in the first inning?

The Fiddler, Zach Wissner-Gross, August 18, 2023(original post)

The official solution appeared in the post of August 25, 2023 and gives fourth for the main puzzle and third and fourth, with about 1.99771.9977 runs a game, for the Extra Credit. Both agree with the answers below.

Solution

The trade-off. A home run scores the slugger and everyone on base, so he wants to bat after some contact hitters have reached base. But every batter ahead of him is also a chance for the inning to end before he comes up. Batting later buys more runners at the risk of not batting at all.

His first time up shows the trade-off cleanly. If he bats kkth, the k−1k - 1 contact hitters before him each single with chance 13\frac13. His home run, with chance 110\frac1{10}, is worth 11 run plus one for each runner on base, so this first trip to the plate is worth 110\frac1{10} of the expected value of 1+(runners on)1 + (\text{runners on}) in the cases where he gets to bat at all.

  • Batting first or second, he always bats; the expected value is 11, or 1+13=431 + \frac13 = \frac43.

  • Batting third, he always bats, since two outs cannot end the inning; the two hitters ahead of him put on 23\frac23 of a runner on average, so the value is 53=4527\frac53 = \frac{45}{27}.

  • Batting fourth, he bats only if at least one of the three hitters ahead of him singled. With ss singles among them, which happens with chance (3s)(13)s(23)3−s\binom3s(\frac13)^s(\frac23)^{3-s}, he bats with ss runners on: 49⋅2+29⋅3+127⋅4  =  4627.\tfrac49 \cdot 2 + \tfrac29 \cdot 3 + \tfrac1{27} \cdot 4 \;=\; \tfrac{46}{27}.

  • Batting fifth, he needs two singles among four hitters, and a fourth single scores a run on its own rather than adding a runner: 2481⋅3+881⋅4+181⋅4=43\frac{24}{81}\cdot 3 + \frac{8}{81}\cdot 4 + \frac1{81}\cdot 4 = \frac43.

The first trip to the plate is worth most from the fourth spot, by just 127\frac1{27} of a home run’s worth over the third. That is a narrow margin, and it is not the whole story: a slugger batting early may come up a second time, and the contact hitters drive in runs of their own when they find the bases loaded.

The whole inning. To count everything, describe the inning by its state: the number of outs, which bases are occupied, and who is due up. From each state the next plate appearance leads to two others, with known chances and a known number of runs. Writing E(σ)E(\sigma) for the expected runs still to come from state σ\sigma, E(σ)  =  ∑outcomesPr⁡(outcome)(runs scored+E(next state)),E(\sigma) \;=\; \sum_{\text{outcomes}} \Pr(\text{outcome}) \bigl(\text{runs scored} + E(\text{next state})\bigr), with E=0E = 0 once there are three outs. Hits do not add outs, so an inning can in principle go on for ever and the states can loop back on themselves; these equations are therefore solved as a linear system, one for each number of outs, over the 8×9=728 \times 9 = 72 combinations of runners and batter. Solving them with the slugger in each spot gives the first-inning expectation:

slugger bats 1 2 3 4 5
runs 0.1841 0.2107 0.2394 0.2401 0.2027
slugger bats 6 7 8 9
runs 0.1562 0.1683 0.1742 0.1770

 bat the slugger fourth: 0.24014 runs,against 0.23937 batting third \boxed{\ \begin{array}{c} \text{bat the slugger fourth: } 0.24014 \text{ runs,} \\ \text{against } 0.23937 \text{ batting third} \end{array} \ } The first-trip advantage of 1270≈0.0037\frac{1}{270} \approx 0.0037 runs survives, shrunk to 0.00080.0008 by the other effects. The answer is fragile in the way such close calls are: with a home run rate of 55 per cent instead of 1010, the official write-up notes, the best spot moves to ninth.

The computation

The check does not solve equations. It plays the rules forward one plate appearance at a time, carrying the probability of every situation (inning, outs, runners, batter due up) and adding up the expected runs as they score, until the chance that the game is still going is below 10−1510^{-15}. The same function handles any number of innings and any set of sluggers.

import numpy as np
from itertools import combinations

def expected_runs(sluggers, innings):
    """Play forward one plate appearance at a time, carrying
    the chance of every situation: inning, outs, runners
    (bit 0 first base, bit 1 second, bit 2 third) and the
    batter due up. Returns the expected runs scored."""
    dist = np.zeros((innings, 3, 8, 9))
    dist[0, 0, 0, 0] = 1.0           # first inning, batter 1
    runs = 0.0
    while dist.sum() > 1e-15:
        new = np.zeros_like(dist)
        for inn, outs, bases, i in zip(*np.nonzero(dist)):
            p = dist[inn, outs, bases, i]
            j = (i + 1) % 9
            if i in sluggers:        # home run, 1 in 10
                on = bin(bases).count("1")
                runs += p*0.1*(1 + on)
                new[inn, outs, 0, j] += p*0.1
                q = 0.9
            else:                    # single, 1 in 3
                runs += p/3*(bases >> 2)       # from third
                new[inn, outs, (bases << 1 | 1) & 7, j] += p/3
                q = 2/3
            if outs < 2:             # an out, runners stay
                new[inn, outs + 1, bases, j] += p*q
            elif inn + 1 < innings:  # third out: next inning
                new[inn + 1, 0, 0, j] += p*q
        dist = new
    return runs

for k in range(9):
    e = expected_runs({k}, 1)
    print(f"slugger batting {k + 1}: {e:.5f} runs")

It prints

slugger batting 1: 0.18413 runs
slugger batting 2: 0.21073 runs
slugger batting 3: 0.23937 runs
slugger batting 4: 0.24014 runs
slugger batting 5: 0.20273 runs
slugger batting 6: 0.15624 runs
slugger batting 7: 0.16834 runs
slugger batting 8: 0.17425 runs
slugger batting 9: 0.17696 runs

Extra Credit

Now you have two sluggers and seven contact hitters, and you want the most runs over a nine-inning game. Where should the sluggers bat?

Solution

Over a game, each inning starts with whoever follows the last batter of the inning before, so the innings are linked. The inning equations above handle this with one more ingredient. For each possible leadoff batter ss, solving the same kind of linear system gives the expected runs RsR_s in an inning that ss leads off, and the chance MstM_{st} that the next inning is led off by tt. If dd is the row of chances for who leads off an inning, starting with batter 11 for certain, the game’s expected runs are ∑inningsd⋅R,with d replaced by dM after each inning.\sum_{\text{innings}} d \cdot R, \qquad \text{with } d \text{ replaced by } dM \text{ after each inning}. Doing this for each of the (92)=36\binom92 = 36 placements of the two sluggers gives the five best:

sluggers bat 3 and 4 2 and 3 3 and 7 4 and 8 3 and 8
runs a game 1.9977 1.9876 1.9843 1.9806 1.9799

 the sluggers should bat third and fourth. \boxed{\ \text{the sluggers should bat third and fourth}. \ } Putting them back to back is best, but splitting them four places apart, so that the contact hitters can refill the bases after the first slugger clears them, is close behind. Over a whole game a single slugger is also best third rather than fourth, since being near the top of the order matters more when the order turns over several times.

The computation

The forward simulation above runs a full nine innings for each placement.

pairs = combinations(range(9), 2)
games = sorted(((expected_runs({a, b}, 9), a + 1, b + 1)
                for a, b in pairs), reverse=True)
for e, a, b in games[:5]:
    print(f"sluggers batting {a} and {b}: {e:.4f} runs")

It prints

sluggers batting 3 and 4: 1.9977 runs
sluggers batting 2 and 3: 1.9876 runs
sluggers batting 3 and 7: 1.9843 runs
sluggers batting 4 and 8: 1.9806 runs
sluggers batting 3 and 8: 1.9799 runs
Report an error on this page

Reports are stored by Netlify. See the privacy note.