timsort.js
/**
 * * Returns the length of the run beginning at the specified position in
 * the specified array and reverses the run if it is descending (ensuring
 * that the run will always be ascending when the method returns).
 *
 * A run is the longest ascending sequence with:
 *
 *    a[lo] <= a[lo + 1] <= a[lo + 2] <= ...
 *
 * or the longest descending sequence with:
 *
 *    a[lo] >  a[lo + 1] >  a[lo + 2] >  ...
 *
 * For its intended use in a stable mergesort, the strictness of the
 * definition of "descending" is needed so that the call can safely
 * reverse a descending sequence without violating stability.
 *
 * @param {ARray} a 
 * @param {Number} lo 
 * @param {Number} hi 
 * @param {Function} c 
 * @returns {Number}
 */
Returns the length of the run beginning at the specified position in
the specified array and reverses the run if it is descending (ensuring
that the run will always be ascending when the method returns).

A run is the longest ascending sequence with.



or the longest descending sequence with.



For its intended use in a stable mergesort, the strictness of the
definition of "descending" is needed so that the call can safely
reverse a descending sequence without violating stability.


Returns the length of the run beginning at the specified position in the specified array and reverses the run if it is descending ( ensuring that the run will always be ascending when the method returns ) . A run is the longest ascending sequence with . or the longest descending sequence with . For its intended use in a stable mergesort the strictness of the definition of " descending " is needed so that the call can safely reverse a descending sequence without violating stability .
function countRunAndMakeAscending (a, lo, hi, c){
    let runHi = lo + 1;
    if (runHi === hi){
        return 1;
    } 
    if (c(a[runHi++], a[lo]) < 0) { 
        while(runHi < hi && c(a[runHi], a[runHi - 1]) < 0){
            runHi++;
        }
        reverseRange(a, lo, runHi);
    } else {                              
        while (runHi < hi && c(a[runHi], a[runHi - 1]) >= 0){
            runHi++;
        } 
    }
    return runHi - lo;
}
function countRunAndMakeAscending ( a , lo , hi , c ) { let runHi = lo + 1 ; if ( runHi === hi ) { return 1 ; } if ( c ( a [ runHi ++ ] , a [ lo ] ) < 0 ) { while ( runHi < hi && c ( a [ runHi ] , a [ runHi - 1 ] ) < 0 ) { runHi ++ ; } reverseRange ( a , lo , runHi ) ; } else { while ( runHi < hi && c ( a [ runHi ] , a [ runHi - 1 ] ) >= 0 ) { runHi ++ ; } } return runHi - lo ; }
* Returns the length of the run beginning at the specified position in
 the specified array and reverses the run if it is descending (ensuring
 that the run will always be ascending when the method returns).
* Returns the length of the run beginning at the specified position in the specified array and reverses the run if it is descending ( ensuring that the run will always be ascending when the method returns ) .
//assert lo < hi;
 // Find end of run, and reverse range if descending
 // Descending
 // Ascending
