September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1,38 @@
report z_quicksort.
data(numbers) = value int4_table( ( 4 ) ( 65 ) ( 2 ) ( -31 ) ( 0 ) ( 99 ) ( 2 ) ( 83 ) ( 782 ) ( 1 ) ).
perform quicksort changing numbers.
write `[`.
loop at numbers assigning field-symbol(<numbers>).
write <numbers>.
endloop.
write `]`.
form quicksort changing numbers type int4_table.
data(less) = value int4_table( ).
data(equal) = value int4_table( ).
data(greater) = value int4_table( ).
if lines( numbers ) > 1.
data(pivot) = numbers[ lines( numbers ) / 2 ].
loop at numbers assigning field-symbol(<number>).
if <number> < pivot.
append <number> to less.
elseif <number> = pivot.
append <number> to equal.
elseif <number> > pivot.
append <number> to greater.
endif.
endloop.
perform quicksort changing less.
perform quicksort changing greater.
clear numbers.
append lines of less to numbers.
append lines of equal to numbers.
append lines of greater to numbers.
endif.
endform.

View file

@ -0,0 +1,254 @@
/* ARM assembly Raspberry PI */
/* program quickSort.s */
/* look pseudo code in wikipedia quicksort */
/************************************/
/* Constantes */
/************************************/
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ WRITE, 4 @ Linux syscall
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessSortOk: .asciz "Table sorted.\n"
szMessSortNok: .asciz "Table not sorted !!!!!.\n"
sMessResult: .ascii "Value : "
sMessValeur: .fill 11, 1, ' ' @ size => 11
szCarriageReturn: .asciz "\n"
.align 4
iGraine: .int 123456
.equ NBELEMENTS, 10
#TableNumber: .int 9,5,6,1,2,3,10,8,4,7
#TableNumber: .int 1,3,5,2,4,6,10,8,4,7
#TableNumber: .int 1,3,5,2,4,6,10,8,4,7
#TableNumber: .int 1,2,3,4,5,6,10,8,4,7
TableNumber: .int 10,9,8,7,6,5,4,3,2,1
#TableNumber: .int 13,12,11,10,9,8,7,6,5,4,3,2,1
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
1:
ldr r0,iAdrTableNumber @ address number table
mov r1,#0 @ indice first item
mov r2,#NBELEMENTS @ number of élements
bl triRapide @ call quicksort
ldr r0,iAdrTableNumber @ address number table
bl displayTable
ldr r0,iAdrTableNumber @ address number table
mov r1,#NBELEMENTS @ number of élements
bl isSorted @ control sort
cmp r0,#1 @ sorted ?
beq 2f
ldr r0,iAdrszMessSortNok @ no !! error sort
bl affichageMess
b 100f
2: @ yes
ldr r0,iAdrszMessSortOk
bl affichageMess
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrsMessValeur: .int sMessValeur
iAdrszCarriageReturn: .int szCarriageReturn
iAdrsMessResult: .int sMessResult
iAdrTableNumber: .int TableNumber
iAdrszMessSortOk: .int szMessSortOk
iAdrszMessSortNok: .int szMessSortNok
/******************************************************************/
/* control sorted table */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains the number of elements > 0 */
/* r0 return 0 if not sorted 1 if sorted */
isSorted:
push {r2-r4,lr} @ save registers
mov r2,#0
ldr r4,[r0,r2,lsl #2]
1:
add r2,#1
cmp r2,r1
movge r0,#1
bge 100f
ldr r3,[r0,r2, lsl #2]
cmp r3,r4
movlt r0,#0
blt 100f
mov r4,r3
b 1b
100:
pop {r2-r4,lr}
bx lr @ return
/***************************************************/
/* Appel récursif Tri Rapide quicksort */
/***************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item */
/* r2 contains the number of elements > 0 */
triRapide:
push {r2-r5,lr} @ save registers
sub r2,#1 @ last item index
cmp r1,r2 @ first > last ?
bge 100f @ yes -> end
mov r4,r0 @ save r0
mov r5,r2 @ save r2
bl partition1 @ cutting into 2 parts
mov r2,r0 @ index partition
mov r0,r4 @ table address
bl triRapide @ sort lower part
add r1,r2,#1 @ index begin = index partition + 1
add r2,r5,#1 @ number of elements
bl triRapide @ sort higter part
100: @ end function
pop {r2-r5,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* Partition table elements */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item */
/* r2 contains index of last item */
partition1:
push {r1-r7,lr} @ save registers
ldr r3,[r0,r2,lsl #2] @ load value last index
mov r4,r1 @ init with first index
mov r5,r1 @ init with first index
1: @ begin loop
ldr r6,[r0,r5,lsl #2] @ load value
cmp r6,r3 @ compare value
ldrlt r7,[r0,r4,lsl #2] @ if < swap value table
strlt r6,[r0,r4,lsl #2]
strlt r7,[r0,r5,lsl #2]
addlt r4,#1 @ and increment index 1
add r5,#1 @ increment index 2
cmp r5,r2 @ end ?
blt 1b @ no loop
ldr r7,[r0,r4,lsl #2] @ swap value
str r3,[r0,r4,lsl #2]
str r7,[r0,r2,lsl #2]
mov r0,r4 @ return index partition
100:
pop {r1-r7,lr}
bx lr
/******************************************************************/
/* Display table elements */
/******************************************************************/
/* r0 contains the address of table */
displayTable:
push {r0-r3,lr} @ save registers
mov r2,r0 @ table address
mov r3,#0
1: @ loop display table
ldr r0,[r2,r3,lsl #2]
ldr r1,iAdrsMessValeur @ display value
bl conversion10 @ call function
ldr r0,iAdrsMessResult
bl affichageMess @ display message
add r3,#1
cmp r3,#NBELEMENTS - 1
ble 1b
ldr r0,iAdrszCarriageReturn
bl affichageMess
100:
pop {r0-r3,lr}
bx lr
/******************************************************************/
/* display text with size calculation */
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
push {r0,r1,r2,r7,lr} @ save registres
mov r2,#0 @ counter length
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index
cmp r1,#0 @ if 0 its over
addne r2,r2,#1 @ else add 1 in the length
bne 1b @ and loop
@ so here r2 contains the length of the message
mov r1,r0 @ address message in r1
mov r0,#STDOUT @ code to write to the standard output Linux
mov r7, #WRITE @ code call system "write"
svc #0 @ call systeme
pop {r0,r1,r2,r7,lr} @ restaur des 2 registres */
bx lr @ return
/******************************************************************/
/* Converting a register to a decimal unsigned */
/******************************************************************/
/* r0 contains value and r1 address area */
/* r0 return size of result (no zero final in area) */
/* area size => 11 bytes */
.equ LGZONECAL, 10
conversion10:
push {r1-r4,lr} @ save registers
mov r3,r1
mov r2,#LGZONECAL
1: @ start loop
bl divisionpar10U @ unsigned r0 <- dividende. quotient ->r0 reste -> r1
add r1,#48 @ digit
strb r1,[r3,r2] @ store digit on area
cmp r0,#0 @ stop if quotient = 0
subne r2,#1 @ else previous position
bne 1b @ and loop
@ and move digit from left of area
mov r4,#0
2:
ldrb r1,[r3,r2]
strb r1,[r3,r4]
add r2,#1
add r4,#1
cmp r2,#LGZONECAL
ble 2b
@ and move spaces in end on area
mov r0,r4 @ result length
mov r1,#' ' @ space
3:
strb r1,[r3,r4] @ store space in area
add r4,#1 @ next position
cmp r4,#LGZONECAL
ble 3b @ loop if r4 <= area size
100:
pop {r1-r4,lr} @ restaur registres
bx lr @return
/***************************************************/
/* division par 10 unsigned */
/***************************************************/
/* r0 dividende */
/* r0 quotient */
/* r1 remainder */
divisionpar10U:
push {r2,r3,r4, lr}
mov r4,r0 @ save value
//mov r3,#0xCCCD @ r3 <- magic_number lower raspberry 3
//movt r3,#0xCCCC @ r3 <- magic_number higter raspberry 3
ldr r3,iMagicNumber @ r3 <- magic_number raspberry 1 2
umull r1, r2, r3, r0 @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0)
mov r0, r2, LSR #3 @ r2 <- r2 >> shift 3
add r2,r0,r0, lsl #2 @ r2 <- r0 * 5
sub r1,r4,r2, lsl #1 @ r1 <- r4 - (r2 * 2) = r4 - (r0 * 10)
pop {r2,r3,r4,lr}
bx lr @ leave function
iMagicNumber: .int 0xCCCCCCCD

View file

@ -1,10 +1,9 @@
-----------------------------------------------------------------------
-- Generic Quicksort procedure
-- Generic Quick_Sort procedure
-----------------------------------------------------------------------
generic
type Element_Type is private;
type Index_Type is (<>);
type Element_Array is array(Index_Type range <>) of Element_Type;
with function "<" (Left, Right : Element_Type) return Boolean is <>;
with function ">" (Left, Right : Element_Type) return Boolean is <>;
procedure Sort(Item : in out Element_Array);
type Element is private;
type Index is (<>);
type Element_Array is array(Index range <>) of Element;
with function "<" (Left, Right : Element) return Boolean is <>;
procedure Quick_Sort(A : in out Element_Array);

View file

@ -1,50 +1,44 @@
-----------------------------------------------------------------------
-- Generic Quicksort procedure
-- Generic Quick_Sort procedure
-----------------------------------------------------------------------
procedure Sort (Item : in out Element_Array) is
procedure Quick_Sort (A : in out Element_Array) is
procedure Swap(Left, Right : in out Element_Type) is
Temp : Element_Type := Left;
procedure Swap(Left, Right : Index) is
Temp : Element := A (Left);
begin
Left := Right;
Right := Temp;
A (Left) := A (Right);
A (Right) := Temp;
end Swap;
Pivot_Index : Index_Type;
Pivot_Value : Element_Type;
Right : Index_Type := Item'Last;
Left : Index_Type := Item'First;
begin
if Item'Length > 1 then
Pivot_Index := Index_Type'Val((Index_Type'Pos(Item'Last) + 1 +
Index_Type'Pos(Item'First)) / 2);
Pivot_Value := Item(Pivot_Index);
Left := Item'First;
Right := Item'Last;
loop
while Left < Item'Last and then Item(Left) < Pivot_Value loop
Left := Index_Type'Succ(Left);
end loop;
while Right > Item'First and then Item(Right) > Pivot_Value loop
Right := Index_Type'Pred(Right);
end loop;
exit when Left >= Right;
Swap(Item(Left), Item(Right));
if Left < Item'Last then
Left := Index_Type'Succ(Left);
end if;
if Right > Item'First then
Right := Index_Type'Pred(Right);
end if;
end loop;
if Right > Item'First then
Sort(Item(Item'First..Index_Type'Pred(Right)));
end if;
if Left < Item'Last then
Sort(Item(Left..Item'Last));
end if;
if A'Length > 1 then
declare
Pivot_Value : Element := A (A'First);
Right : Index := A'Last;
Left : Index := A'First;
begin
loop
while Left < Right and not (Pivot_Value < A (Left)) loop
Left := Index'Succ (Left);
end loop;
while Pivot_Value < A (Right) loop
Right := Index'Pred (Right);
end loop;
exit when Right <= Left;
Swap (Left, Right);
Left := Index'Succ (Left);
Right := Index'Pred (Right);
end loop;
if Right = A'Last then
Right := Index'Pred (Right);
Swap (A'First, A'Last);
end if;
if Left = A'First then
Left := Index'Succ (Left);
end if;
Quick_Sort (A (A'First .. Right));
Quick_Sort (A (Left .. A'Last));
end;
end if;
end Sort;
end Quick_Sort;

View file

@ -1,13 +1,12 @@
with Sort;
with Ada.Text_Io;
with Ada.Float_Text_IO; use Ada.Float_Text_IO;
procedure Sort_Test is
type Days is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
type Sales is array(Days range <>) of Float;
procedure Sort_Days is new Sort(Float, Days, Sales);
type Sales is array (Days range <>) of Float;
procedure Sort_Days is new Quick_Sort(Float, Days, Sales);
procedure Print(Item : Sales) is
procedure Print (Item : Sales) is
begin
for I in Item'range loop
Put(Item => Item(I), Fore => 5, Aft => 2, Exp => 0);

View file

@ -0,0 +1,28 @@
DIM test(9)
test() = 4, 65, 2, -31, 0, 99, 2, 83, 782, 1
PROCquicksort(test(), 0, 10)
FOR i% = 0 TO 9
PRINT test(i%) ;
NEXT
PRINT
END
DEF PROCquicksort(a(), s%, n%)
LOCAL l%, p, r%, t%
IF n% < 2 THEN ENDPROC
t% = s% + n% - 1
l% = s%
r% = t%
p = a((l% + r%) DIV 2)
REPEAT
WHILE a(l%) < p l% += 1 : ENDWHILE
WHILE a(r%) > p r% -= 1 : ENDWHILE
IF l% <= r% THEN
SWAP a(l%), a(r%)
l% += 1
r% -= 1
ENDIF
UNTIL l% > r%
IF s% < r% PROCquicksort(a(), s%, r% - s% + 1)
IF l% < t% PROCquicksort(a(), l%, t% - l% + 1 )
ENDPROC

View file

@ -0,0 +1,37 @@
100 PROGRAM "QuickSrt.bas"
110 RANDOMIZE
120 NUMERIC A(5 TO 19)
130 CALL INIT(A)
140 CALL WRITE(A)
150 CALL QSORT(LBOUND(A),UBOUND(A))
160 CALL WRITE(A)
170 DEF INIT(REF A)
180 FOR I=LBOUND(A) TO UBOUND(A)
190 LET A(I)=RND(98)+1
200 NEXT
210 END DEF
220 DEF WRITE(REF A)
230 FOR I=LBOUND(A) TO UBOUND(A)
240 PRINT A(I);
250 NEXT
260 PRINT
270 END DEF
280 DEF QSORT(AH,FH)
290 NUMERIC E
300 LET E=AH:LET U=FH:LET K=A(E)
310 DO UNTIL E=U
320 DO UNTIL E=U OR A(U)<K
330 LET U=U-1
340 LOOP
350 IF E<U THEN
360 LET A(E)=A(U):LET E=E+1
370 DO UNTIL E=U OR A(E)>K
380 LET E=E+1
390 LOOP
400 IF E<U THEN LET A(U)=A(E):LET U=U-1
410 END IF
420 LOOP
430 LET A(E)=K
440 IF AH<E-1 THEN CALL QSORT(AH,E-1)
450 IF E+1<FH THEN CALL QSORT(E+1,FH)
460 END DEF

View file

@ -0,0 +1,6 @@
(defun quicksort (list)
(when list
(destructuring-bind (x . xs) list
(nconc (quicksort (remove-if (lambda (a) (> a x)) xs))
`(,x)
(quicksort (remove-if (lambda (a) (<= a x)) xs))))))

View file

@ -1,48 +1,49 @@
import extensions.
import system'routines.
import system'collections.
import extensions;
import system'routines;
import system'collections;
extension $op
extension op
{
quickSort
[
if (self isEmpty) [ ^ self ].
quickSort()
{
if (self.isEmpty()) { ^ self };
var pivot := self[0].
var pivot := self[0];
array_list less := ArrayList new.
array_list pivotList := ArrayList new.
array_list more := ArrayList new.
auto less := new ArrayList();
auto pivotList := new ArrayList();
auto more := new ArrayList();
self forEach(:item)
[
self.forEach:(item)
{
if (item < pivot)
[
less append(item)
];
if (item > pivot)
[
more append(item)
];
[
pivotList append(item)
]
].
{
less.append(item)
}
else if (item > pivot)
{
more.append(item)
}
else
{
pivotList.append(item)
}
};
less := less quickSort.
more := more quickSort.
less := less.quickSort();
more := more.quickSort();
less appendRange(pivotList).
less appendRange(more).
less.appendRange(pivotList);
less.appendRange(more);
^ less
]
}
}
program =
[
var list := (3, 14, 1, 5, 9, 2, 6, 3).
public program()
{
var list := new int[]{3, 14, 1, 5, 9, 2, 6, 3};
console printLine("before:", list).
console printLine("after :", list quickSort).
].
console.printLine("before:", list.asEnumerable());
console.printLine("after :", list.quickSort().asEnumerable());
}

View file

@ -0,0 +1,35 @@
main
new collection,size
set size=16
set collection=size for i=0:1:size-1 set collection(i)=$random(size)
write "Collection to sort:",!!
zwrite collection ; This will only work on Intersystem's flavor of MUMPS
do quicksort(.collection,0,collection-1)
write:$$isSorted(.collection) !,"Collection is sorted:",!!
zwrite collection ; This will only work on Intersystem's flavor of MUMPS
q
quicksort(array,low,high)
if low<high do
. set pivot=$$partition(.array,low,high)
. do quicksort(.array,low,pivot-1)
. do quicksort(.array,pivot+1,high)
q
partition(A,p,r)
set pivot=A(r)
set i=p-1
for j=p:1:r-1 do
. i A(j)<=pivot do
. . set i=i+1
. . set helper=A(j)
. . set A(j)=A(i)
. . set A(i)=helper
set helper=A(r)
set A(r)=A(i+1)
set A(i+1)=helper
quit i+1
isSorted(array)
set sorted=1
for i=0:1:array-2 do quit:sorted=0
. for j=i+1:1:array-1 do quit:sorted=0
. . set:array(i)>array(j) sorted=0
quit sorted

View file

@ -0,0 +1,32 @@
Red []
;;-------------------------------
;; we have to use function not func here, otherwise we'd have to define all "vars" as local...
qsort: function [list][
;;-------------------------------
if 1 >= length? list [ return list ]
left: copy []
right: copy []
eq: copy [] ;; "equal"
pivot: list/2 ;; simply choose second element as pivot element
foreach ele list [
case [
ele < pivot [ append left ele ]
ele > pivot [ append right ele ]
true [append eq ele ]
]
]
;; this is the last expression of the function, so coding "return" here is not necessary
reduce [qsort left eq qsort right]
]
;; lets test the function with an array of 100k integers, range 1..1000
list: []
loop 100000 [append list random 1000]
t0: now/time/precise ;; start timestamp
qsort list ;; the return value (block) contains the sorted list, original list has not changed
print ["time1: " now/time/precise - t0] ;; about 1.1 sec on my machine
t0: now/time/precise
sort list ;; just for fun time the builtin function also ( also implementation of quicksort )
print ["time2: " now/time/precise - t0]

View file

@ -36,12 +36,13 @@ fn partition<T,F>(v: &mut [T], f: &F) -> usize
{
let len = v.len();
let pivot_index = len / 2;
let last_index = len - 1;
v.swap(pivot_index, len - 1);
v.swap(pivot_index, last_index);
let mut store_index = 0;
for i in 0..len - 1 {
if f(&v[i], &v[len - 1]) {
for i in 0..last_index {
if f(&v[i], &v[last_index]) {
v.swap(i, store_index);
store_index += 1;
}

View file

@ -1,11 +1,6 @@
def sort(xs: List[Int]): List[Int] = {
xs match {
case Nil => Nil
case x :: xx => {
// Arbitrarily partition list in two
val (lo, hi) = xx.partition(_ < x)
// Sort each half
sort(lo) ++ (x :: sort(hi))
}
}
def sort(xs: List[Int]): List[Int] = xs match {
case Nil => Nil
case head :: tail =>
val (less, notLess) = tail.partition(_ < head) // Arbitrarily partition list in two
sort(less) ++ (head :: sort(notLess)) // Sort each half
}

View file

@ -1,9 +1,6 @@
def sort[T](xs: List[T], lessThan: (T, T) => Boolean): List[T] = {
xs match {
case Nil => Nil
case x :: xx => {
val (lo, hi) = xx.partition(lessThan(_, x))
sort(lo, lessThan) ++ (x :: sort(hi, lessThan))
}
}
def sort[T](xs: List[T], lessThan: (T, T) => Boolean): List[T] = xs match {
case Nil => Nil
case x :: xx =>
val (lo, hi) = xx.partition(lessThan(_, x))
sort(lo, lessThan) ++ (x :: sort(hi, lessThan))
}

View file

@ -1,9 +1,6 @@
def sort[T](xs: List[T])(implicit ord: Ordering[T]): List[T] = {
xs match {
case Nil => Nil
case x :: xx => {
val (lo, hi) = xx.partition(ord.lt(_, x))
sort[T](lo) ++ (x :: sort[T](hi))
}
}
def sort[T](xs: List[T])(implicit ord: Ordering[T]): List[T] = xs match {
case Nil => Nil
case x :: xx =>
val (lo, hi) = xx.partition(ord.lt(_, x))
sort[T](lo) ++ (x :: sort[T](hi))
}

View file

@ -1,9 +1,6 @@
def sort[T <: Ordered[T]](xs: List[T]): List[T] = {
xs match {
case Nil => Nil
case x :: xx => {
val (lo, hi) = xx.partition(_ < x)
sort(lo) ++ (x :: sort(hi))
}
}
def sort[T <: Ordered[T]](xs: List[T]): List[T] = xs match {
case Nil => Nil
case x :: xx =>
val (lo, hi) = xx.partition(_ < x)
sort(lo) ++ (x :: sort(hi))
}