Optimized Pancake sort

Optimized Pancake sort is a modification of Pancake Sort, which improves on the $$O(n^2)$$ time of the original algorithm. The result is a modification of Rotate Merge Sort, where all the moves are legal for pancakes, yet retains all of the time bounds of Rotate Merge.

Optimized Pancake sort makes $$O(n\log n)$$ comparisons and $$O(n\log^2 n)$$ moves worst case but $$O(\log n)$$ space due to recursion. Unlike typical Pancake Sort, this algorithm makes $$O(n\log n)$$ flips instead of $$O(n)$$ which is sub-optimal, but each flip is $$O(\log n)$$ moves amortized. This sort can also be made stable (and, consequently, a Burnt Pancake variant).

Algorithm
The algorithm is best described recursively:
 * 1) Divide array $$A$$ into $$BC$$ and sort $$B$$ recursively.
 * 2) Rotate $$BC \rightarrow CB$$ and sort $$C$$ recursively.
 * 3) Merge $$C$$ and $$B$$ using an in-place recursive pancake merge.

Pseudocode
procedure opti_pancake_sort(array arr, int n) do if n > 1 do int m = floor(n/2) opti_pancake_sort(arr, m)      rotate(arr, 0, m, n-m) opti_pancake_sort(arr, n-m) merge(arr, m, n-m) end if end

Rotation
procedure rotate(array arr, int pos, int len1, int len2) do flip range 0 to pos+len1-1 flip range 0 to pos+len1+len2-1 flip range 0 to pos+len2-1 flip range 0 to pos-1 end

Merge routine
procedure merge(array arr, int len1, int len2) do if len1 > 0 and len2 > 0 do int midLen1 = length of len1 larger than median int midLen2 = length of len2 smaller than median # both can be found using a single binary search rotate(arr, len1-midLen1, midLen1, midLen2) merge(arr, len1-midLen1, midLen1) rotate(arr, 0, len1, len2) merge(arr, midLen2, len2-midLen2) rotate(arr, 0, len2, len1) end if end