/* Array or list sort and reverse */

SORT_* :
 ARRAY
 LIST
;

*_SORT :
 QUICK
 SHUFFLE
 REVERSE
 NO
;

/* * */

Sort ->
Arg Array : ^&Array

- ArraySort 'Array' Sort_method
' Sort_method = SortMethod Already_ordered Array._ SORT_ARRAY
' Already_ordered = AlreadyOrdered Array

Return

/* * */

AlreadyOrdered Sort ->
Arg Array : Array
  - Counter = 0   

Do Counter ++ [ Array.i < Array.(i + 1) ]
Where i = 1 to Array._ - 1

Return

/* * */

Sort ->
Arg Dest : &List : T, Src : List : <T>

New : List : [Src] = <> ..

Dest = New
' ListSort >New< Src Sort_method
' Sort_method = SortMethod Already_ordered Src._ SORT_LIST
' Already_ordered = AlreadyOrdered Src

Return

/* * */

AlreadyOrdered Sort ->
Arg List : List
  - Counter = 0   

Prev = . ..

Do get Element from List
 Z = Prev = Element
 Counter ++ [ Z && Z < Element ]
;

Return

/* Action selectors */

SortMethod Sort ->
Arg Ordered, Total : Integer
    . : SORT_ARRAY

When Total = 0 | Total = 1 then
Return NO_SORT

When Ordered = Total - 1 then
Return NO_SORT

When Ordered = 0 then
Return REVERSE_SORT

Else
Return SHUFFLE_SORT

/* * */

SortMethod Sort ->
Arg Ordered, Total : Integer
    . : SORT_LIST

When Total = 0 | Total = 1 then
Return NO_SORT

When Ordered = Total - 1 then
Return NO_SORT

When Ordered = 0 then
Return REVERSE_SORT

Else
Return QUICK_SORT

/* Empty functions */

ArraySort '?' NO_SORT = _
ListSort >?< ? NO_SORT = _

