import algorithm, sequtils, strutils

type OID = distinct string

# Borrow the `$` procedure from the base string type.
proc `$`(oid: OID): string {.borrow.}

template toSeqInt(oid: OID): seq[int] =
  ## Convert an OID into a sequence of integers.
  oid.string.split('.').map(parseInt)

proc oidCmp(a, b: OID): int =
  ## Compare two OIDs. Return 0 if OIDs are equal, -1 if the first is
  ## less than the second, +1 is the first is greater than the second.
  let aseq = a.toSeqInt
  let bseq = b.toSeqInt
  for i in 0..<min(aseq.len, bseq.len):
    result = cmp(aseq[i], bseq[i])
    if result != 0: return
  result = cmp(aseq.len, bseq.len)

when isMainModule:

  const OIDS = [OID"1.3.6.1.4.1.11.2.17.19.3.4.0.10",
                OID"1.3.6.1.4.1.11.2.17.5.2.0.79",
                OID"1.3.6.1.4.1.11.2.17.19.3.4.0.4",
                OID"1.3.6.1.4.1.11150.3.4.0.1",
                OID"1.3.6.1.4.1.11.2.17.19.3.4.0.1",
                OID"1.3.6.1.4.1.11150.3.4.0"]

  for oid in OIDS.sorted(oidCmp):
    echo oid


mums := list(2,4,3,1,2)
sorted := nums sort  # returns a new sorted array.  'nums' is unchanged
nums sortInPlace  # sort 'nums' "in-place"


import java.util.Arrays;

public class Example {
    public static void main(String[] args)
    {
        int[] nums = {2,4,3,1,2};
        Arrays.sort(nums);
    }
}


include ..\Utilitys.pmt

( "1.3.6.1.4.1.11.2.17.19.3.4.0.10"
 "1.3.6.1.4.1.11.2.17.5.2.0.79"
 "1.3.6.1.4.1.11.2.17.19.3.4.0.4"
 "1.3.6.1.4.1.11150.3.4.0.1"
 "1.3.6.1.4.1.11.2.17.19.3.4.0.1"
 "1.3.6.1.4.1.11150.3.4.0" )

len for
    var i
    i get "." " " subst split
    len for
        var j
        j get tonum j set
    endfor
    i set
endfor

sort

len for
    var i
    i get
    "" var string
    len for
        get tostr "." chain string swap chain var string
    endfor
    drop
    string 0 del i set
endfor

len for get print nl endfor


main:-
    sort_oid_list(["1.3.6.1.4.1.11.2.17.19.3.4.0.10",
    "1.3.6.1.4.1.11.2.17.5.2.0.79",
    "1.3.6.1.4.1.11.2.17.19.3.4.0.4",
    "1.3.6.1.4.1.11150.3.4.0.1",
    "1.3.6.1.4.1.11.2.17.19.3.4.0.1",
    "1.3.6.1.4.1.11150.3.4.0"], Sorted_list),
    foreach(member(oid(_, Oid), Sorted_list), writeln(Oid)).

sort_oid_list(Oid_list, Sorted_list):-
    parse_oid_list(Oid_list, Parsed),
    sort(1, @=<, Parsed, Sorted_list).

parse_oid_list([], []):-!.
parse_oid_list([Oid|Oid_list], [oid(Numbers, Oid)|Parsed]):-
    parse_oid(Oid, Numbers),
    parse_oid_list(Oid_list, Parsed).

parse_oid(Oid, Numbers):-
    split_string(Oid, ".", ".", Strings),
    number_strings(Numbers, Strings).

number_strings([], []):-!.
number_strings([Number|Numbers], [String|Strings]):-
    number_string(Number, String),
    number_strings(Numbers, Strings).


function int_arr(a, b) {
  return a - b;
}
var numbers = [20, 7, 65, 10, 3, 0, 8, -60];
numbers.sort(int_arr);
document.write(numbers);


from jinja2 import Template
print(Template("{{ [53, 17, 42, 61, 35] | sort }}").render())


julia> a = [4,2,3,1]
4-element Int32 Array:
 4
 2
 3
 1
julia> sort(a) #out-of-place/non-mutating sort
4-element Int32 Array:
 1
 2
 3
 4

julia> a
4-element Int32 Array:
 4
 2
 3
 1

julia> sort!(a) # in-place/mutating sort
4-element Int32 Array:
 1
 2
 3
 4

julia> a
4-element Int32 Array:
 1
 2
 3
 4


/*REXX program performs a  sort  of  OID  (Object IDentifiers ◄── used in Network data).*/
call gen                                         /*generate an array (@.) from the OIDs.*/
call show   'before sort ───► '                  /*display the  @  array before sorting.*/
                             say copies('░', 79) /*   "   fence, separate before & after*/
call adj    1                                    /*expand  the  $  list of OID numbers. */
call bSort  #                                    /*sort     "   "    "   "  "     "     */
call adj    0                                    /*shrink   "   "    "   "  "     "     */
call show   ' after sort ───► '                  /*display the  @  array after sorting. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
bSort: procedure expose @.; parse arg n;   m=n-1 /*N: is the number of @ array elements.*/
          do m=m  for m  by -1  until ok;  ok= 1 /*keep sorting the @ array until done. */
             do j=1  for m;     _= j + 1         /*calculate the next (index) in @ array*/
             if @.j>@._  then parse value    @.j  @._  0      with      @._  @.j  ok
             end   /*j*/                         /* [↑]  swap two out─of─order elements.*/
          end      /*m*/                         /* [↑]  use a simple  bubble  sort.    */
       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
gen:   $=    1.3.6.1.4.1.11.2.17.19.3.4.0.10 ,   /* ◄──┐                                */
             1.3.6.1.4.1.11.2.17.5.2.0.79    ,   /* ◄──┤                                */
             1.3.6.1.4.1.11.2.17.19.3.4.0.4  ,   /* ◄──┼─◄─ six OID numbers (as a list).*/
             1.3.6.1.4.1.11150.3.4.0.1       ,   /* ◄──┤                                */
             1.3.6.1.4.1.11.2.17.19.3.4.0.1  ,   /* ◄──┤                                */
             1.3.6.1.4.1.11150.3.4.0             /* ◄──┘                                */
       w= 0                                                      /*W: max length of #'s.*/
       #= words($);     do i=1  for #;    @.i= word($, i);    w= max(w, length(@.i) )
                        end   /*i*/                              /*W: max length of #'s.*/
       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
adj:   arg LZ;  do j=1  for #;       x= translate(@.j, , .);  y= /*construct X version. */
                   do k=1  for words(x);           _= word(x, k) /*get a number in  X.  */
                   if LZ  then y= y right(_, w, 0)               /*(prepend) leading 0's*/
                          else y= y    (_   +   0)               /* (elide)     "     " */
                   end   /*k*/
                @.j = translate( space(y), ., ' ')               /*reconstitute number. */
                end      /*j*/                                   /*LZ:  Leading Zero(s).*/
       return                                                    /*──   ─       ─       */
/*──────────────────────────────────────────────────────────────────────────────────────*/
show:  do a=1 for #; say right("OID number",20) right(a,length(#)) arg(1) @.a; end; return


  num: -10?10              / Integers from 0 to 9 in random order
5 9 4 2 0 3 6 1 8 7

  srt: {[email protected]<x}              / Generalized sort ascending
  srt num
0 1 2 3 4 5 6 7 8 9


// version 1.0.6

fun main(args: Array<String>) {
   val ints = intArrayOf(6, 2, 7, 8, 3, 1, 10, 5, 4, 9)
   ints.sort()
   println(ints.joinToString(prefix = "[", postfix = "]"))
}


1) sorting digits in a number returns a new number of ordered digits
{W.sort < 51324}
-> 12345

2) sorting a sequence of numbers returns a new ordered sequence of these numbers
{S.sort < 51 111 33 2 41}
-> 2 33 41 51 111

3) sorting an array of numbers returns the same array ordered
{A.sort! < {A.new 51 111 33 2 41}}
-> [2,33,41,51,111]


/*
 +--------------------------------------------------------------
 +        Program Name : SortOIDNumeric.ring
 +        Date         : 2016-07-14
 +        Author       : Bert Mariani
 +        Purpose      : Sort OID List in Numeric Order
 +--------------------------------------------------------------
*/

oldOidList =
[
	".1.3.6.1.4.1.11.2.17.19.3.4.0.10",
	".1.3.6.1.4.1.11.2.17.5.2.0.79",
	".1.3.6.1.4.1.11.2.17.19.3.4.0.4",
	".1.3.6.1.4.1.11150.3.4.0.1",
	".1.3.6.1.4.1.11.2.17.19.3.4.0.1",
	".1.3.6.1.4.1.11150.3.4.0"
]

        ### SHOW BEFORE SORT
        See nl + "oldOIDList Before Sort" +nl
        See  oldOidList

    #---------------------

     delChar = "."
     nulChar = ""
     padChar = " "
     padSize = 6
     newDotPadList = []

    ### Split list into lines
    for line in oldOidList

        ### Split line by . into components
        noDotList  = str2list( substr(line, delChar, nl) )

        ### Pad components with left blanks to make equal size
        newPadList  = PadStringList(noDotList, padChar, padSize)

        ### Join the components back to a line
        newDotPadString  = JoinStringList(delChar, newPadList)

        ### Create new list - Alpha
        Add(newDotPadList, newDotPadString)
    next

    ### Sorts Alpha list
    newDotPadListSorted = sort(newDotPadList)

         ### SHOW ALPHA INTERMEDIATE OUTPUT
         See nl + "newDotPadListSorted Intermediate Sort" +nl
         See  newDotPadListSorted

    ### Remove blanks for original look
    newOidList = RemovePadCharList( newDotPadListSorted, padChar, nulChar)

    ###--------------------

        ### SHOW AFTER SORT - NUMERIC
        See nl + "newOIDList Final Sort" +nl
        See  newOidList

###--------------------------------------------------------------------
### Function: PadStringList
###         newList = PadStringList(oldList, padChar, padSize )
###--------------------------------------------------------------------

Func PadStringList oldList, padChar, padSize
    newList = []
    for line in oldList
        newPadSize = padSize - len(line)
        newLine = Copy( padChar, newPadSize) + line
        Add(newList, newLine)
    next

    ### First line in all blank because of leading dot - remove
    Del(newList,1)
return newList

###------------------------------------------------------------
### FUNC JoinStringList
###         newString = JoinStringList( joinChar, oldList)
###------------------------------------------------------------

Func JoinStringList joinChar, OldList
    newString = ""
    for line in OldList
        newString = newString + joinChar + line
    next
return newString

###---------------------------------------------------------------------
### FUNC RemovePadCharList
###         newOidList = RemovePadCharList( oldList, padChar, nulChar)
###---------------------------------------------------------------------

Func RemovePadCharList oldList, padChar, nulChar
    newList = []
    for line in oldList
          noPadString = substr(line, padChar, nulChar)
        Add(newList, noPadString)
    next
return newList
###-----------------------------------------------------------

>;


local(array) = array(5,20,3,2,6,1,4)
#array->sort
#array // 1, 2, 3, 4, 5, 6, 20

// Reverse the sort order
#array->sort(false)
#array // 20, 6, 5, 4, 3, 2, 1


N =20
dim IntArray( N)

print "Original order"
for i =1 to N
    t =int( 1000 *rnd( 1))
    IntArray( i) =t
    print t
next i

sort IntArray(), 1, N

print "Sorted oprder"
for i =1 to N
    print IntArray( i)
next i


put "3,2,5,4,1" into X
sort items of X numeric
put X
-- outputs "1,2,3,4,5"


import Foundation

public struct OID {
  public var val: String

  public init(_ val: String) {
    self.val = val
  }
}

extension OID: CustomStringConvertible {
  public var description: String {
    return val
  }
}

extension OID: Comparable {
  public static func < (lhs: OID, rhs: OID) -> Bool {
    let split1 = lhs.val.components(separatedBy: ".").compactMap(Int.init)
    let split2 = rhs.val.components(separatedBy: ".").compactMap(Int.init)
    let minSize = min(split1.count, split2.count)

    for i in 0..<minSize {
      if split1[i] < split2[i] {
        return true
      } else if split1[i] > split2[i] {
        return false
      }
    }

    return split1.count < split2.count
  }

  public static func == (lhs: OID, rhs: OID) -> Bool {
    return lhs.val == rhs.val
  }
}

let ids = [
  "1.3.6.1.4.1.11.2.17.19.3.4.0.10",
  "1.3.6.1.4.1.11.2.17.5.2.0.79",
  "1.3.6.1.4.1.11.2.17.19.3.4.0.4",
  "1.3.6.1.4.1.11150.3.4.0.1",
  "1.3.6.1.4.1.11.2.17.19.3.4.0.1",
  "1.3.6.1.4.1.11150.3.4.0"
].map(OID.init)

for id in ids.sorted() {
  print(id)
}


# Example input data:
set oid_list [list \
                  1.3.6.1.4.1.11.2.17.19.3.4.0.10 \
                  1.3.6.1.4.1.11.2.17.5.2.0.79 \
                  1.3.6.1.4.1.11.2.17.19.3.4.0.4 \
                  1.3.6.1.4.1.11150.3.4.0.1 \
                  1.3.6.1.4.1.11.2.17.19.3.4.0.1 \
                  1.3.6.1.4.1.11150.3.4.0 ]
set oid2_lists [list ]
set dots_max 0
set i 0
foreach oid $oid_list {
    set oid_list [split $oid "."]
    set dot_count [llength $oid_list]
    incr dot_count -1
    if { $dot_count > $dots_max } {
        set dots_max $dot_count
    }
    set dots_arr(${i}) $dot_count
    lappend oid2_lists $oid_list
    incr i
}
# pad for strings of different dot counts
set oid3_lists [list]
for {set ii 0} {$ii < $i} {incr ii} {
    set oid_list [lindex $oid2_lists $ii]
    set add_fields [expr { $dots_max - $dots_arr(${ii}) } ]
    if { $add_fields > 0 } {
        for {set j 0} {$j < $add_fields} {incr j} {
            lappend oid_list -1
        }
    }
    lappend oid3_lists $oid_list
}
for {set n $dots_max} {$n >= 0 } {incr n -1} {
    set oid3_lists [lsort -integer -index $n -increasing $oid3_lists]
}
# unpad strings of different dot counts
set oid4_lists [list]
for {set ii 0} {$ii < $i} {incr ii} {
    set oid_list [lindex $oid3_lists $ii]
    set j [lsearch -exact -integer $oid_list -1]
    if { $j > -1 } {
        set oid2_list [lrange $oid_list 0 ${j}-1]
        lappend oid4_lists $oid2_list
    } else {
        lappend oid4_lists $oid_list
    }
}
foreach oid_list $oid4_lists {
    puts [join $oid_list "."]
}


' Sort a list of object identifiers - VBScript
function myCompare(x,y)
	dim i,b
	sx=split(x,".")
	sy=split(y,".")
	b=false
	for i=0 to ubound(sx)
		if i > ubound(sy) then b=true: exit for
		select case sgn(int(sx(i))-int(sy(i)))
			case  1: b=true:  exit for
			case -1: b=false: exit for
		end select
	next
	myCompare=b
end function

function bubbleSort(t)
	dim i,n
	n=ubound(t)
	do
		changed=false
		n= n-1
		for i=0 to n
			if myCompare(t(i),t(i+1)) then
				tmp=t(i): t(i)=t(i+1): t(i+1)=tmp
				changed=true
			end if
		next
	loop until not changed
	bubbleSort=t
end function

a=array( _
	"1.3.6.1.4.1.11.2.17.19.3.4.0.10", _
	"1.3.6.1.4.1.11.2.17.5.2.0.79", _
	"1.3.6.1.4.1.11.2.17.19.3.4.0.4", _
	"1.3.6.1.4.1.11150.3.4.0.1", _
	"1.3.6.1.4.1.11.2.17.19.3.4.0.1", _
	"1.3.6.1.4.1.11150.3.4.0")
bubbleSort a
wscript.echo join(a,vbCrlf)


t = {4, 5, 2}
table.sort(t)
print(unpack(t))


a = [4,3,7,-2,9,1]; b = sort(a)     % b contains elements of a in ascending order
[b,idx] = sort(a)                   % b contains a(idx)


fcn sortOIDS(oids){  // oids is not modified, a new list is created
   // pad each oid with a terminal (-1) so zip won't short cut
   oids=oids.pump(List(),fcn(oid){ (oid + ".-1").split(".").apply("toInt") });
   oids.sort(  // in place sort
      fcn(a,b){ // a & b are (x,y,z,...-1), eg (0,4,2,54,-1), (4,6,-1)
	 a.zip(b).reduce(fcn(_,[(a,b)]){  // if one list longer, zip truncates
	    if(a==b) return(True);	 // continue to next field
	    return(Void.Stop,a<b);	// OIDa<OIDb == cmp this field
	 },True);
      });
   oids.pump(List,fcn(list){ list[0,-1].concat(".") }) // back to strings
}


:- module sort_int_list.
:- interface.
:- import_module io.

:- pred main(io::di, uo::uo) is det.

:- implementation.
:- import_module list.

main(!IO) :-
  Nums = [2, 4, 0, 3, 1, 2],
  list.sort(Nums, Sorted),
  io.write(Sorted, !IO),
  io.nl(!IO).


MODULE ArraySort EXPORTS Main;

IMPORT IntArraySort;

VAR arr := ARRAY [1..10] OF INTEGER{3, 6, 1, 2, 10, 7, 9, 4, 8, 5};

BEGIN
  IntArraySort.Sort(arr);
END ArraySort.


SORTARRAY(X,SEP)
 ;X is the list of items to sort
 ;X1 is the temporary array
 ;SEP is the separator string between items in the list X
 ;Y is the returned list
 ;This routine uses the inherent sorting of the arrays
 NEW I,X1,Y
 SET Y=""
 FOR I=1:1:$LENGTH(X,SEP) SET X1($PIECE(X,SEP,I))=""
 SET I="" FOR  SET I=$O(X1(I)) Q:I=""  SET Y=$SELECT($L(Y)=0:I,1:Y_SEP_I)
 KILL I,X1
 QUIT Y


/**
 <doc>
Sort integer array, in Neko

Array sort function modified from Haxe codegen with -D neko-source

The Neko target emits support code for Haxe basics, sort is included

Tectonics:
prompt$ nekoc sort.neko
prompt$ neko sort

 </doc>
**/

var sort = function(a) {
    var i = 0;
    var len = $asize(a);
    while ( i < len ) {
        var swap = false;
        var j = 0;
        var max = (len - i) - 1;
        while ( j < max ) {
            if ( (a[j] - a[j + 1]) > 0 ) {
                var tmp = a[j + 1];
                a[j + 1] = a[j];
                a[j] = tmp;
                swap = true;
            }
            j += 1;
        }
        if ( $not(swap) )
            break;;
        i += 1;
    }
    return a;
}

var arr = $array(5,3,2,1,4)
$print(arr, "\n")

/* Sorts in place */
sort(arr)
$print(arr, "\n")

/* Also returns the sorted array for chaining */
$print(sort($array(3,1,4,1,5,9,2,6,5,3,5,8)), "\n")


using System.Console;

module IntSort
{
    Main() : void
    {
        def nums = [1, 5, 3, 7, 2, 8, 3, 9];
        def sorted = nums.Sort((x, y) => x.CompareTo(y));

        WriteLine(nums);
        WriteLine(sorted);
    }
}


/* NetRexx */
options replace format comments java crossref savelog symbols binary

ia = int[]
ia = [ 2, 4, 3, 1, 2, -1, 0, -2 ]

display(ia)
Arrays.sort(ia)
display(ia)

-- Display results
method display(in = int[]) public static

  sorted = Rexx('')

  loop ix = 0 for in.length
    sorted = sorted || Rexx(in[ix]).right(4)
    end ix

  say sorted.strip('t')

  return


import algorithm

var a: array[0..8, int] = [2, 3, 5, 8, 4, 1, 6, 9, 7]
a.sort(Ascending)
for x in a:
  echo x


bundle Default {
  class Sort {
    function : Main(args : System.String[]) ~ Nil {
      nums := Structure.IntVector->New([2,4,3,1,2]);
      nums->Sort();
    }
  }
}


NSArray *nums = @[@2, @4, @3, @1, @2];
NSArray *sorted = [nums sortedArrayUsingSelector:@selector(compare:)];


let nums = [|2; 4; 3; 1; 2|]
Array.sort compare nums


a = .array~of(4, 1, 6, -2, 99, -12)
say "The sorted numbers are"
say a~sortWith(.numericComparator~new)~makeString


#include <order/interpreter.h>

ORDER_PP( 8seq_sort(8less, 8seq(2, 4, 3, 1, 2)) )


declare
  Nums = [2 4 3 1 2]
  Sorted = {List.sort Nums Value.'<'}
in
  {Show Sorted}


Construct a list of numbers
<@ LETCNSLSTLIT>L|65^84^1^25^77^4^47^2^42^44^41^25^69^3^51^45^4^39^</@>
Numbers sort as strings
<@ ACTSRTENTLST>L</@>
<@ SAYDMPLST>L</@>
<@ ACTSRTENTLSTLIT>L|__StringDescending</@>
<@ SAYDMPLST>L</@>

Construct another list of numbers
<@ LETCNSLSTLIT>list|65^84^1^25^77^4^47^2^42^44^41^25^69^3^51^45^4^39^</@>
Numbers sorted as numbers
<@ ACTSRTENTLSTLIT>list|__Numeric</@>
<@ SAYDMPLST>list</@>
<@ ACTSRTENTLSTLIT>list|__NumericDescending</@>
<@ SAYDMPLST>list</@>


include ..\Utilitys.pmt

( 9 10 3 1 4 5 8 7 6 2 ) sort print


DCL (T(10)) FIXED BIN(31); /* scratch space of length N/2 */

MERGE: PROCEDURE (A,LA,B,LB,C);
   DECLARE (A(*),B(*),C(*)) FIXED BIN(31);
   DECLARE (LA,LB) FIXED BIN(31) NONASGN;
   DECLARE (I,J,K) FIXED BIN(31);

   I=1; J=1; K=1;
   DO WHILE ((I <= LA) & (J <= LB));
      IF(A(I) <= B(J)) THEN
         DO; C(K)=A(I); K=K+1; I=I+1; END;
      ELSE
         DO; C(K)=B(J); K=K+1; J=J+1; END;
   END;
   DO WHILE (I <= LA);
      C(K)=A(I); I=I+1; K=K+1;
   END;
   RETURN;
END MERGE;

MERGESORT: PROCEDURE (A,N) RECURSIVE ;
     DECLARE (A(*))               FIXED BINARY(31);
     DECLARE N                    FIXED BINARY(31) NONASGN;
     DECLARE Temp                 FIXED BINARY;
     DECLARE (M,I)                FIXED BINARY;
     DECLARE AMP1(N)              FIXED BINARY(31) BASED(P);
     DECLARE P POINTER;
    IF (N=1) THEN RETURN;
   M = trunc((N+1)/2);
   IF (M>1) THEN CALL MERGESORT(A,M);
   P=ADDR(A(M+1));
   IF (N-M > 1) THEN CALL MERGESORT(AMP1,N-M);
   IF A(M) <= AMP1(1) THEN RETURN;
   DO I=1 to M; T(I)=A(I); END;
   CALL MERGE(T,M,AMP1,N-M,A);
   RETURN;
END MERGESORT;


T Employee
   String name, category

   F (name, category)
      .name = name
      .category = category

V employees = [
   Employee(‘David’, ‘Manager’),
   Employee(‘Alice’, ‘Sales’),
   Employee(‘Joanna’, ‘Director’),
   Employee(‘Henry’, ‘Admin’),
   Employee(‘Tim’, ‘Sales’),
   Employee(‘Juan’, ‘Admin’)
]

employees.sort(key' e -> e.name)

L(e) employees
   print(‘#<6 : #.’.format(e.name, e.category))


lvars ar = {2 4 3 1 2};
;;; Convert array to list.
;;; destvector leaves its results and on the pop11 stack + an integer saying how many there were
destvector(ar);
;;; conslist uses the items left on the stack plus the integer, to make a list of those items.
lvars ls = conslist();
;;; Sort it
sort(ls) -> ls;
;;; Convert list to array
destlist(ls);
consvector() -> ar;


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program shellSort64.s   */

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

/*******************************************/
/* Structures                               */
/********************************************/
/* city structure      */
    .struct  0
city_name:                             //
    .struct  city_name + 8             // string pointer
city_habitants:                        //
    .struct  city_habitants + 8        // integer
city_end:

/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz "Name : @  number habitants : @ \n"
szMessSortHab:      .asciz "Sort table for number of habitants :\n"
szMessSortName:     .asciz "Sort table for name of city :\n"
szCarriageReturn:   .asciz "\n"

// cities name
szCeret:           .asciz "Ceret"
szMaureillas:      .asciz "Maureillas"
szTaillet:         .asciz "Taillet"
szReynes:          .asciz "Reynes"
szVives:           .asciz "Vivés"
szBoulou:          .asciz "Le Boulou"
szSaintJean:       .asciz "Saint Jean Pla de Corts"
szCluses:          .asciz "Les Cluses"
szAlbere:          .asciz "L'Albère"
szPerthus:         .asciz "Le Perthus"

.align 4
TableCities:
                 .quad szCluses         // address name string
                 .quad 251              // number of habitants
                 .quad szCeret
                 .quad 7705
                 .quad szMaureillas
                 .quad 2596
                 .quad szBoulou
                 .quad 5554
                 .quad szSaintJean
                 .quad 2153
                 .quad szAlbere
                 .quad 83
                 .quad szVives
                 .quad 174
                 .quad szTaillet
                 .quad 115
                 .quad szPerthus
                 .quad 586
                 .quad szReynes
                 .quad 1354
.equ NBELEMENTS,  (. - TableCities) / city_end
                 .skip city_end         // temp area for element in shellSort
                                        // see other soluce to use stack
                                        // in programm arm assembly in this forum
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:              .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                             // entry of program

    ldr x0,qAdrszMessSortHab
    bl affichageMess

    ldr x0,qAdrTableCities        // address table
    mov x1,0                      // not use in routine
    mov x2,NBELEMENTS             // number of élements
    mov x3,#city_habitants        // sort by number habitants
    mov x4,#'N'                   // numeric
    bl shellSort
    ldr x0,qAdrTableCities        // address table
    bl displayTable

     ldr x0,qAdrszMessSortName
    bl affichageMess

    ldr x0,qAdrTableCities        // address table
    mov x1,0                      // not use in routine
    mov x2,NBELEMENTS             // number of élements
    mov x3,#city_name             // sort by city name
    mov x4,#'A'                   // alphanumeric
    bl shellSort
    ldr x0,qAdrTableCities        // address table
    bl displayTable

100:                              // standard end of the program
    mov x0,0                      // return code
    mov x8,EXIT                   // request to exit program
    svc 0                         // perform the system call

qAdrsZoneConv:            .quad sZoneConv
qAdrszCarriageReturn:     .quad szCarriageReturn
qAdrsMessResult:          .quad sMessResult
qAdrTableCities:          .quad TableCities
qAdrszMessSortHab:        .quad szMessSortHab
qAdrszMessSortName:        .quad szMessSortName
/***************************************************/
/*   shell Sort                                    */
/***************************************************/
/* x0 contains the address of table */
/* x1 contains the first element but not use !!   */
/*   this routine use first element at index zero !!!  */
/* x2 contains the number of element */
/* x3 contains the offset of sort zone */
/* x4 contains type of sort zone N = numeric A = alphanumeric */
shellSort:
    stp x1,lr,[sp,-16]!          // save  registers
    stp x2,x3,[sp,-16]!          // save  registers
    stp x4,x5,[sp,-16]!          // save  registers
    stp x6,x7,[sp,-16]!          // save  registers
    stp x8,x9,[sp,-16]!          // save  registers
    stp x10,x11,[sp,-16]!          // save  registers
    stp x12,x13,[sp,-16]!          // save  registers
    mov x8,x3                    // save offset area sort
    mov x9,x4                    // save type sort
    mov x7,city_end              // element size
    sub x12,x2,1                 // index last item
    mov x11,x12                  // init gap = last item
1:                               // start loop 1
    lsr x11,x11,1                // gap = gap / 2
    cbz x11,100f                 // if gap = 0 -> end
    mov x3,x11                   // init loop indice 1
2:                               // start loop 2
    mul x1,x3,x7                 // offset élement
    mov x2,NBELEMENTS
    mul x2,x7,x2
    bl copyElement
    add x1,x1,x8                 // + offset sort zone
    ldr x4,[x0,x1]               // load first value
    mov x5,x3                    // init loop indice 2
3:                               // start loop 3
    cmp x5,x11                   // indice < gap
    blt 7f                       // yes -> end loop 2
    sub x6,x5,x11                // index = indice - gap
    mul x1,x6,x7                 // compute offset
    add x10,x1,x8                // + offset sort zone
    ldr x2,[x0,x10]              // load second value
    cmp x9,#'A'                  // sort area alapha ?
    beq 4f                       // yes
    cmp x4,x2                    //  else compare numeric values
    bge 7f                       // highter
    b 6f                         // lower
4:                               // compare area alphanumeric
    mov x10,#0                   // counter
5:
    ldrb w13,[x4,x10]            // byte string 1
    ldrb w6,[x2,x10]             // byte string 2
    cmp w13,w6
    bgt 7f
    blt 6f

    cmp w13,#0                   //  end string 1
    beq 7f                       // end comparaison
    add x10,x10,#1               // else add 1 in counter
    b 5b                         // and loop

6:
    mul x2,x5,x7                 // offset élement
    bl copyElement               // copy element x1 to element x2
    sub x5,x5,x11                // indice = indice - gap
    b 3b                         // and loop
7:
    mov x1,NBELEMENTS
    mul x1,x7,x1
    mul x2,x7,x5
    bl copyElement
    add x3,x3,1                  // increment indice 1
    cmp x3,x12                   // end ?
    ble 2b                       // no -> loop 2
    b 1b                         // yes loop for new gap

100:                             // end function
    ldp x12,x13,[sp],16          // restaur  2 registers
    ldp x10,x11,[sp],16          // restaur  2 registers
    ldp x8,x9,[sp],16            // restaur  2 registers
    ldp x6,x7,[sp],16            // restaur  2 registers
    ldp x4,x5,[sp],16            // restaur  2 registers
    ldp x2,x3,[sp],16            // restaur  2 registers
    ldp x1,lr,[sp],16            // restaur  2 registers
    ret                          // return to address lr x30

/******************************************************************/
/*      copy table element                                */
/******************************************************************/
/* r0 contains the address of table */
/* r1 offset origin element */
/* r2 offset destination element */
copyElement:
    stp x1,lr,[sp,-16]!          // save  registers
    stp x2,x3,[sp,-16]!          // save  registers
    stp x4,x5,[sp,-16]!          // save  registers
    mov x3,0
    add x1,x1,x0
    add x2,x2,x0
1:
    ldrb w4,[x1,x3]
    strb w4,[x2,x3]
    add x3,x3,1
    cmp x3,city_end
    blt 1b
100:
    ldp x4,x5,[sp],16            // restaur  2 registers
    ldp x2,x3,[sp],16            // restaur  2 registers
    ldp x1,lr,[sp],16            // restaur  2 registers
    ret                          // return to address lr x30
/******************************************************************/
/*      Display table elements                                */
/******************************************************************/
/* x0 contains the address of table */
displayTable:
    stp x1,lr,[sp,-16]!          // save  registers
    stp x2,x3,[sp,-16]!          // save  registers
    stp x4,x5,[sp,-16]!          // save  registers
    stp x6,x7,[sp,-16]!          // save  registers
    mov x2,x0                    // table address
    mov x3,0
    mov x6,city_end
1:                               // loop display table
    mul x4,x3,x6
    add x4,x4,city_name
    ldr x1,[x2,x4]
    ldr x0,qAdrsMessResult
    bl strInsertAtCharInc        // put name in message
    mov x5,x0                     // save address of new message
    mul x4,x3,x6
    add x4,x4,city_habitants       // and load value
    ldr x0,[x2,x4]
    ldr x1,qAdrsZoneConv         // display value
    bl conversion10              // call function
    mov x0,x5
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc        // insert result at @ character
    bl affichageMess             // display message
    add x3,x3,1
    cmp x3,#NBELEMENTS - 1
    ble 1b
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
100:
    ldp x6,x7,[sp],16            // restaur  2 registers
    ldp x4,x5,[sp],16            // restaur  2 registers
    ldp x2,x3,[sp],16            // restaur  2 registers
    ldp x1,lr,[sp],16            // restaur  2 registers
    ret                          // return to address lr x30
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


(defun insert-by-key (o os key)
   (cond ((endp os) (list o))
         ((< (cdr (assoc key o))
             (cdr (assoc key (first os))))
          (cons o os))
         (t (cons (first os)
                  (insert-by-key o (rest os) key)))))

(defun isort-by-key (os key)
   (if (endp os)
       nil
       (insert-by-key (first os)
                      (isort-by-key (rest os) key)
                      key)))

(isort-by-key
 '(((name  . "map")
   (weight . 9)
   (value  . 150))
  ((name   . "compass")
   (weight . 13)
   (value  . 35))
  ((name   . "water")
   (weight . 153)
   (value  . 200))
  ((name   . "sandwich")
   (weight . 50)
   (value  . 60))
  ((name   . "glucose")
   (weight . 15)
   (value  . 60)))
 'value)


DEFINE PTR="CARD"
DEFINE PAIR_SIZE="4"
DEFINE PAIR_COUNT="1"

TYPE Pair=[PTR name,value]

BYTE ARRAY pairs(100)
BYTE count=[0]

PTR FUNC GetItemAddr(INT index)
  PTR addr

  addr=pairs+index*PAIR_SIZE
RETURN (addr)

PROC PrintArray()
  INT i
  Pair POINTER p

  Put('[)
  FOR i=0 TO count-1
  DO
    IF i>0 THEN Put(' ) FI
    p=GetItemAddr(i)
    PrintF("(%S,%S)",p.name,p.value)
  OD
  Put(']) PutE()
RETURN

PROC Append(CHAR ARRAY n,v)
  Pair POINTER dst

  dst=GetItemAddr(count)
  dst.name=n
  dst.value=v
  count==+1
RETURN

PROC InitData()
  Append("Warsaw","Poland")
  Append("Prague","Czech Republic")
  Append("London","United Kingdom")
  Append("Paris","France")
  Append("Madrit","Spain")
  Append("Berlin","Germany")
  Append("Rome","Italy")
  Append("Moscow","Russia")
  Append("Budapest","Hungary")
RETURN

PROC Sort()
  INT i,j,minpos
  CHAR ARRAY tmp
  Pair POINTER p1,p2

  FOR i=0 TO count-2
  DO
    minpos=i
    FOR j=i+1 TO count-1
    DO
      p1=GetItemAddr(minpos)
      p2=GetItemAddr(j)
      IF SCompare(p1.name,p2.name)>0 THEN
        minpos=j
      FI
    OD

    IF minpos#i THEN
      p1=GetItemAddr(minpos)
      p2=GetItemAddr(i)
      tmp=p1.name p1.name=p2.name p2.name=tmp
      tmp=p1.value p1.value=p2.value p2.value=tmp
    FI
  OD
RETURN

PROC Main()
  InitData()
  PrintE("Array before sort:")
  PrintArray() PutE()

  Sort()
  PrintE("Array after sort:")
  PrintArray()
RETURN


Dim numbers(20)
For i = 0 To 20
   numbers(i) = Random(1000)
Next

SortArray(numbers(), #PB_Sort_Ascending)


nums <- c(2,4,3,1,2)
sorted <- sort(nums)


with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO;           use Ada.Text_IO;

with Ada.Containers.Generic_Array_Sort;

procedure Demo_Array_Sort is

   function "+" (S : String) return Unbounded_String renames To_Unbounded_String;

   type A_Composite is
      record
         Name  : Unbounded_String;
         Value : Unbounded_String;
      end record;

   function "<" (L, R : A_Composite) return Boolean is
   begin
      return L.Name < R.Name;
   end "<";

   procedure Put_Line (C : A_Composite) is
   begin
      Put_Line (To_String (C.Name) & " " & To_String (C.Value));
   end Put_Line;

   type An_Array is array (Natural range <>) of A_Composite;

   procedure Sort is new Ada.Containers.Generic_Array_Sort (Natural, A_Composite, An_Array);

   Data : An_Array := (1 => (Name => +"Joe",    Value => +"5531"),
                       2 => (Name => +"Adam",   Value => +"2341"),
                       3 => (Name => +"Bernie", Value => +"122"),
                       4 => (Name => +"Walter", Value => +"1234"),
                       5 => (Name => +"David",  Value => +"19"));

begin
   Sort (Data);
   for I in Data'Range loop
      Put_Line (Data (I));
   end loop;
end Demo_Array_Sort;


MODE SORTSTRUCT = PERSON;
OP < = (PERSON a,b)BOOL: age OF a < age OF b;
PR READ "prelude/sort.a68" PR;

MODE PERSON = STRUCT (STRING name, INT age);
FORMAT person repr = $"Name: "g", Age: "g(0)l$;

[]SORTSTRUCT person = (("joe", 120), ("foo", 31), ("bar", 51));
printf((person repr, shell sort(person), $l$))


rascal>import List;
ok

rascal>a = [1, 4, 2, 3, 5];
list[int]: [1,4,2,3,5]

rascal>sort(a)
list[int]: [1,2,3,4,5]

rascal>sort(a, bool(int a, int b){return a >= b;})
list[int]: [5,4,3,2,1]


use framework "Foundation"

----- SORTING COMPOSITE STRUCTURES (BY MULTIPLE KEYS) ------

-- List of {strKey, blnAscending} pairs -> list of records -> sorted list of records

-- sortByComparing :: [(String, Bool)] -> [Record] -> [Record]
on sortByComparing(keyDirections, xs)
    set ca to current application

    script recDict
        on |λ|(x)
            ca's NSDictionary's dictionaryWithDictionary:x
        end |λ|
    end script
    set dcts to map(recDict, xs)

    script asDescriptor
        on |λ|(kd)
            set {k, d} to kd
            ca's NSSortDescriptor's sortDescriptorWithKey:k ascending:d selector:dcts
        end |λ|
    end script

    ((ca's NSArray's arrayWithArray:dcts)'s ¬
        sortedArrayUsingDescriptors:map(asDescriptor, keyDirections)) as list
end sortByComparing

--------------------------- TEST ---------------------------
on run
    set xs to [¬
        {city:"Shanghai ", pop:24.2}, ¬
        {city:"Karachi ", pop:23.5}, ¬
        {city:"Beijing ", pop:21.5}, ¬
        {city:"Sao Paulo ", pop:24.2}, ¬
        {city:"Dhaka ", pop:17.0}, ¬
        {city:"Delhi ", pop:16.8}, ¬
        {city:"Lagos ", pop:16.1}]

    -- Boolean true for ascending order, false for descending:

    sortByComparing([{"pop", false}, {"city", true}], xs)
end run

-------------------- GENERIC FUNCTIONS ---------------------

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


/* ARM assembly Raspberry PI  */
/*  program compositeSort.s   */

/* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

/*******************************************/
/* Structures                               */
/********************************************/
/* city structure      */
    .struct  0
city_name:                             @
    .struct  city_name + 4
city_habitants:                             @
    .struct  city_habitants + 4
city_end:
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz "Name : @  number habitants : @ \n"
szMessSortHab:      .asciz "Sort table for number of habitants :\n"
szMessSortName:     .asciz "Sort table for name of city :\n"
szCarriageReturn:   .asciz "\n"

// cities name
szCeret:           .asciz "Ceret"
szMaureillas:      .asciz "Maureillas"
szTaillet:         .asciz "Taillet"
szReynes:          .asciz "Reynes"
szVives:           .asciz "Vivés"
szBoulou:          .asciz "Le Boulou"
szSaintJean:       .asciz "Saint Jean Pla de Corts"
szCluses:          .asciz "Les Cluses"
szAlbere:          .asciz "L'Albère"
szPerthus:         .asciz "Le Perthus"
.align 4

TableCities:
                 .int szCluses         @ address name string
                 .int 251              @ number of habitants
                 .int szCeret
                 .int 7705
                 .int szMaureillas
                 .int 2596
                 .int szBoulou
                 .int 5554
                 .int szSaintJean
                 .int 2153
                 .int szAlbere
                 .int 83
                 .int szVives
                 .int 174
                 .int szTaillet
                 .int 115
                 .int szPerthus
                 .int 586
                 .int szReynes
                 .int 1354
.equ NBELEMENTS,  (. - TableCities) / city_end
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:        .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                                             @ entry of program

    ldr r0,iAdrszMessSortHab
    bl affichageMess

    ldr r0,iAdrTableCities                        @ address city table
    mov r1,#0                                     @ not use in routine
    mov r2,#NBELEMENTS                            @ number of élements
    mov r3,#city_habitants                        @ sort by number habitants
    mov r4,#'N'                                   @ Alphanumeric
    bl shellSort
    ldr r0,iAdrTableCities                        @ address number table
    bl displayTable

    ldr r0,iAdrszMessSortName
    bl affichageMess

    ldr r0,iAdrTableCities                        @ address city table
    mov r1,#0                                     @ not use in routine
    mov r2,#NBELEMENTS                            @ number of élements
    mov r3,#city_name                             @ sort by name
    mov r4,#'A'                                   @ Alphanumeric
    bl shellSort
    ldr r0,iAdrTableCities                        @ address number table
    bl displayTable

100:                                              @ standard end of the program
    mov r0, #0                                    @ return code
    mov r7, #EXIT                                 @ request to exit program
    svc #0                                        @ perform the system call

iAdrszCarriageReturn:     .int szCarriageReturn
iAdrsMessResult:          .int sMessResult
iAdrTableCities:          .int TableCities
iAdrszMessSortHab:        .int szMessSortHab
iAdrszMessSortName:       .int szMessSortName
/***************************************************/
/*   shell Sort                                    */
/***************************************************/

/* r0 contains the address of table */
/* r1 contains the first element but not use !!   */
/*   this routine use first element at index zero !!!  */
/* r2 contains the number of element */
/* r3 contains the offset of sort zone */
/* r4 contains type of sort zone N = numeric A = alphanumeric */
shellSort:
    push {r0-r12,lr}             @ save registers
    sub sp,#city_end             @ reserve area on stack
    mov fp,sp                    @ frame pointer = stack
    mov r8,r3                    @ save offser area sort
    mov r9,r4                    @ save type sort
    mov r7,#city_end             @ element size
    //vidregtit debut
    sub r12,r2,#1                @ index last item
    mov r6,r12                   @ init gap = last item
1:                               @ start loop 1
    lsrs r6,#1                   @ gap = gap / 2
    beq 100f                     @ if gap = 0 -> end
    mov r3,r6                    @ init loop indice 1
2:                               @ start loop 2
    mul r1,r3,r7                 @ offset élement
    mov r2,fp                    @ save on stack
    bl saveElement
    add r1,r8                    @ + offset sort zone
    ldr r4,[r0,r1]               @ load first value
    mov r5,r3                    @ init loop indice 2
3:                               @ start loop 3
    cmp r5,r6                    @ indice < gap
    blt 8f                       @ yes -> end loop 2
    sub r10,r5,r6                @ index = indice - gap
    mul r1,r10,r7                @ offset élement
    add r10,r1,r8                @ + offset sort zone
    ldr r2,[r0,r10]              @ load second value
    push {r3,r5}                 @ save registrars because not enought register
    cmp r9,#'A'                  @ sort area alapha ?
    beq 4f                       @ yes
    cmp r4,r2                    @  else compare numeric values
    bge 7f                       @ highter
    b 6f                         @ lower
4:                               @ compare area alphanumeric
    mov r10,#0                   @ counter
5:
    ldrb r3,[r4,r10]             @ byte string 1
    ldrb r5,[r2,r10]             @ byte string 2
    cmp r3,r5
    bgt 7f
    blt 6f

    cmp r3,#0                    @  end string 1
    beq 7f                       @ ens comparaison
    add r10,r10,#1               @ else add 1 in counter
    b 5b                         @ and loop

6:
    pop {r3,r5}                  @ restaur registers
    mul r2,r5,r7                 @ offset élement
    bl copyElement               @ copy element r1 to element r2
    sub r5,r6                    @ indice = indice - gap
    b 3b                         @ and loop
7:
    pop {r3,r5}
8:                               @ end loop 3
    mul r1,r5,r7                 @ offset destination élement
    mov r2,fp                    @ restaur element in table
    bl restaurElement
    add r3,#1                    @ increment indice 1
    cmp r3,r12                   @ end ?
    ble 2b                       @ no -> loop 2
    b 1b                         @ yes loop for new gap

100:                             @ end function
    add sp,#city_end
    pop {r0-r12,lr}              @ restaur registers
    bx lr                        @ return
/******************************************************************/
/*      copy table element                                */
/******************************************************************/
/* r0 contains the address of table */
/* r1 offset origin element */
/* r2 offset destination element */
copyElement:
    push {r0-r4,lr}                                    @ save registers
    //vidregtit copy
    mov r3,#0
    add r1,r0
    add r2,r0
1:
    ldrb r4,[r1,r3]
    strb r4,[r2,r3]
    add r3,#1
    cmp r3,#city_end
    blt 1b
100:
    pop {r0-r4,lr}
    bx lr
/******************************************************************/
/*      save element                                */
/******************************************************************/
/* r0 contains the address of table */
/* r1 offset origin element */
/* r2 address destination  */
saveElement:
    push {r0-r4,lr}                                    @ save registers
    mov r3,#0
    add r1,r0
1:
    ldrb r4,[r1,r3]
    strb r4,[r2,r3]
    add r3,#1
    cmp r3,#city_end
    blt 1b
100:
    pop {r0-r4,lr}
    bx lr
/******************************************************************/
/*      restaur element                                */
/******************************************************************/
/* r0 contains the address of table */
/* r1 offset destination element */
/* r2 address origine  */
restaurElement:
    push {r0-r4,lr}                                    @ save registers
    mov r3,#0
    add r1,r0
1:
    ldrb r4,[r2,r3]
    strb r4,[r1,r3]
    add r3,#1
    cmp r3,#city_end
    blt 1b
100:
    pop {r0-r4,lr}
    bx lr
/******************************************************************/
/*      Display table elements                                */
/******************************************************************/
/* r0 contains the address of table */
displayTable:
    push {r0-r6,lr}              @ save registers
    mov r2,r0                    @ table address
    mov r3,#0
    mov r6,#city_end
1:                               @ loop display table
    mul r4,r3,r6
    add r4,#city_name
    ldr r1,[r2,r4]
    ldr r0,iAdrsMessResult
    bl strInsertAtCharInc        @ put name in message
    mov r5,r0                    @ save address of new message
    mul r4,r3,r6
    add r4,#city_habitants       @ and load value
    ldr r0,[r2,r4]
    ldr r1,iAdrsZoneConv
    bl conversion10              @ call decimal conversion
    mov r0,r5
    ldr r1,iAdrsZoneConv         @ insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess             @ display message
    add r3,#1
    cmp r3,#NBELEMENTS - 1
    ble 1b
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
100:
    pop {r0-r6,lr}
    bx lr
iAdrsZoneConv:      .int sZoneConv

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"


/*REXX program sorts an array (using E─sort), in this case, the array contains integers.*/
numeric digits 30                                /*enables handling larger Euler numbers*/
                          @.  =              0;            @.1 =               1
                          @.3 =             -1;            @.5 =               5
                          @.7 =            -61;            @.9 =            1385
                          @.11=         -50521;            @.13=         2702765
                          @.15=     -199360981;            @.17=     19391512145
                          @.19= -2404879675441;            @.21= 370371188237525
#= 21                                            /*indicate there're  21 Euler  numbers.*/
call tell  'unsorted'                            /*display the array before the  eSort. */
call eSort     #                                 /*sort the array of some Euler numbers.*/
call tell  '  sorted'                            /*display the array  after  the eSort. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
eSort: procedure expose @.;   parse arg N;     h=N                   /*an eXchange sort.*/
              do  while h>1;                   h= h%2                /*define a segment.*/
                 do i=1  for N-h;              j=i;     k= h+i       /*sort top segment.*/
                    do  while  @.k<@.j                               /*see if need swap.*/
                        parse value  @.j @.k   with   @.k @.j        /*swap two elements*/
                        if h>=j  then leave;   j= j-h;   k= k-h      /*this part sorted?*/
                        end   /*while @.k<@.j*/
                    end       /*i*/
              end             /*while h>1*/
       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
tell:  say copies('─', 65);       _= left('',9);                       w= length(#)
              do j=1  for #;  say _ arg(1)  'array element'   right(j, w)"="right(@.j, 20)
              end   /*j*/
       return


start:
Gui, Add, ListView, r20 w200, 1|2
data =
(
foo,53
joe,34
bar,23
)

Loop, parse, data, `n
{
  stringsplit, row, A_LoopField, `,
  LV_Add(row, row1, row2)
}
LV_ModifyCol()  ; Auto-size columns
Gui, Show
msgbox, sorting by column1
LV_ModifyCol(1, "sort") ; sort by first column
msgbox, sorting by column2
LV_ModifyCol(2, "sort Integer") ; sort by second column numerically
return

GuiClose:
ExitApp


# syntax: GAWK -f SORT_AN_ARRAY_OF_COMPOSITE_STRUCTURES.AWK
BEGIN {
# AWK lacks structures but one can be simulated using an associative array.
    arr["eight  8 "]
    arr["two    2 "]
    arr["five   5 "]
    arr["nine   9 "]
    arr["one    1 "]
    arr["three  3 "]
    arr["six    6 "]
    arr["seven  7 "]
    arr["four   4 "]
    arr["ten    10"]
    arr["zero   0 "]
    arr["twelve 12"]
    arr["minus2 -2"]
    show(1,7,"@val_str_asc","name") # use name part of name-value pair
    show(8,9,"@val_num_asc","value") # use value part of name-value pair
    exit(0)
}
function show(a,b,sequence,description,  i,x) {
    PROCINFO["sorted_in"] = "@unsorted"
    for (i in arr) {
      x = substr(i,a,b)
      sub(/ +/,"",x)
      arr[i] = x
    }
    PROCINFO["sorted_in"] = sequence
    printf("sorted by %s:",description)
    for (i in arr) {
      printf(" %s",arr[i])
    }
    printf("\n")
}


nums = [2,4,3,1,2]
sorted = nums.sort      # returns a new sorted array.  'nums' is unchanged
p sorted                #=> [1, 2, 2, 3, 4]
p nums                  #=> [2, 4, 3, 1, 2]

nums.sort!              # sort 'nums' "in-place"
p nums                  #=> [1, 2, 2, 3, 4]


class MAIN is
   main is
      arr: ARRAY{INT} := |4, 6, 7, 2, 1, 0, 100, 21, 34|;
      #OUT+"unsorted: " + arr + "\n";

      -- sort in place:
      arr.sort;

      #OUT+"  sorted: " + arr + "\n";
   end;
end;


babel> baz ([map "foo" 3 "bar" 17] [map "foo" 4 "bar" 18] [map "foo" 5 "bar" 19] [map "foo" 0 "bar" 20]) <
babel> bop baz { <- "foo" lumap ! -> "foo" lumap ! lt? } lssort ! <
babel> bop {"foo" lumap !} over ! lsnum !
( 0 3 4 5 )


      INSTALL @lib$+"SORTSALIB"
      sort% = FN_sortSAinit(0,0)

      DIM pair{name$, number%}
      DIM array{(10)} = pair{}
      FOR i% = 1 TO DIM(array{()}, 1)
        READ array{(i%)}.name$, array{(i%)}.number%
      NEXT

      DATA "Eight", 8, "Two", 2, "Five", 5, "Nine", 9, "One", 1
      DATA "Three", 3, "Six", 6, "Seven", 7, "Four", 4, "Ten", 10

      C% = DIM(array{()}, 1)
      D% = 1
      CALL sort%, array{()}, array{(0)}.number%, array{(0)}.name$

      FOR i% = 1 TO DIM(array{()}, 1)
        PRINT array{(i%)}.name$, array{(i%)}.number%
      NEXT


( (tab=("C++",1979)+(Ada,1983)+(Ruby,1995)+(Eiffel,1985))
& out$"unsorted array:"
& lst$tab
& out$("sorted array:" !tab \n)
& out$"But tab is still unsorted:"
& lst$tab
);


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

typedef struct twoStringsStruct {
    char * key, *value;
} sTwoStrings;

int ord( char v )
{
    static char *dgts = "012345679";
    char *cp;
    for (cp=dgts; v != *cp; cp++);
    return (cp-dgts);
}

int cmprStrgs(const sTwoStrings *s1,const sTwoStrings *s2)
{
    char *p1 = s1->key;
    char *p2 = s2->key;
    char *mrk1, *mrk2;
    while ((tolower(*p1) == tolower(*p2)) && *p1) { p1++; p2++;}
    if (isdigit(*p1) && isdigit(*p2)) {
        long v1, v2;
        if ((*p1 == '0') ||(*p2 == '0')) {
            while (p1 > s1->key) {
                p1--; p2--;
                if (*p1 != '0') break;
            }
            if (!isdigit(*p1)) {
                p1++; p2++;
            }
        }
        mrk1 = p1; mrk2 = p2;
        v1 = 0;
        while(isdigit(*p1)) {
            v1 = 10*v1+ord(*p1);
            p1++;
        }
        v2 = 0;
        while(isdigit(*p2)) {
            v2 = 10*v2+ord(*p2);
            p2++;
        }
        if (v1 == v2)
           return(p2-mrk2)-(p1-mrk1);
        return v1 - v2;
    }
    if (tolower(*p1) != tolower(*p2))
       return (tolower(*p1) - tolower(*p2));
    for(p1=s1->key, p2=s2->key; (*p1 == *p2) && *p1; p1++, p2++);
    return (*p1 -*p2);
}

int maxstrlen( char *a, char *b)
{
	int la = strlen(a);
	int lb = strlen(b);
	return (la>lb)? la : lb;
}

int main()
{
    sTwoStrings toBsorted[] = {
        { "Beta11a", "many" },
        { "alpha1", "This" },
        { "Betamax", "sorted." },
        { "beta3", "order" },
        { "beta11a", "strings" },
        { "beta001", "is" },
        { "beta11", "which" },
        { "beta041", "be" },
        { "beta05", "in" },
        { "beta1", "the" },
        { "beta40", "should" },
    };
#define ASIZE (sizeof(toBsorted)/sizeof(sTwoStrings))
    int k, maxlens[ASIZE];
    char format[12];
    sTwoStrings *cp;

    qsort( (void*)toBsorted, ASIZE, sizeof(sTwoStrings),cmprStrgs);

    for (k=0,cp=toBsorted; k < ASIZE; k++,cp++) {
        maxlens[k] = maxstrlen(cp->key, cp->value);
        sprintf(format," %%-%ds", maxlens[k]);
        printf(format, toBsorted[k].value);
	}
    printf("\n");
    for (k=0; k < ASIZE; k++) {
        sprintf(format," %%-%ds", maxlens[k]);
        printf(format, toBsorted[k].key);
	}
    printf("\n");

  return 0;
}


import scala.compat.Platform

object Sort_an_integer_array extends App {
  val array = Array((for (i <- 0 to 10) yield scala.util.Random.nextInt()):
    _* /*Sequence is passed as multiple parameters to Array(xs : T*)*/)

  /** Function test the array if it is in order */
  def isSorted[T](arr: Array[T]) = array.sliding(2).forall(pair => pair(0) <= pair(1))

  assert(!isSorted(array), "Not random")
  scala.util.Sorting.quickSort(array)
  assert(isSorted(array), "Not sorted")

  println(s"Array in sorted order.\nSuccessfully completed without errors. [total ${Platform.currentTime - executionStart} ms]")
}


using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    struct Entry
    {
        public Entry(string name, double value) { Name = name; Value = value; }
        public string Name;
        public double Value;
    }

    static void Main(string[] args)
    {
        var Elements = new List<Entry>
        {
            new Entry("Krypton", 83.798), new Entry("Beryllium", 9.012182), new Entry("Silicon", 28.0855),
            new Entry("Cobalt", 58.933195), new Entry("Selenium", 78.96), new Entry("Germanium", 72.64)
        };

        var sortedElements = Elements.OrderBy(e => e.Name);

        foreach (Entry e in sortedElements)
            Console.WriteLine("{0,-11}{1}", e.Name, e.Value);
    }
}


var array integer: nums is [] (2, 4, 3, 1, 2);

nums := sort(nums);


var nums = [2,4,3,1,2];
var sorted = nums.sort;  # returns a new sorted array.
nums.sort!;              # sort 'nums' "in-place"


;; Gathered with Google Squared
(def *langs* [["Clojure" 2007] ["Common Lisp" 1984] ["Java" 1995] ["Haskell" 1990]
              ["Lisp" 1958] ["Scheme" 1975]])

user> (sort-by second *langs*) ; using a keyfn

(["Lisp" 1958] ["Scheme" 1975] ["Common Lisp" 1984] ["Haskell" 1990] ["Java" 1995] ["Clojure" 2007])


CL-USER> (defparameter *test-scores* '(("texas" 68.9) ("ohio" 87.8) ("california" 76.2) ("new york" 88.2)) )
*TEST-SCORES*


import std.stdio, std.algorithm;

struct Pair { string name, value; }

void main() {
    Pair[] pairs = [{"Joe",    "5531"},
                    {"Adam",   "2341"},
                    {"Bernie",  "122"},
                    {"Walter", "1234"},
                    {"David",    "19"}];

    pairs.schwartzSort!q{ a.name }.writeln;
}


- val nums = Array.fromList [2, 4, 3, 1, 2];
val nums = [|2,4,3,1,2|] : int array
- ArrayQSort.sort Int.compare nums;
val it = () : unit
- nums;
val it = [|1,2,2,3,4|] : int array


var nums = [2, 4, 3, 1, 2]
nums.sortInPlace()
print(nums)


set result [lsort -integer $unsorted_list]


program SortCompositeStructures;

{$APPTYPE CONSOLE}

uses SysUtils, Generics.Collections, Generics.Defaults;

type
  TStructurePair = record
    name: string;
    value: string;
    constructor Create(const aName, aValue: string);
  end;

constructor TStructurePair.Create(const aName, aValue: string);
begin
  name := aName;
  value := aValue;
end;

var
  lArray: array of TStructurePair;
begin
  SetLength(lArray, 3);
  lArray[0] := TStructurePair.Create('dog', 'rex');
  lArray[1] := TStructurePair.Create('cat', 'simba');
  lArray[2] := TStructurePair.Create('horse', 'trigger');

  TArray.Sort<TStructurePair>(lArray , TDelegatedComparer<TStructurePair>.Construct(
  function(const Left, Right: TStructurePair): Integer
  begin
    Result := CompareText(Left.Name, Right.Name);
  end));
end.


def compareBy(keyfn) { # This ought to be in the standard library
  return def comparer(a, b) {
    return keyfn(a).op__cmp(keyfn(b))
  }
}

def x := [
  ["Joe",3],
  ["Bill",4],
  ["Alice",20],
  ["Harry",3],
]

println(x.sort(compareBy(fn [name,_] { name })))


needs bsort
arrayname number_elements bsort


nums="2 4 3 1 5"
sorted=`printf "%s\n" $nums | sort -n`
echo $sorted  # prints 1 2 3 4 5


decl int<> nums
append 2 4 3 1 2 nums
sort nums


;; sorting (name value) by name - Ignoring case
(define (name a) (first a))
(define( sort-proc a b)
    (string-ci<? (name a) (name b)))

(define people
   '(("😎" -42) ("albert" 33) ("Simone" 44) ("Antoinette" 42) ("elvis" 666) ("😃" 1000)))

(list-sort sort-proc people)
   → (("albert" 33) ("Antoinette" 42) ("elvis" 666) ("Simone" 44) ("😃" 1000) ("😎" -42))


import system'routines;
import extensions;

public program()
{
    var elements := new object[]{
            KeyValue.new("Krypton", 83.798r),
            KeyValue.new("Beryllium", 9.012182r),
            KeyValue.new("Silicon", 28.0855r),
            KeyValue.new("Cobalt", 58.933195r),
            KeyValue.new("Selenium", 78.96r),
            KeyValue.new("Germanium", 72.64r)};

    var sorted := elements.sort:(former,later => former.Key < later.Key );

    sorted.forEach:(element)
    {
         console.printLine(element.Key," - ",element)
    }
}


defmodule Person do
  defstruct name: "", value: 0
end

list = [struct(Person, [name: "Joe", value: 3]),
        struct(Person, [name: "Bill", value: 4]),
        struct(Person, [name: "Alice", value: 20]),
        struct(Person, [name: "Harry", value: 3])]

Enum.sort(list) |> Enum.each(fn x -> IO.inspect x end)
IO.puts ""
Enum.sort_by(list, &(&1.value)) |> Enum.each(&IO.inspect &1)


import "/sort" for Sort

var a = [7, 10, 2, 4, 6, 1, 8, 3, 9, 5]
Sort.quick(a)
System.print(a)


include c:\cxpl\codes;          \intrinsic 'code' declarations

proc    SSort(A, N);            \Shell sort array in ascending order
int     A;                      \address of array
int     N;                      \number of elements in array (size)
int     I, J, Gap, JG, T;
[Gap:= N>>1;
while Gap > 0 do
        [for I:= Gap to N-1 do
                [J:= I - Gap;
                loop    [JG:= J + Gap;
                        if A(J) <= A(JG) then quit;
                        T:= A(J);   A(J):= A(JG);   A(JG):= T;  \swap elements
                        J:= J - Gap;
                        if J < 0 then quit;
                        ];
                ];
        Gap:= Gap>>1;
        ];
];      \SSort

int A, I;
[A:= [3, 1, 4, 1, 5, 9, 2, 6, 5, 4];
SSort(A, 10);
for I:= 0 to 10-1 do [IntOut(0, A(I));  ChOut(0, ^ )];
CrLf(0);
]


export sub shell_sort(x())
// Shell sort based on insertion sort

   local gap, i, j, first, last, tempi, tempj

   last = arraysize(x(),1)
   gap = int(last / 10) + 1
   while(TRUE)
	first = gap + 1
	for i = first to last
	   	tempi = x(i)
	    	j = i - gap
	    	while(TRUE)
			tempj = x(j)
			if tempi >= tempj then
		    		j = j + gap
		    		break
			end if
			x(j+gap) = tempj
			if j <= gap then
		    		break
			end if
			j = j - gap
	    	wend
	    	x(j) = tempi
	next i
	if gap = 1 then
	   	return
	else
	   	gap = int(gap / 3.5) + 1
	end if
   wend
end sub

if peek$("library") = "main" then

	clear screen

	ITEMS = 100
	dim numeros(ITEMS)

	for n = 1 to ITEMS
		numeros(n) = ran(ITEMS + 1)
	next n

	print time$
	shell_sort(numeros())
	print time$
	print "Press a key to see ordered numbers."
	inkey$

	for n = 1 to ITEMS
		print numeros(n),", ";
	next n

end if


nums = [2,4,3,1,2];
nums = nums(sort(nums));


include sort.e
include misc.e

constant NAME = 1
function compare_names(sequence a, sequence b)
    return compare(a[NAME],b[NAME])
end function

sequence s
s = { { "grass",  "green" },
      { "snow",   "white" },
      { "sky",    "blue"  },
      { "cherry", "red"   } }

pretty_print(1,custom_sort(routine_id("compare_names"),s),{2})


program: sort_integer_array
  input: [2,4,3,1]
  output: [1,2,3,4]


let persons = [| ("Joe", 120); ("foo", 31); ("bar", 51) |]
Array.sortInPlaceBy fst persons
printfn "%A" persons


TUPLE: example-pair name value ;

: sort-by-name ( seq -- seq' ) [ [ name>> ] compare ] sort ;


class Pair // create a composite structure
{
  Str name
  Str value
  new make (Str name, Str value)
  {
    this.name = name
    this.value = value
  }

  override Str toStr ()
  {
    "(Pair: $name, $value)"
  }
}

class Main
{
  public static Void main ()
  {
    // samples
    pairs := [Pair("Fantom", "OO"), Pair("Clojure", "Functional"), Pair("Java", "OO") ]

    sorted := pairs.dup // make a copy of original list
    sorted.sort |Pair a, Pair b -> Int|  // sort using custom comparator
    {
      a.name <=> b.name
    }
    echo ("Started with : " + pairs.join(" "))
    echo ("Finished with: " + sorted.join(" "))
  }
}


PROGRAM EXAMPLE
  IMPLICIT NONE

  TYPE Pair
    CHARACTER(6) :: name
    CHARACTER(1) :: value
  END TYPE Pair

  TYPE(Pair) :: rcc(10), temp
  INTEGER :: i, j

  rcc(1) = Pair("Black", "0")
  rcc(2) = Pair("Brown", "1")
  rcc(3) = Pair("Red", "2")
  rcc(4) = Pair("Orange", "3")
  rcc(5) = Pair("Yellow", "4")
  rcc(6) = Pair("Green", "5")
  rcc(7) = Pair("Blue", "6")
  rcc(8) = Pair("Violet", "7")
  rcc(9) = Pair("Grey", "8")
  rcc(10) = Pair("White", "9")

  DO i = 2, SIZE(rcc)
     j = i - 1
     temp = rcc(i)
        DO WHILE (j>=1 .AND. LGT(rcc(j)%name, temp%name))
           rcc(j+1) = rcc(j)
           j = j - 1
        END DO
     rcc(j+1) = temp
  END DO

  WRITE (*,"(2A6)") rcc

END PROGRAM EXAMPLE


' FB 1.05.0 Win64

Type Pair
  As String name, value
  Declare Constructor(name_ As String, value_ As String)
  Declare Operator Cast() As String
End Type

Constructor Pair(name_ As String, value_ As String)
  name  = name_
  value = value_
End Constructor

Operator Pair.Cast() As String
  Return "[" + name + ", " + value + "]"
End Operator

' selection sort, quick enough for sorting small number of pairs
Sub sortPairsByName(p() As Pair)
  Dim As Integer i, j, m
  For i = LBound(p) To UBound(p) - 1
    m = i
    For j = i + 1 To UBound(p)
      If p(j).name < p(m).name Then m = j
    Next j
    If m <> i Then Swap p(i), p(m)
  Next i
End Sub

Dim As Pair pairs(1 To 4) = _
{ _
  Pair("grass", "green"), _
  Pair("snow", "white" ), _
  Pair("sky", "blue"),    _
  Pair("cherry", "red")   _
}

Print "Before sorting :"
For i As Integer = 1 To 4
  Print Tab(3); pairs(i)
Next

sortPairsByName pairs()

Print
Print "After sorting by name :"
For i As Integer = 1 To 4
  Print Tab(3); pairs(i)
Next

Print
Print "Press any key to quit"
Sleep


class Pair
{
   var name
   var value

   new[name is string, value is string] :=
   {
      this.name = name
      this.value = value
   }
}

a = [new Pair["one", "1"], new Pair["two", "2"], new Pair["three", "3"]]
sort[a, {|a,b| lexicalCompare[a.name, b.name]}]


package main

import (
    "fmt"
    "sort"
)

type pair struct {
    name, value string
}
type csArray []pair

// three methods satisfy sort.Interface
func (a csArray) Less(i, j int) bool { return a[i].name < a[j].name }
func (a csArray) Len() int           { return len(a) }
func (a csArray) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

var x = csArray{
    pair{"joe", "120"},
    pair{"foo", "31"},
    pair{"bar", "251"},
}

func main() {
    sort.Sort(x)
    for _, p := range x {
        fmt.Printf("%5s: %s\n", p.name, p.value)
    }
}


class Holiday {
    def date
    def name
    Holiday(dateStr, name) { this.name = name; this.date = format.parse(dateStr) }
    String toString() { "${format.format date}: ${name}" }
    static format = new java.text.SimpleDateFormat("yyyy-MM-dd")
}

def holidays = [ new Holiday("2009-12-25", "Christmas Day"),
                 new Holiday("2009-04-22", "Earth Day"),
                 new Holiday("2009-09-07", "Labor Day"),
                 new Holiday("2009-07-04", "Independence Day"),
                 new Holiday("2009-10-31", "Halloween"),
                 new Holiday("2009-05-25", "Memorial Day"),
                 new Holiday("2009-03-14", "PI Day"),
                 new Holiday("2009-01-01", "New Year's Day"),
                 new Holiday("2009-12-31", "New Year's Eve"),
                 new Holiday("2009-11-26", "Thanksgiving"),
                 new Holiday("2009-02-14", "St. Valentine's Day"),
                 new Holiday("2009-03-17", "St. Patrick's Day"),
                 new Holiday("2009-01-19", "Martin Luther King Day"),
                 new Holiday("2009-02-16", "President's Day") ]

holidays.sort { x, y -> x.date <=> y.date }
holidays.each { println it }


import Data.List
import Data.Function (on)

data Person =
  P String
    Int
  deriving (Eq)

instance Show Person where
  show (P name val) = "Person " ++ name ++ " with value " ++ show val

instance Ord Person where
  compare (P a _) (P b _) = compare a b

pVal :: Person -> Int
pVal (P _ x) = x

people :: [Person]
people = [P "Joe" 12, P "Bob" 8, P "Alice" 9, P "Harry" 2]

main :: IO ()
main = do
  mapM_ print $ sort people
  putStrLn []
  mapM_ print $ sortBy (on compare pVal) people


record star(name,HIP)

procedure main()

Ori := [ star("Betelgeuse",27989),
         star("Rigel",24436),
         star("Belatrix", 25336),
         star("Alnilam",26311) ]

write("Some Orion stars by HIP#")
every write( (x := !sortf(Ori,2)).name, " HIP ",x.HIP)
end


   names =: ;: 'Perlis Wilkes Hamming Minsky Wilkinson McCarthy'
   values=: ;: 'Alan Maurice Richard Marvin James John'
   pairs =: values ,. names
   pairs /: names
+-------+---------+
|Richard|Hamming  |
+-------+---------+
|John   |McCarthy |
+-------+---------+
|Marvin |Minsky   |
+-------+---------+
|Alan   |Perlis   |
+-------+---------+
|Maurice|Wilkes   |
+-------+---------+
|James  |Wilkinson|
+-------+---------+


import java.util.Arrays;
import java.util.Comparator;

public class SortComp {
    public static class Pair {
        public String name;
        public String value;
        public Pair(String n, String v) {
            name = n;
            value = v;
        }
    }

    public static void main(String[] args) {
        Pair[] pairs = {new Pair("06-07", "Ducks"), new Pair("00-01", "Avalanche"),
            new Pair("02-03", "Devils"), new Pair("01-02", "Red Wings"),
            new Pair("03-04", "Lightning"), new Pair("04-05", "lockout"),
            new Pair("05-06", "Hurricanes"), new Pair("99-00", "Devils"),
            new Pair("07-08", "Red Wings"), new Pair("08-09", "Penguins")};

        sortByName(pairs);
        for (Pair p : pairs) {
            System.out.println(p.name + " " + p.value);
        }
    }

    public static void sortByName(Pair[] pairs) {
        Arrays.sort(pairs, new Comparator<Pair>() {
            public int compare(Pair p1, Pair p2) {
                return p1.name.compareTo(p2.name);
            }
        });
    }
}


var arr = [
  {id: 3, value: "foo"},
  {id: 2, value: "bar"},
  {id: 4, value: "baz"},
  {id: 1, value: 42},
  {id: 5, something: "another string"} // Works with any object declaring 'id' as a number.
];
arr = arr.sort(function(a, b) {return a.id - b.id}); // Sort with comparator checking the id.


def example:
 [
  {"name": "Joe", "value": 3},
  {"name": "Bill", "value": 4},
  {"name": "Alice", "value": 20},
  {"name": "Harry", "value": 3}
 ];


lst = Pair[Pair("gold", "shiny"),
           Pair("neon", "inert"),
           Pair("sulphur", "yellow"),
           Pair("iron", "magnetic"),
           Pair("zebra", "striped"),
           Pair("star", "brilliant"),
           Pair("apple", "tasty"),
           Pair("ruby", "red"),
           Pair("dice", "random"),
           Pair("coffee", "stimulating"),
           Pair("book", "interesting")]

println("The original list: \n - ", join(lst, "\n - "))
sort!(lst; by=first)
println("\nThe list, sorted by name: \n - ", join(lst, "\n - "))
sort!(lst; by=last)
println("\nThe list, sorted by value: \n - ", join(lst, "\n - "))


// version 1.1

data class Employee(val name: String, var category: String) : Comparable<Employee> {
    override fun compareTo(other: Employee) = this.name.compareTo(other.name)
}

fun main(args: Array<String>) {
    val employees = arrayOf(
        Employee("David", "Manager"),
        Employee("Alice", "Sales"),
        Employee("Joanna", "Director"),
        Employee("Henry", "Admin"),
        Employee("Tim", "Sales"),
        Employee("Juan", "Admin")
    )
    employees.sort()
    for ((name, category) in employees) println("${name.padEnd(6)} : $category")
}


{def H.sort
 {def H.sort.i
  {lambda {:f :x :a}
   {if {A.empty? :a}
    then {A.new :x}
    else {if {:f :x {A.first :a}}
    then {A.addfirst! :x :a}
    else {A.addfirst! {A.first :a} {H.sort.i :f :x {A.rest :a}}} }}}}
 {def H.sort.r
  {lambda {:f :a1 :a2}
   {if {A.empty? :a1}
    then :a2
    else {H.sort.r :f {A.rest :a1} {H.sort.i :f {A.first :a1} :a2}} }}}
 {lambda {:f :a}
  {H.sort.r :f :a {A.new}} }}
-> H.sort

{def H.display
 {lambda {:h}
  {table
   {tr {S.map {{lambda {:h :i} {td {car {A.get :i :h}}}} :h}
              {S.serie 0 {- {A.length :h} 1}}}}
   {tr {S.map {{lambda {:h :i} {td {cdr {A.get :i :h}}}} :h}
              {S.serie 0 {- {A.length :h} 1}}}}
}}}
-> H.display

1) an array of pairs:
{def H {A.new {cons Joe 5531}
              {cons Adam 2341}
              {cons Bernie 122}
              {cons Walter 1234}
              {cons David 19}}}
-> H

2) display sorted by names:
{H.display
 {H.sort {lambda {:a :b} {< {lexicographic {car :a} {car :b}} 0}} {H}}}
->
Adam 	Bernie 	David 	Joe 	Walter
 2341 	122 	19 	5531 	1234

3) display sorted by values:
{H.display
 {H.sort {lambda {:a :b} {< {cdr :a} {cdr :b}}} {H}}}
->
David 	Bernie 	Walter 	Adam 	Joe
 19 	122 	1234 	2341 	5531


N =20
dim IntArray$( N, 2)

print "Original order"
for i =1 to N
    name$ =mid$( "SortArrayOfCompositeStructures", int( 25 *rnd( 1)), 1 +int( 4 *rnd( 1)))
    IntArray$( i, 1) =name$
    print name$,
    t$ =str$( int( 1000 *rnd( 1)))
    IntArray$( i, 2) =t$
    print t$
next i

sort IntArray$(), 1, N, 1
print "Sorted by name"  ' (  we specified column 1)
for i =1 to N
    print IntArray$( i, 1), IntArray$( i, 2)
next i


function sorting( a, b )
    return a[1] < b[1]
end

tab = { {"C++", 1979}, {"Ada", 1983}, {"Ruby", 1995}, {"Eiffel", 1985} }

table.sort( tab, sorting )
for _, v in ipairs( tab ) do
    print( unpack(v) )
end


Module CheckIt {
      Flush ' empty stack of values
      Class Quick {
      Private:
            partition=lambda-> {
                  Read &A(), p, r : i = p-1 : x=A(r)
                  For j=p to r-1 {If .LE(A(j), x) Then i++:Swap A(i),A(j)
                  } : Swap A(i+1), A(r) :  Push  i+2, i
            }
      Public:
            LE=Lambda->Number<=Number
            Module ForStrings {
                  .partition<=lambda-> {
                        Read &a$(), p, r : i = p-1 : x$=a$(r)
                        For j=p to r-1 {If a$(j)<= x$ Then i++:Swap a$(i),a$(j)
                        } : Swap a$(i+1), a$(r) : Push i+2, i
                  }
            }
            Function quicksort {
                 Read ref$
                 {
                         loop : If Stackitem() >= Stackitem(2) Then Drop 2 : if  empty then {Break} else continue
                         over 2,2 : call .partition(ref$) :shift 3
                 }
            }
      }
      Quick=Quick()
      Quick.LE=lambda (a, b)->{
            =a.name$<=b.name$
      }
      Data "Joe",   5531
      Data "Adam", 2341
      Data "Bernie", 122
      Data "Walter", 1234
      Data "David",  19
      Class pair {
            name$
            value_
      }
      Document Doc$={Unsorted Pairs:
      }
      Dim A(1 to 5)=pair()
      For i=1 to 5 {
            For A(i) {
                  Read .name$, .value_
                  Doc$=Format$("{0}, {1}", .name$, .value_)+{
                  }
            }
      }

      Call Quick.quicksort(&A(),1, 5)
      Doc$={
            Sorted Pairs
            }
      k=Each(A())
      While k {
            getone=array(k)
            For getone {
                              Doc$=Format$("{0}, {1}", .name$, .value_)+{
                              }
            }
      }
      Report Doc$
      Clipboard Doc$
}
Checkit
module Checkit2 {
      Inventory Alfa="Joe":=5531, "Adam":=2341, "Bernie":=122
      Append Alfa, "Walter":=1234, "David":=19
      Sort Alfa
      k=Each(Alfa)
      While k {
            Print eval$(Alfa, k^), Eval(k)
      }
}
Checkit2
module Checkit3 {
      class any {
             x
            class:
            Module any (.x) {}
      }
      Inventory Alfa="Joe":=any(5531), "Adam":=any(2341), "Bernie":=any(122)
      Append Alfa, "Walter":=any(1234), "David":=any(19)
      Sort Alfa
      k=Each(Alfa)
      While k {
            \\ k^ is the index number by k cursor
            \\ Alfa("joe") return object
            \\ Alfa(0!) return first element object
            \\ Alfa(k^!) return (k^) objext
            Print eval$(Alfa, k^),  Alfa(k^!).x
      }
}
Checkit3


fn keyCmp comp1 comp2 =
(
    case of
    (
        (comp1[1] > comp2[1]):	1
        (comp1[1] < comp2[1]):	-1
        default:		0
    )
)

people = #(#("joe", 39), #("dave", 37), #("bob", 42))
qsort people keyCmp
print people


/* NetRexx */
options replace format comments java crossref symbols nobinary

-- =============================================================================
class RSortCompsiteStructure public

  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  method main(args = String[]) public static
    places = [ -
      PairBean('London',     'UK'), PairBean('New York',   'US') -
    , PairBean('Boston',     'US'), PairBean('Washington', 'US') -
    , PairBean('Washington', 'UK'), PairBean("Birmingham", 'US') -
    , PairBean("Birmingham", 'UK'), PairBean("Boston",     'UK') -
    ]
    say displayArray(places)
    Arrays.sort(places, PairComparator())
    say displayArray(places)
    return

  method displayArray(harry = PairBean[]) constant
    disp = ''
    loop elmt over harry
      disp = disp','elmt
      end elmt
    return '['disp.substr(2)']' -- trim leading comma

-- =============================================================================
class RSortCompsiteStructure.PairBean
  properties indirect
    name
    value
  method PairBean(name_, value_) public
    setName(name_)
    setValue(value_)
    return
  method toString() public returns String
    return '('getName()','getValue()')'

-- =============================================================================
class RSortCompsiteStructure.PairComparator implements Comparator
  method compare(lft = Object, rgt = Object) public binary returns int
    cRes = int
    if lft <= RSortCompsiteStructure.PairBean, rgt <= RSortCompsiteStructure.PairBean then do
      lName = String (RSortCompsiteStructure.PairBean lft).getName()
      rName = String (RSortCompsiteStructure.PairBean rgt).getName()
      cRes = lName.compareTo(rName)
      if cRes == 0 then do
        lVal = String (RSortCompsiteStructure.PairBean lft).getValue()
        rVal = String (RSortCompsiteStructure.PairBean rgt).getValue()
        cRes = lVal.compareTo(rVal)
        end
      end
    else signal IllegalArgumentException('Arguments must be of type PairBean')
    return cRes


import algorithm, sugar

var people = @{"joe": 120, "foo": 31, "bar": 51}
sort(people, (x,y) => cmp(x[0], y[0]))
echo people


use Collection;

class Entry implements Compare {
  @name : String;
  @value : Float;

  New(name : String, value : Float) {
    @name := name;
    @value := value;
  }

  method : public : Compare(rhs : Compare) ~ Int  {
    return @name->Compare(rhs->As(Entry)->GetName());
  }

  method : public : GetName() ~ String {
    return @name;
  }

  method : public : HashID() ~ Int {
    return @name->HashID();
  }

  method : public : ToString() ~ String {
    return "name={[email protected]}, value={[email protected]}";
  }
}

class Sorter {
  function : Main(args : String[]) ~ Nil {
    entries := CompareVector->New();
    entries->AddBack(Entry->New("Krypton", 83.798));
    entries->AddBack(Entry->New("Beryllium", 9.012182));
    entries->AddBack(Entry->New("Silicon", 28.0855));
    entries->AddBack(Entry->New("Cobalt", 58.933195));
    entries->AddBack(Entry->New("Selenium", 78.96));
    entries->AddBack(Entry->New("Germanium", 72.64));

    entries->Sort();
    each(i : entries) {
      entries->Get(i)->As(Entry)->ToString()->PrintLine();
    };
  }
}


@interface Pair : NSObject {
    NSString *name;
    NSString *value;
}
+(instancetype)pairWithName:(NSString *)n value:(NSString *)v;
-(instancetype)initWithName:(NSString *)n value:(NSString *)v;
-(NSString *)name;
-(NSString *)value;
@end

@implementation Pair
+(instancetype)pairWithName:(NSString *)n value:(NSString *)v {
    return [[self alloc] initWithName:n value:v];
}
-(instancetype)initWithName:(NSString *)n value:(NSString *)v {
    if ((self = [super init])) {
        name = n;
        value = v;
    }
    return self;
}
-(NSString *)name { return name; }
-(NSString *)value { return value; }
-(NSString *)description {
    return [NSString stringWithFormat:@"< %@ -> %@ >", name, value];
}
@end

int main() {
    @autoreleasepool {

        NSArray *pairs = @[
                       [Pair pairWithName:@"06-07" value:@"Ducks"],
                       [Pair pairWithName:@"00-01" value:@"Avalanche"],
                       [Pair pairWithName:@"02-03" value:@"Devils"],
                       [Pair pairWithName:@"01-02" value:@"Red Wings"],
                       [Pair pairWithName:@"03-04" value:@"Lightning"],
                       [Pair pairWithName:@"04-05" value:@"lockout"],
                       [Pair pairWithName:@"05-06" value:@"Hurricanes"],
                       [Pair pairWithName:@"99-00" value:@"Devils"],
                       [Pair pairWithName:@"07-08" value:@"Red Wings"],
                       [Pair pairWithName:@"08-09" value:@"Penguins"]];

        // optional 3rd arg: you can also specify a selector to compare the keys
        NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

        // it takes an array of sort descriptors, and it will be ordered by the
        // first one, then if it's a tie by the second one, etc.
        NSArray *sorted = [pairs sortedArrayUsingDescriptors:@[sd]];
        NSLog(@"%@", sorted);

    }

    return 0;
}


# let people = [("Joe", 12); ("Bob", 8); ("Alice", 9); ("Harry", 2)];;
val people : (string * int) list =
  [("Joe", 12); ("Bob", 8); ("Alice", 9); ("Harry", 2)]
# let sortedPeopleByVal = List.sort (fun (_, v1) (_, v2) -> compare v1 v2) people;;
val sortedPeopleByVal : (string * int) list =
  [("Harry", 2); ("Bob", 8); ("Alice", 9); ("Joe", 12)]


(import (scheme char))

(define (comp a b)
   (string-ci<? (a 'name #f) (b 'name #f)))

(for-each print
   (sort comp (list
      { 'name "David"
        'value "Manager" }
      { 'name "Alice"
        'value "Sales" }
      { 'name "Joanna"
        'value "Director" }
      { 'name "Henry"
        'value "Admin" }
      { 'name "Tim"
        'value "Sales" }
      { 'name "Juan"
        'value "Admin" })))


a = .array~new

a~append(.pair~new("06-07", "Ducks"))
a~append(.pair~new("00-01", "Avalanche"))
a~append(.pair~new("02-03", "Devils"))
a~append(.pair~new("01-02", "Red Wings"))
a~append(.pair~new("03-04", "Lightning"))
a~append(.pair~new("04-05", "lockout"))
a~append(.pair~new("05-06", "Hurricanes"))
a~append(.pair~new("99-00", "Devils"))
a~append(.pair~new("07-08", "Red Wings"))
a~append(.pair~new("08-09", "Penguins"))

b = a~copy   -- make a copy before sorting
b~sort
say "Sorted using direct comparison"
do pair over b
   say pair
end

c = a~copy
-- this uses a custom comparator instead
c~sortWith(.paircomparator~new)
say
say "Sorted using a comparator (inverted)"
do pair over c
   say pair
end

-- a name/value mapping class that directly support the sort comparisons
::class pair inherit comparable
::method init
  expose name value
  use strict arg name, value

::attribute name
::attribute value

::method string
  expose name value
  return name "=" value

-- the compareto method is a requirement brought in
-- by the
::method compareto
  expose name
  use strict arg other
  return name~compareto(other~name)

-- a comparator that shows an alternate way of sorting
::class pairComparator subclass comparator
::method compare
  use strict arg left, right
  -- perform the comparison on the names
  return -left~name~compareTo(right~name)


declare
  People = [person(name:joe value:3)
            person(name:bill value:4)
            person(name:alice value:20)
            person(name:harry value:3)]

  SortedPeople = {Sort People
                  fun {$ P1 P2}
                     P1.name < P2.name
                  end
                 }
in
  {ForAll SortedPeople Show}


vecsort([["name", "value"],["name2", "value2"]], 1, 2)


sequence s = {{"grass","green"},{"snow","white"},{"sky","blue"},{"cherry","red"},{0,1.2},{3.4,-1}}

?sort(s)
function compare_col2(sequence a, b) return compare(a[2],b[2]) end function
?custom_sort(compare_col2,s)
?sort_columns(s,{2})    -- 0.8.0+, same result as above w/o needing an explicit comparison routine


include ..\Utilitys.pmt

def minverse
    reverse
enddef

getid minverse var f

( ( "grass" "green" ) ( "snow" "white" ) ( "sky" "blue" ) ( "cherry" "red" ) ( 0 1.2 ) ( 3.4 -1 ) )
dup

sort print nl

/# sorted by second component #/
f map sort f map print


$list = @{
"def" = "one"
"abc" = "two"
"jkl" = "three"
"abcdef" = "four"
"ghi" = "five"
"ghijkl" = "six"
 }
 $list.GetEnumerator() | sort {-($PSItem.Name).length}, Name


Structure MyPair ; Define a structured data type
  Name$
  Value.i
EndStructure

Dim People.MyPair(2)             ; Allocate some elements

People(0)\Name$ = "John"         ; Start filling them in
People(0)\Value = 100

People(1)\Name$ = "Emma"
People(1)\Value = 200

People(2)\Name$ = "Johnny"
People(2)\Value = 175

If OpenConsole()
  Define i
  ; Sort ascending by name
  SortStructuredArray(People(), #PB_Sort_Ascending, OffsetOf(MyPair\Name$), #PB_Sort_String)
  PrintN(#CRLF$+"Sorted ascending by name.")
  For i=0 To 2
    PrintN(People(i)\Name$+" - Value: "+Str(People(i)\Value))
  Next
  ; Sort descending by value
  SortStructuredArray(People(), #PB_Sort_Descending, OffsetOf(MyPair\Value), #PB_Sort_Integer)
  PrintN(#CRLF$+"Sorted descending by value.")
  For i=0 To 2
    PrintN(People(i)\Name$+" - Value: "+Str(People(i)\Value))
  Next
  ; Wait for user...
  PrintN(#CRLF$+"Press ENTER to exit"):Input()
EndIf


sortbyname <- function(x, ...) x[order(names(x), ...)]
x <- c(texas=68.9, ohio=87.8, california=76.2, "new york"=88.2)
sortbyname(x)


#lang racket

(define data '([Joe 5531] [Adam 2341] [Bernie 122] [Walter 1234] [David 19]))

(sort data < #:key cadr)
;; --> '((David 19) (Bernie 122) (Walter 1234) (Adam 2341) (Joe 5531))

;; Demonstrating a "key" that is not just a direct element
(sort data string<? #:key (compose1 symbol->string car))
;; --> '((Adam 2341) (Bernie 122) (David 19) (Joe 5531) (Walter 1234))


my class Employee {
   has Str $.name;
   has Rat $.wage;
}

my $boss     = Employee.new( name => "Frank Myers"     , wage => 6755.85 );
my $driver   = Employee.new( name => "Aaron Fast"      , wage => 2530.40 );
my $worker   = Employee.new( name => "John Dude"       , wage => 2200.00 );
my $salesman = Employee.new( name => "Frank Mileeater" , wage => 4590.12 );

my @team = $boss, $driver, $worker, $salesman;

my @orderedByName = @team.sort( *.name )».name;
my @orderedByWage = @team.sort( *.wage )».name;

say "Team ordered by name (ascending order):";
say @orderedByName.join('  ');
say "Team ordered by wage (ascending order):";
say @orderedByWage.join('  ');


/*REXX program  sorts an array of composite structures  (which has two classes of data).*/
#=0                                              /*number elements in structure (so far)*/
name='tan'   ;  value= 0;  call add name,value   /*tan    peanut M&M's are  0%  of total*/
name='orange';  value=10;  call add name,value   /*orange    "    "     "  10%   "   "  */
name='yellow';  value=20;  call add name,value   /*yellow    "    "     "  20%   "   "  */
name='green' ;  value=20;  call add name,value   /*green     "    "     "  20%   "   "  */
name='red'   ;  value=20;  call add name,value   /*red       "    "     "  20%   "   "  */
name='brown' ;  value=30;  call add name,value   /*brown     "    "     "  30%   "   "  */
call show  'before sort',  #
say  copies('▒', 70)
call xSort                 #
call show  ' after sort',  #
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
add:   procedure expose # @.;   #=#+1            /*bump the number of structure entries.*/
       @.#.color=arg(1);      @.#.pc=arg(2)      /*construct a entry of the structure.  */
       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show:  procedure expose @.;   do j=1  for arg(2) /*2nd arg≡number of structure elements.*/
                              say right(arg(1),30)  right(@.j.color,9)  right(@.j.pc,4)'%'
                              end   /*j*/        /* [↑]  display  what,  name,  value.  */
       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
xSort: procedure expose @.; parse arg N;    h=N
                              do while h>1;                       h=h%2
                                do i=1  for N-h;        j=i;      k=h+i
                                  do  while @.k.color<@.j.color         /*swap elements.*/
                                  [email protected].j.color;        @.j.[email protected].k.color;     @.k.color=_
                                  [email protected].j.pc;           @.j.pc   [email protected].k.pc;        @.k.pc   =_
                                  if h>=j  then leave;    j=j-h;    k=k-h
                                  end   /*while @.k.color ···*/
                                end     /*i*/
                              end       /*while h>1*/
       return


aList= sort([:Eight = 8, :Two = 2, :Five = 5, :Nine = 9, :One = 1,
             :Three = 3, :Six = 6, :Seven = 7, :Four = 4, :Ten = 10] , 2)
for item in aList
    ? item[1] + space(10-len(item[1])) + item[2]
next


Person = Struct.new(:name,:value) do
  def to_s; "name:#{name}, value:#{value}" end
end

list = [Person.new("Joe",3),
        Person.new("Bill",4),
        Person.new("Alice",20),
        Person.new("Harry",3)]
puts list.sort_by{|x|x.name}
puts
puts list.sort_by(&:value)


sqliteconnect #mem, ":memory:"                          ' create in memory db
mem$	= "CREATE TABLE people(num integer, name text,city text)"
#mem execute(mem$)
data "1","George","Redding","2","Fred","Oregon","3","Ben","Seneca","4","Steve","Fargo","5","Frank","Houston"

for i = 1 to 5                                          ' read data and place in memory DB
 read num$ :read name$: read city$
 #mem execute("INSERT INTO people VALUES(";num$;",'";name$;"','";city$;"')")
next i
#mem execute("SELECT * FROM people ORDER BY name")      'sort by name order
WHILE  #mem hasanswer()
  #row  = #mem #nextrow()
  num   = #row num()
  name$	= #row name$()
  city$	= #row city$()
  print num;" ";name$;" ";city$
WEND


use std::cmp::Ordering;

#[derive(Debug)]
struct Employee {
    name: String,
    category: String,
}

impl Employee {
    fn new(name: &str, category: &str) -> Self {
        Employee {
            name: name.into(),
            category: category.into(),
        }
    }
}

impl PartialEq for Employee {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
    }
}

impl Eq for Employee {}

impl PartialOrd for Employee {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Employee {
    fn cmp(&self, other: &Self) -> Ordering {
        self.name.cmp(&other.name)
    }
}

fn main() {
    let mut employees = vec![
        Employee::new("David", "Manager"),
        Employee::new("Alice", "Sales"),
        Employee::new("Joanna", "Director"),
        Employee::new("Henry", "Admin"),
        Employee::new("Tim", "Sales"),
        Employee::new("Juan", "Admin"),
    ];
    employees.sort();
    for e in employees {
        println!("{:<6} : {}", e.name, e.category);
    }
}


case class Pair(name:String, value:Double)
val input = Array(Pair("Krypton", 83.798), Pair("Beryllium", 9.012182), Pair("Silicon", 28.0855))
input.sortBy(_.name) // Array(Pair(Beryllium,9.012182), Pair(Krypton,83.798), Pair(Silicon,28.0855))

// alternative versions:
input.sortBy(struct => (struct.name, struct.value)) // additional sort field (name first, then value)
input.sortWith((a,b) => a.name.compareTo(b.name) < 0) // arbitrary comparison function


$ include "seed7_05.s7i";

const type: pair is new struct
    var string: name is "";
    var string: value is "";
  end struct;

const func integer: compare (in pair: pair1, in pair: pair2) is
  return compare(pair1.name, pair2.name);

const func string: str (in pair: aPair) is
  return "(" <& aPair.name <& ", " <& aPair.value <& ")";

enable_output(pair);

const func pair: pair (in string: name, in string: value) is func
  result
    var pair: newPair is pair.value;
  begin
    newPair.name := name;
    newPair.value := value;
  end func;

var array pair: data is [] (
    pair("Joe",    "5531"),
    pair("Adam",   "2341"),
    pair("Bernie", "122"),
    pair("Walter", "1234"),
    pair("David",  "19"));

const proc: main is func
  local
    var pair: aPair is pair.value;
  begin
    data := sort(data);
    for aPair range data do
      writeln(aPair);
    end for;
  end func;


# Declare an array of pairs
var people = [['joe', 120], ['foo', 31], ['bar', 51]];

# Sort the array in-place by name
people.sort! {|a,b| a[0] <=> b[0] };

# Alternatively, we can use the `.sort_by{}` method
var sorted = people.sort_by { |item| item[0] };

# Display the sorted array
say people;


BEGIN

    CLASS COMPARABLE;;

    COMPARABLE CLASS PAIR(N,V); TEXT N,V;;

    CLASS COMPARATOR;
    VIRTUAL:
        PROCEDURE COMPARE IS
            INTEGER PROCEDURE COMPARE(A, B); REF(COMPARABLE) A, B;;
    BEGIN
    END**OF**COMPARATOR;

    COMPARATOR CLASS PAIRBYNAME;
    BEGIN
        INTEGER PROCEDURE COMPARE(A, B); REF(COMPARABLE) A, B;
        BEGIN
            COMPARE := IF A QUA PAIR.N < B QUA PAIR.N THEN -1 ELSE
                       IF A QUA PAIR.N > B QUA PAIR.N THEN +1 ELSE 0;
        END;
    END**OF**PAIRBYNAME;

    PROCEDURE BUBBLESORT(A, C); NAME A; REF(COMPARABLE) ARRAY A; REF(COMPARATOR) C;
    BEGIN
       INTEGER LOW, HIGH, I;
       BOOLEAN SWAPPED;

       PROCEDURE SWAP(I, J); INTEGER I, J;
       BEGIN
           REF(COMPARABLE) TEMP;
           TEMP :- A(I); A(I) :- A(J); A(J) :- TEMP;
       END**OF**SWAP;

       LOW := LOWERBOUND(A, 1);
       HIGH := UPPERBOUND(A, 1);
       SWAPPED := TRUE;
       WHILE SWAPPED DO
       BEGIN
           SWAPPED := FALSE;
           FOR I := LOW + 1 STEP 1 UNTIL HIGH DO
           BEGIN
               COMMENT IF THIS PAIR IS OUT OF ORDER ;
               IF C.COMPARE(A(I - 1), A(I)) > 0 THEN
               BEGIN
                   COMMENT SWAP THEM AND REMEMBER SOMETHING CHANGED ;
                   SWAP(I - 1, I);
                   SWAPPED := TRUE;
               END;
           END;
       END;
    END**OF**BUBBLESORT;

    COMMENT ** MAIN PROGRAM **;
    REF(PAIR) ARRAY A(1:5);
    INTEGER I;

    A(1) :- NEW PAIR( "JOE", "5531" );
    A(2) :- NEW PAIR( "ADAM", "2341" );
    A(3) :- NEW PAIR( "BERNIE", "122" );
    A(4) :- NEW PAIR( "WALTER", "1234" );
    A(5) :- NEW PAIR( "DAVID", "19" );

    BUBBLESORT(A, NEW PAIRBYNAME);

    FOR I:= 1 STEP 1 UNTIL 5 DO
    BEGIN OUTTEXT(A(I).N); OUTCHAR(' '); OUTTEXT(A(I).V); OUTIMAGE; END;
    OUTIMAGE;

END.


-- setup
CREATE TABLE pairs (name VARCHAR(16), VALUE VARCHAR(16));
INSERT INTO pairs VALUES ('Fluffy', 'cat');
INSERT INTO pairs VALUES ('Fido', 'dog');
INSERT INTO pairs VALUES ('Francis', 'fish');
-- order them by name
SELECT * FROM pairs ORDER BY name;


extension Sequence {
  func sorted<Value>(
    on: KeyPath<Element, Value>,
    using: (Value, Value) -> Bool
  ) -> [Element] where Value: Comparable {
    return withoutActuallyEscaping(using, do: {using -> [Element] in
      return self.sorted(by: { using($0[keyPath: on], $1[keyPath: on]) })
    })
  }
}

struct Person {
  var name: String
  var role: String
}

let a = Person(name: "alice", role: "manager")
let b = Person(name: "bob", role: "worker")
let c = Person(name: "charlie", role: "driver")

print([c, b, a].sorted(on: \.name, using: <))


set people {{joe 120} {foo 31} {bar 51}}
# sort by the first element of each pair
lsort -index 0 $people


list="namez:order!
name space:in
name1:sort
name:Please"

newline="
"

dumplist() {
	(
		IFS=$newline
		for pair in $list; do
			(
				IFS=:
				set -- $pair
				echo "  $1 => $2"
			)
		done
	)
}

echo "Original list:"
dumplist

list=`IFS=$newline; printf %s "$list" | sort -t: -k1,1`

echo "Sorted list:"
dumplist


#import std

#cast %sWLW

examples =

(
   -<&l <('z','a'),('x','c'),('y','b')>,  # sorted by the left
   -<&r <('z','a'),('x','c'),('y','b')>)  # sorted by the right


import "/sort" for Cmp, Sort, Comparable

class Pair is Comparable {
    construct new (name, value) {
        _name = name
        _value = value
    }

    name  { _name }
    value { _value }

    compare(other) { Cmp.string.call(_name, other.name) }

    toString { "{%(_name), %(_value)}" }
}

var pairs = [
    Pair.new("grass", "green"),
    Pair.new("snow", "white"),
    Pair.new("sky", "blue"),
    Pair.new("cherry", "red")
]

System.print("Before sorting:")
System.print("  " + pairs.join("\n  "))
Sort.insertion(pairs)
System.print("\nAfter sorting:")
System.print("  " + pairs.join("\n  "))


include c:\cxpl\stdlib;
char Dict(10,10);
int  Entries;

proc BSort(A, N);       \Bubble sort array A's key string into ascending order
char A;                 \address of array
int  N;                 \number of items in array (size)
int  B, I, J, T;
[B:= A;                 \B(I) accesses 32-bit pointers, not A(I) 8-bit bytes
for J:= N-1 downto 0 do
    for I:= 0 to J-1 do
        if StrCmp(A(I,1), A(I+1,1)) > 0 then
            [T:= B(I);  B(I):= B(I+1);  B(I+1):= T];    \swap pointers
];

proc AddEntry(Letter, Greek);   \Insert entry into associative array
char Letter, Greek;
[Dict(Entries,0):= Letter;
StrCopy(Greek, @Dict(Entries,1));
Entries:= Entries+1;            \(limit checks ignored for simplicity)
];

int I;
[Entries:= 0;
AddEntry(^A, "alpha");          \add items in arbitrary order
AddEntry(^D, "delta");
AddEntry(^B, "beta");
AddEntry(^C, "gamma");
BSort(Dict, Entries);           \sort entries by Greek name
for I:= 0 to Entries-1 do       \show sorted entries
    [ChOut(0, Dict(I,0));  ChOut(0, ^ );  Text(0, @Dict(I,1));  CrLf(0)];
]


class P{var name,value;
   fcn init(nm,val){name,value=vm.arglist}
   fcn __opLT(p){name<p.name}  // implementation of P1 < P2
}
// create list of pairs:
p:=List(P("sam","a"),P("fred","b"),P("chris","c"));
p.sort();
p.apply("name"); //-->L("chris","fred","sam")


V connections = [(0, 2), (0, 3), (0, 4),
                 (1, 3), (1, 4), (1, 5),
                 (6, 2), (6, 3), (6, 4),
                 (7, 3), (7, 4), (7, 5),
                 (2, 3), (3, 4), (4, 5)]

F ok(conn, perm)
   R abs(perm[conn[0]] - perm[conn[1]]) != 1

F solve()
   [[Int]] r
   V perm = Array(1..8)
   L
      I all(:connections.map(conn -> ok(conn, @perm)))
         r [+]= copy(perm)
      I !perm.next_permutation()
         L.break
   R r

V solutions = solve()
print(‘A, B, C, D, E, F, G, H = ’solutions[0].join(‘, ’))


With
Ada.Text_IO,
Connection_Types,
Connection_Combinations;

procedure main is
   Result : Connection_Types.Partial_Board renames Connection_Combinations;
begin
   Ada.Text_IO.Put_Line( Connection_Types.Image(Result) );
end;


     perms←{
     ⍝∇ 20100513/20140818 ra⌈ --()--
        1=⍴⍴⍵:⍵[∇ ''⍴⍴⍵]
       ↑{0∊⍴⍵:⍵ ⋄ (⍺[1]⌷⍵),(1↓⍺)∇ ⍵~⍺[1]⌷⍵}∘(⍳⍵)¨↓⍉1+(⌽⍳⍵)⊤¯1+⍳!⍵
   }

solution←{
    links←  (3 4 5) (4 5 6) (1 4 7) (1 2 3 5 7 8) (1 2 4 6 7 8) (2 5 8) (3 4 5) (4 5 6) ⍝ node i connects with nodes i⊃links
    tries←8 perms 8
    fails←{1∊{1∊⍵∊¯1 0 1}¨|⍺-¨⍺∘{⍺[⍵]}¨⍵}
  ⍝    ⍴⍸~tries fails ⍤1⊢links
  ⍝ 16
   solns←⍸~tries fails ⍤1⊢links
   tries[''⍴solns;]
   }