Solution (source code)

= Solution

Save the last entry, shift the others right in descending index order, and put the saved value at the left. Descending order prevents overwriting an unread entry.
``
PROCEDURE rotate(i, n, k: INTEGER);
VAR x: T; step, t: INTEGER;
BEGIN
  IF (k = 0) OR (k = n) THEN RETURN END;
  step := 0;
  WHILE step < k DO
    x := m[i+n-1];
    t := n-1;
    WHILE t > 0 DO
      m[i+t] := m[i+t-1];
      t := t-1
    END;
    m[i] := x;
    step := step+1
  END
END rotate;
``
For one pass, after the shifts at offsets greater than `t`, those positions contain the original preceding entries; offsets through `t` are still available, and `x` retains the original last entry. The <loop variant> `t` decreases to zero. The outer <loop invariant> is that the segment has been rotated right by `step` places relative to its initial state. Repeating a one-step <cyclic permutation> $k$ times therefore gives the required <array rotation>. \b[The method uses one extra `T` variable and $O(kn)$ time], with $O(1)$ auxiliary space. The early return avoids all accesses for an identity rotation.