CS‑01 calc stackhp first, all calculators welcome
#8 — Any

The Outbreak Curve

The problem

It is Halloween season, so assume the worst. A zombie virus reaches a town of 80,000 people, carried in by a single infected traveller at hour 0. Nobody is immune, nobody is cured, and there is no way out.

Early on, while almost everyone is still healthy, the number of infected grows exponentially at a rate of r = 0.20 per hour. That is about 22% more each hour, since e^0.2 = 1.221. But the outbreak cannot grow that way forever. The more of the town is already infected, the harder it is for a zombie to find someone new, so the spread slows down. The standard model for this is the logistic equation, where I is the number infected, N the town’s population and r the early growth rate:

dI/dt = r · I · (1 − I/N)

with N = 80,000, r = 0.20 per hour and I = 1 at t = 0. Treat the town as closed (nobody enters or leaves) and the infected as a smooth number rather than a head count.

Emergency services are stretched thinnest at the moment the outbreak is spreading fastest, when new infections per hour are at their maximum. That is when the shelters fill, the beds run out and the barricades are tested hardest.

At what hour, counted from the first infection, is the outbreak spreading fastest?

Notes

  • The model is deliberately simple: a closed town, a smooth curve, no one fighting back. A real outbreak is messier. It is the shape of the curve that matters here.
  • Answer in hours, to a few decimal places. Converting to hours and minutes is a nice extra.
  • It needs a logarithm and one subtraction. Because of that subtraction a slide rule is not a fair contender this time.

Hint

Click for a hint

The rate of new infections, r · I · (1 − I/N), is a parabola in I. It is zero when I = 0 and zero again when I = N, so it peaks exactly half way between them.

The fastest spread therefore happens when I = N/2. Now solve the logistic curve

I(t) = N / ( 1 + (N/I₀ − 1) · e^(−r·t) )

for the time at which I reaches that value.

Solution

Click to reveal the solution

Where the peak is. The rate dI/dt = r · I · (1 − I/N) is a downward parabola in I with its vertex at I = N/2. So new infections per hour are greatest when exactly half the town is infected.

When that happens. The logistic solution is

I(t) = N / ( 1 + (N/I₀ − 1) · e^(−r·t) )

Setting I = N/2 gives 1 + (N/I₀ − 1) · e^(−r·t) = 2, so

(N/I₀ − 1) · e^(−r·t) = 1     →     t = ln(N/I₀ − 1) / r

With N = 80,000, I₀ = 1 and r = 0.20:

t = ln(79,999) / 0.20 = 11.28977 / 0.20 = 56.4488 hours

Answer: 56.45 hours, which is 56 hours 27 minutes after the first infection.

Checks. At that moment exactly 40,000 people are infected, and the outbreak is adding r · N / 4 = 0.20 × 80,000 / 4 = 4,000 new infections per hour. Stepping the equation forward numerically in tiny time slices, the rate peaks at the same hour.

Why the logistic matters. Ignore the slowdown and let the infection keep growing exponentially at r = 0.20 per hour, and it reaches 40,000 in ln(40,000) / 0.20 = 52.98 hours. The real curve takes about 3.5 hours longer, because the later part of the climb is already being held back by the shrinking pool of healthy people.

Calculator solutions

HP-42S

No memory registers needed. The subtraction turns 80,000 into 79,999.

80000        ENTER
1            -
LN
0.2          ÷

Result: 56.4488

HP-15C

LN is g then the LN key.

80000        ENTER
1            -
g LN
0.2          ÷

Display: 56.4488

HP-41C
80000        ENTER
1            -
LN
0.2          ÷

Display: 56.4488

HP-48GX

LN is the right-shift of 1/x. Plain stack entry, no symbolic traps.

80000        ENTER
1            -
right-shift 1/x   (LN)
0.2          ÷

Display: 56.448847068

HP-25

The machine powers up in FIX 2. Press f FIX 4 first to compare against the other machines.

80000        ENTER
1            -
f LN
0.2          ÷

Display: 56.4488

Elektronika MK-61

Natural log is F then the key marked ln (the 3 key). Enter every number starting with a digit: 0.2 is typed 0 . 2.

80000        В↑
1            -
F ln
0.2          ÷

Display: 56.448845

The MK-61 works to 8 digits, so its last digit or two can differ slightly from the other machines’.

TI-84
ln(80000-1)/.2

Result: 56.44884707

Casio fx-991

Natural display mode:

ln(80000-1)÷0.2

Result: 56.44884707

Bonus: hold the gate

For programmable calculators only.

The town has one last strongpoint, a walled compound with a single gate. 1,000 zombies are about to hit it. You decide how many defenders to put on the wall. This is a game: you key in a garrison, the program fights the siege, and you learn whether the gate held. Your task is to find the smallest garrison that holds, by writing the program and then playing it.

The rules. The fight is played one round at a time. In every round:

  • each defender brings down 0.25 zombies,
  • each zombie brings down 0.05 defenders, and
  • every defender brought down rises as a zombie, joining the horde at once.

Both sides lose their casualties in the same round, using the numbers from the start of that round. With D defenders and Z zombies, and t = 0.05 · Z defenders falling this round:

D  becomes  D − t
Z  becomes  Z + t − 0.25 · D

The fight is over when either side is down to 1 or fewer. If the defenders still have more than one left, the gate held; otherwise it fell. The zombies always start at Z = 1000.

The task. Write a program that takes the garrison D in a register, runs the siege, and stops with the number of defenders left on the display. A result of 1 or less means the gate fell, and a negative number is just the last round overshooting.

Test your program on these cases:

Case Garrison D
A 500
B 600

Then play: raise and lower the garrison until you have the smallest whole number of defenders that holds the gate.

Click for a hint

Keep three registers: D, Z and the casualties t. Each round computes t first, then both new numbers from the old ones. The order matters, because the new Z needs the old D:

t    =  0.05 · Z
Z    =  Z + t − 0.25 · D       (uses the old D, so do this first)
D    =  D − t

After each round, test D and then Z against 1 and leave the loop if either is 1 or less. When the loop ends, recall D.

Click to reveal the solution
Case Garrison Defenders left Result
A 500 −1.28 the gate fell
B 600 258.5 the gate held

Playing the game, the smallest garrison that holds is 559:

Garrison Defenders left Result
558 −2.07 the gate fell
559 46.7 the gate held

Every garrison from 559 upward holds, and every smaller one falls. The edge is sharp: one defender more or fewer decides the siege.

Why 559 and not about 447. If the dead did not rise, this would be the classic square-law fight, named after Frederick Lanchester, who worked it out in the First World War. Firepower scales with the square of the numbers, so the break-even is where 0.25 · D² equals 0.05 · Z²:

D = Z · √(0.05 / 0.25) = 1000 · √0.2 = 447.2

The raised dead add reinforcements to the horde every round, so the defenders need roughly a quarter more than the square law says. The 559 belongs to this model, stepped one round at a time; it is a number for this game, not a constant of nature.

Programs

Programs follow for the HP-42S, HP-15C, HP-41C, Elektronika MK-61 and HP-25. Open the one for your calculator, key it in once, then store a garrison and run it. The text to the right of a listing explains it; do not key it in.

HP-42S

This program uses 29 lines. Press PRGM, key in the lines, press PRGM again.

01      LBL 01                            start
02-03   1000   STO 02                     Z = 1000, the horde
04      LBL 02                            a round starts here
05-08   RCL 02   0.05   ×   STO 04        t = 0.05 · Z, saved
09      RCL+ 02                           Z + t
10-13   RCL 01   0.25   ×   −             Z + t − 0.25 · D, using the old D
14      STO 02                            the new Z
15-18   RCL 01   RCL 04   −   STO 01      D − t, the new D
19-21   1   X≥Y?   GTO 03                 1 ≥ D: the defenders are done, leave
22-25   RCL 02   1   X≥Y?   GTO 03        1 ≥ Z: the horde is done, leave
26      GTO 02                            next round
27      LBL 03
28      RCL 01                            the defenders left
29      RTN                               stop, result in X

To run it, store the garrison and start it. For case A:

500  STO 01
XEQ 01

The defenders left appear in X: −1.2842.

HP-15C

This program uses 42 lines. g P/R toggles program mode; LBL 1 is f LBL 1, and the test is g x≤y (the g ÷ key).

01      f LBL 1                           start
02-06   1000   STO 2                      Z = 1000, the horde
07      f LBL 2                           a round starts here
08-14   RCL 2   0.05   ×   STO 4          t = 0.05 · Z, saved
15-16   RCL 2   +                         Z + t
17-23   RCL 1   0.25   ×   −              Z + t − 0.25 · D, using the old D
24      STO 2                             the new Z
25-28   RCL 1   RCL 4   −   STO 1         D − t, the new D
29-32   1   ENTER   RCL 1   g x≤y         D ≤ 1 ?
33      GTO 3                             yes: the defenders are done, leave
34-37   1   ENTER   RCL 2   g x≤y         Z ≤ 1 ?
38      GTO 3                             yes: the horde is done, leave
39      GTO 2                             next round
40      f LBL 3
41-42   RCL 1   R/S                       stop with the defenders left showing

To run it, store the garrison and start it. For case A:

500  STO 1
GSB 1

The defenders left show when the program stops: −1.2842. A long fight takes the 15C a few minutes.

HP-41C

This program is 33 lines long. PRGM toggles program mode; LBL is the gold shift of STO, and the test X<=Y? is the gold shift of +.

01      LBL 01                            start
02-03   1000   STO 02                     Z = 1000, the horde
04      LBL 02                            a round starts here
05-08   RCL 02   0.05   ×   STO 04        t = 0.05 · Z, saved
09-10   RCL 02   +                        Z + t
11-14   RCL 01   0.25   ×   −             Z + t − 0.25 · D, using the old D
15      STO 02                            the new Z
16-19   RCL 01   RCL 04   −   STO 01      D − t, the new D
20-23   1   ENTER↑   RCL 01   X<=Y?        D ≤ 1 ?
24      GTO 03                            yes: the defenders are done, leave
25-28   1   ENTER↑   RCL 02   X<=Y?        Z ≤ 1 ?
29      GTO 03                            yes: the horde is done, leave
30      GTO 02                            next round
31      LBL 03
32-33   RCL 01   R/S                      stop with the defenders left showing

To run it, store the garrison and start it. For case A:

500  STO 01
XEQ 01

The defenders left show when the program stops: −1.2842. A long fight takes the 41C a few minutes.

Elektronika MK-61

This program uses 44 of the machine’s 105 steps. F ПРГ enters program mode and F АВТ leaves it. Type every number starting with a digit. Addresses start at 00. A conditional or БП jump takes its two-digit address as one step, and the conditional jumps when its test is false.

00-03   1 0 0 0                           Z = 1000, the horde
04      x→П 2
05      П→x 2                             a round starts here (address 05)
06-11   В↑  0 . 0 5   ×                   0.05 · Z
12      x→П 4                             t, saved
13-14   П→x 2   +                         Z + t
15-22   П→x 1   В↑  0 . 2 5   ×   −       Z + t − 0.25 · D, using the old D
23      x→П 2                             the new Z
24-27   П→x 1   П→x 4   −   x→П 1         D − t, the new D
28-31   1   В↑  П→x 1   −                 1 − D
32-33   F x<0   42                        if 1 − D is not negative, D ≤ 1: leave
34-37   1   В↑  П→x 2   −                 1 − Z
38-39   F x<0   42                        if 1 − Z is not negative, Z ≤ 1: leave
40-41   БП 05                             next round
42      П→x 1                             the defenders left (address 42)
43      С/П                               stop

To run it, store the garrison and start it. For case A:

5  0  0  x→П 1
БП 0 0
С/П

The defenders left show when it stops: −1.284218.

The MK-61 works to 8 digits, and the fight subtracts large numbers from each other, so its answer agrees with the other machines to about five figures, not to the last digit. It shows the same winners and losers.

HP-25

The HP-25 has room for 49 program steps, and this program uses 34. With the switch at PRGM, press f PRGM to clear program memory, then key in the steps. A typed number takes one step per key, RCL n, STO n and GTO nn take one step each, and a test runs the step after it only when it is true.

01-05   1 0 0 0   STO 2                   Z = 1000, the horde
06      RCL 2                             a round starts here (line 06)
07-11   . 0 5   ×   STO 4                 t = 0.05 · Z, saved
12-13   RCL 2   +                         Z + t
14-19   RCL 1   . 2 5   ×   −             Z + t − 0.25 · D, using the old D
20      STO 2                             the new Z
21-24   RCL 1   RCL 4   −   STO 1         D − t, the new D
25-27   1   f x≥y   GTO 33                1 ≥ D: the defenders are done, leave
28-31   RCL 2   1   f x≥y   GTO 33        1 ≥ Z: the horde is done, leave
32      GTO 06                            next round
33      RCL 1                             the defenders left (line 33)
34      R/S                               stop

Typing the 1 right after STO 1 pushes D up into Y, so the test asks whether 1 ≥ D with no RCL needed.

Set the switch to RUN, press f FIX 4, store the garrison, then GTO 0 0 and R/S. For case A:

500  STO 1
GTO 0 0
R/S

The defenders left show when the program stops: −1.2842. The HP-25 is slow, and a long fight takes it a few minutes.

Anymediumepidemiologylogistic-growthlogarithmshalloweenzombies

Solvable on: HP-42S, HP-15C, HP-41C, HP-48GX, HP-25, Elektronika MK-61, TI-84, Casio fx-991