Solution (source code)

= Solution

Set aside the selected pivot at the end, <array partitioning> the other entries, then move the pivot to the separation index:
``
def partition(l: Int, r: Int): Int = {
  require(0 <= l && l < r && r <= a.length)
  def swap(i: Int, j: Int): Unit = {
    val t = a(i); a(i) = a(j); a(j) = t
  }
  val chosen = bestIndex(l, r)
  val x = a(chosen)
  swap(chosen, r - 1)
  var p = l
  var j = l
  while (j < r - 1) {
    if (a(j) < x) {
      swap(p, j)
      p += 1
    }
    j += 1
  }
  swap(p, r - 1)
  p
}
``
The <loop invariant> is $l\leq p\leq j\leq r-1$, $a[l,p)<x$, $a[p,j)\geq x$, and $a(r-1)=x$. The segment's <multiset> is unchanged and all entries outside it are unchanged. A low entry is swapped into the low segment; a high entry simply extends the high segment. The <loop variant> is $r-1-j$. At exit, exchanging the reserved pivot with `a(p)` gives \b[$a[l,p)<x$, $a(p)=x$, and $a[p+1,r)\geq x$]. The displaced value at the old pivot position was already at least $x$. Length one is handled by self-swaps and an empty loop. Duplicate pivot values belong to the high side. This costs $\Theta(r-l)$ time and $O(1)$ auxiliary space.