Solution (source code)

= Solution

Treat the live <array> segment as a <FIFO queue> of runs. Remove its first two runs, append their merged result, and repeat:
``
PROCEDURE Sort(a, b: INTEGER; VAR c, d: INTEGER);
VAR x, y, z: INTEGER;
BEGIN
  c := a; d := b;
  WHILE c < d DO
    x := Run(c, d);
    IF x = d THEN RETURN END;
    y := Run(x, d);
    z := y-c;
    Merge(c, x, y, d);
    c := y;
    d := d+z
  END
END Sort;
``
Compute both run boundaries before writing the destination, which starts at the old `d`. The untouched suffix $u[y..d)$ is followed by the new merged run. The endpoints returned in `c,d` always describe the live <sequence>; obsolete values before `c` are ignored. As allowed, assume enough destination capacity.

For example, $[3,1,4,2]$ becomes the live <sequence> $[2,1,3,4]$, then $[1,2,3,4]$. The first merge combines $[3]$ and $[1,4]$, and the second combines $[2]$ and $[1,3,4]$.
$$
\boxed{u[c..d)\text{ contains the sorted input and }d-c=b-a.}
$$