all tasks
This commit is contained in:
parent
b83f433714
commit
68f8f3e56b
14735 changed files with 178959 additions and 0 deletions
3
Task/Sorting-algorithms-Strand-sort/0DESCRIPTION
Normal file
3
Task/Sorting-algorithms-Strand-sort/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{{Sorting Algorithm}}
|
||||
{{Wikipedia|Strand sort}}
|
||||
Implement the [[wp:Strand sort|Strand sort]]. This is a way of sorting numbers by extracting shorter sequences of already sorted numbers from an unsorted list.
|
||||
2
Task/Sorting-algorithms-Strand-sort/1META.yaml
Normal file
2
Task/Sorting-algorithms-Strand-sort/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Sorting Algorithms
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#include <list>
|
||||
|
||||
template <typename T>
|
||||
std::list<T> strandSort(std::list<T> lst) {
|
||||
if (lst.size() <= 1)
|
||||
return lst;
|
||||
std::list<T> result;
|
||||
std::list<T> sorted;
|
||||
while (!lst.empty()) {
|
||||
sorted.push_back(lst.front());
|
||||
lst.pop_front();
|
||||
for (typename std::list<T>::iterator it = lst.begin(); it != lst.end(); ) {
|
||||
if (sorted.back() <= *it) {
|
||||
sorted.push_back(*it);
|
||||
it = lst.erase(it);
|
||||
} else
|
||||
it++;
|
||||
}
|
||||
result.merge(sorted);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
#include <stdio.h>
|
||||
|
||||
typedef struct node_t *node, node_t;
|
||||
struct node_t { int v; node next; };
|
||||
typedef struct { node head, tail; } slist;
|
||||
|
||||
void push(slist *l, node e) {
|
||||
if (!l->head) l->head = e;
|
||||
if (l->tail) l->tail->next = e;
|
||||
l->tail = e;
|
||||
}
|
||||
|
||||
node removehead(slist *l) {
|
||||
node e = l->head;
|
||||
if (e) {
|
||||
l->head = e->next;
|
||||
e->next = 0;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
void join(slist *a, slist *b) {
|
||||
push(a, b->head);
|
||||
a->tail = b->tail;
|
||||
}
|
||||
|
||||
void merge(slist *a, slist *b) {
|
||||
slist r = {0};
|
||||
while (a->head && b->head)
|
||||
push(&r, removehead(a->head->v <= b->head->v ? a : b));
|
||||
|
||||
join(&r, a->head ? a : b);
|
||||
*a = r;
|
||||
b->head = b->tail = 0;
|
||||
}
|
||||
|
||||
void sort(int *ar, int len)
|
||||
{
|
||||
node_t all[len];
|
||||
|
||||
// array to list
|
||||
for (int i = 0; i < len; i++)
|
||||
all[i].v = ar[i], all[i].next = i < len - 1 ? all + i + 1 : 0;
|
||||
|
||||
slist list = {all, all + len - 1}, rem, strand = {0}, res = {0};
|
||||
|
||||
for (node e = 0; list.head; list = rem) {
|
||||
rem.head = rem.tail = 0;
|
||||
while ((e = removehead(&list)))
|
||||
push((!strand.head || e->v >= strand.tail->v) ? &strand : &rem, e);
|
||||
|
||||
merge(&res, &strand);
|
||||
}
|
||||
|
||||
// list to array
|
||||
for (int i = 0; res.head; i++, res.head = res.head->next)
|
||||
ar[i] = res.head->v;
|
||||
}
|
||||
|
||||
void show(const char *title, int *x, int len)
|
||||
{
|
||||
printf("%s ", title);
|
||||
for (int i = 0; i < len; i++)
|
||||
printf("%3d ", x[i]);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int x[] = {-2,0,-2,5,5,3,-1,-3,5,5,0,2,-4,4,2};
|
||||
# define SIZE sizeof(x)/sizeof(int)
|
||||
|
||||
show("before sort:", x, SIZE);
|
||||
sort(x, sizeof(x)/sizeof(int));
|
||||
show("after sort: ", x, SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
before sort: -2 0 -2 5 5 3 -1 -3 5 5 0 2 -4 4 2
|
||||
after sort: -4 -3 -2 -2 -1 0 0 2 2 3 4 5 5 5 5
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# strand_sort(<output variable> [<value>...]) sorts a list of integers.
|
||||
function(strand_sort var)
|
||||
# Strand sort moves elements from _ARGN_ to _answer_.
|
||||
set(answer) # answer: a sorted list
|
||||
while(DEFINED ARGN)
|
||||
# Split _ARGN_ into two lists, _accept_ and _reject_.
|
||||
set(accept) # accept: elements in sorted order
|
||||
set(reject) # reject: all other elements
|
||||
set(p)
|
||||
foreach(e ${ARGN})
|
||||
if(DEFINED p AND p GREATER ${e})
|
||||
list(APPEND reject ${e})
|
||||
else()
|
||||
list(APPEND accept ${e})
|
||||
set(p ${e})
|
||||
endif()
|
||||
endforeach(e)
|
||||
|
||||
# Prepare to merge _accept_ into _answer_. First, convert both lists
|
||||
# into arrays, for better indexing: set(e ${answer${i}}) is faster
|
||||
# than list(GET answer ${i} e).
|
||||
set(la 0)
|
||||
foreach(e ${answer})
|
||||
math(EXPR la "${la} + 1")
|
||||
set(answer${la} ${e})
|
||||
endforeach(e)
|
||||
set(lb 0)
|
||||
foreach(e ${accept})
|
||||
math(EXPR lb "${lb} + 1")
|
||||
set(accept${lb} ${e})
|
||||
endforeach(e)
|
||||
|
||||
# Merge _accept_ into _answer_.
|
||||
set(answer)
|
||||
set(ia 1)
|
||||
set(ib 1)
|
||||
while(NOT ia GREATER ${la}) # Iterate elements of _answer_.
|
||||
set(ea ${answer${ia}})
|
||||
while(NOT ib GREATER ${lb}) # Take elements from _accept_,
|
||||
set(eb ${accept${ib}}) # while they are less than
|
||||
if(eb LESS ${ea}) # next element of _answer_.
|
||||
list(APPEND answer ${eb})
|
||||
math(EXPR ib "${ib} + 1")
|
||||
else()
|
||||
break()
|
||||
endif()
|
||||
endwhile()
|
||||
list(APPEND answer ${ea}) # Take next from _answer_.
|
||||
math(EXPR ia "${ia} + 1")
|
||||
endwhile()
|
||||
while(NOT ib GREATER ${lb}) # Take rest of _accept_.
|
||||
list(APPEND answer ${accept${ib}})
|
||||
math(EXPR ib "${ib} + 1")
|
||||
endwhile()
|
||||
|
||||
# This _reject_ becomes next _ARGN_. If _reject_ is empty, then
|
||||
# set(ARGN) undefines _ARGN_, breaking the loop.
|
||||
set(ARGN ${reject})
|
||||
endwhile(DEFINED ARGN)
|
||||
|
||||
set("${var}" ${answer} PARENT_SCOPE)
|
||||
endfunction(strand_sort)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
strand_sort(result 11 55 55 44 11 33 33 44 22 22)
|
||||
message(STATUS "${result}") # -- 11;11;22;22;33;33;44;44;55;55
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
(ns rosettacode.strand-sort)
|
||||
|
||||
(defn merge-join
|
||||
"Produces a globally sorted seq from two sorted seqables"
|
||||
[[a & la :as all] [b & lb :as bll]]
|
||||
(cond (nil? a) bll
|
||||
(nil? b) all
|
||||
(< a b) (cons a (lazy-seq (merge-join la bll)))
|
||||
true (cons b (lazy-seq (merge-join all lb)))))
|
||||
|
||||
(defn unbraid
|
||||
"Separates a sorted list from a sequence"
|
||||
[u]
|
||||
(when (seq u)
|
||||
(loop [[x & xs] u
|
||||
u []
|
||||
s []
|
||||
e x]
|
||||
(if (nil? x)
|
||||
[s u]
|
||||
(if (>= x e)
|
||||
(recur xs u (conj s x) x)
|
||||
(recur xs (conj u x) s e))))))
|
||||
|
||||
(defn strand-sort
|
||||
"http://en.wikipedia.org/wiki/Strand_sort"
|
||||
[s]
|
||||
(loop [[s u] (unbraid s)
|
||||
m nil]
|
||||
(if s
|
||||
(recur (unbraid u) (merge-join m s))
|
||||
m)))
|
||||
|
||||
(strand-sort [1, 6, 3, 2, 1, 7, 5, 3])
|
||||
;;=> (1 1 2 3 3 5 6 7)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(defun strand-sort (l cmp)
|
||||
(if l
|
||||
(let* ((l (reverse l))
|
||||
(o (list (car l))) n)
|
||||
(loop for i in (cdr l) do
|
||||
(push i (if (funcall cmp (car o) i) n o)))
|
||||
(merge 'list o (strand-sort n cmp) #'<))))
|
||||
|
||||
(let ((r (loop repeat 15 collect (random 10))))
|
||||
(print r)
|
||||
(print (strand-sort r #'<)))
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
(5 8 6 0 6 8 4 7 0 7 1 5 3 3 6)
|
||||
(0 0 1 3 3 4 5 5 6 6 6 7 7 8 8)
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import std.stdio, std.container;
|
||||
|
||||
DList!T strandSort(T)(DList!T list) {
|
||||
static DList!T merge(DList!T left, DList!T right) {
|
||||
DList!T result;
|
||||
while (!left.empty && !right.empty) {
|
||||
if (left.front <= right.front) {
|
||||
result.insertBack(left.front);
|
||||
left.removeFront();
|
||||
} else {
|
||||
result.insertBack(right.front);
|
||||
right.removeFront();
|
||||
}
|
||||
}
|
||||
result.insertBack(left[]);
|
||||
result.insertBack(right[]);
|
||||
return result;
|
||||
}
|
||||
|
||||
DList!T result, sorted, leftover;
|
||||
|
||||
while (!list.empty) {
|
||||
leftover.clear();
|
||||
sorted.clear();
|
||||
sorted.insertBack(list.front);
|
||||
list.removeFront();
|
||||
foreach (item; list) {
|
||||
if (sorted.back <= item)
|
||||
sorted.insertBack(item);
|
||||
else
|
||||
leftover.insertBack(item);
|
||||
}
|
||||
result = merge(sorted, result);
|
||||
list = leftover;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto lst = DList!int([-2,0,-2,5,5,3,-1,-3,5,5,0,2,-4,4,2]);
|
||||
foreach (e; strandSort(lst))
|
||||
write(e, " ");
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
function merge(sequence left, sequence right)
|
||||
sequence result
|
||||
result = {}
|
||||
while length(left) > 0 and length(right) > 0 do
|
||||
if left[$] <= right[1] then
|
||||
exit
|
||||
elsif right[$] <= left[1] then
|
||||
return result & right & left
|
||||
elsif left[1] < right[1] then
|
||||
result = append(result,left[1])
|
||||
left = left[2..$]
|
||||
else
|
||||
result = append(result,right[1])
|
||||
right = right[2..$]
|
||||
end if
|
||||
end while
|
||||
return result & left & right
|
||||
end function
|
||||
|
||||
function strand_sort(sequence s)
|
||||
integer j
|
||||
sequence result
|
||||
result = {}
|
||||
while length(s) > 0 do
|
||||
j = length(s)
|
||||
for i = 1 to length(s)-1 do
|
||||
if s[i] > s[i+1] then
|
||||
j = i
|
||||
exit
|
||||
end if
|
||||
end for
|
||||
|
||||
result = merge(result,s[1..j])
|
||||
s = s[j+1..$]
|
||||
end while
|
||||
return result
|
||||
end function
|
||||
|
||||
constant s = rand(repeat(1000,10))
|
||||
puts(1,"Before: ")
|
||||
? s
|
||||
puts(1,"After: ")
|
||||
? strand_sort(s)
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
type link struct {
|
||||
int
|
||||
next *link
|
||||
}
|
||||
|
||||
func linkInts(s []int) *link {
|
||||
if len(s) == 0 {
|
||||
return nil
|
||||
}
|
||||
return &link{s[0], linkInts(s[1:])}
|
||||
}
|
||||
|
||||
func (l *link) String() string {
|
||||
if l == nil {
|
||||
return "nil"
|
||||
}
|
||||
r := fmt.Sprintf("[%d", l.int)
|
||||
for l = l.next; l != nil; l = l.next {
|
||||
r = fmt.Sprintf("%s %d", r, l.int)
|
||||
}
|
||||
return r + "]"
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := linkInts([]int{170, 45, 75, -90, -802, 24, 2, 66})
|
||||
fmt.Println("before:", a)
|
||||
b := strandSort(a)
|
||||
fmt.Println("after: ", b)
|
||||
}
|
||||
|
||||
func strandSort(a *link) (result *link) {
|
||||
for a != nil {
|
||||
// build sublist
|
||||
sublist := a
|
||||
a = a.next
|
||||
sTail := sublist
|
||||
for p, pPrev := a, a; p != nil; p = p.next {
|
||||
if p.int > sTail.int {
|
||||
// append to sublist
|
||||
sTail.next = p
|
||||
sTail = p
|
||||
// remove from a
|
||||
if p == a {
|
||||
a = p.next
|
||||
} else {
|
||||
pPrev.next = p.next
|
||||
}
|
||||
} else {
|
||||
pPrev = p
|
||||
}
|
||||
}
|
||||
sTail.next = nil // terminate sublist
|
||||
if result == nil {
|
||||
result = sublist
|
||||
continue
|
||||
}
|
||||
// merge
|
||||
var m, rr *link
|
||||
if sublist.int < result.int {
|
||||
m = sublist
|
||||
sublist = m.next
|
||||
rr = result
|
||||
} else {
|
||||
m = result
|
||||
rr = m.next
|
||||
}
|
||||
result = m
|
||||
for {
|
||||
if sublist == nil {
|
||||
m.next = rr
|
||||
break
|
||||
}
|
||||
if rr == nil {
|
||||
m.next = sublist
|
||||
break
|
||||
}
|
||||
if sublist.int < rr.int {
|
||||
m.next = sublist
|
||||
m = sublist
|
||||
sublist = m.next
|
||||
} else {
|
||||
m.next = rr
|
||||
m = rr
|
||||
rr = m.next
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
-- Same merge as in Merge Sort
|
||||
merge :: (Ord a) => [a] -> [a] -> [a]
|
||||
merge [] ys = ys
|
||||
merge xs [] = xs
|
||||
merge (x : xs) (y : ys)
|
||||
| x <= y = x : merge xs (y : ys)
|
||||
| otherwise = y : merge (x : xs) ys
|
||||
|
||||
strandSort :: (Ord a) => [a] -> [a]
|
||||
strandSort [] = []
|
||||
strandSort (x : xs) = merge strand (strandSort rest) where
|
||||
(strand, rest) = extractStrand x xs
|
||||
extractStrand x [] = ([x], [])
|
||||
extractStrand x (x1 : xs)
|
||||
| x <= x1 = let (strand, rest) = extractStrand x1 xs in (x : strand, rest)
|
||||
| otherwise = let (strand, rest) = extractStrand x xs in (strand, x1 : rest)
|
||||
|
|
@ -0,0 +1 @@
|
|||
strandSort=: (#~ merge $:^:(0<#)@(#~ -.)) (= >./\)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
strandSort 3 1 5 4 2
|
||||
1 2 3 4 5
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
((#~ ; $:^:(0<#)@(#~ -.)) (= >./\)) 3 1 5 4 2
|
||||
┌───┬───┬─┬┐
|
||||
│3 5│1 4│2││
|
||||
└───┴───┴─┴┘
|
||||
((#~ ; $:^:(0<#)@(#~ -.)) (= >./\)) 3 3 1 2 4 3 5 6
|
||||
┌─────────┬─────┬┐
|
||||
│3 3 4 5 6│1 2 3││
|
||||
└─────────┴─────┴┘
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class Strand{
|
||||
// note: the input list is destroyed
|
||||
public static <E extends Comparable<? super E>>
|
||||
LinkedList<E> strandSort(LinkedList<E> list){
|
||||
if(list.size() <= 1) return list;
|
||||
|
||||
LinkedList<E> result = new LinkedList<E>();
|
||||
while(list.size() > 0){
|
||||
LinkedList<E> sorted = new LinkedList<E>();
|
||||
sorted.add(list.removeFirst()); //same as remove() or remove(0)
|
||||
for(Iterator<E> it = list.iterator(); it.hasNext(); ){
|
||||
E elem = it.next();
|
||||
if(sorted.peekLast().compareTo(elem) <= 0){
|
||||
sorted.addLast(elem); //same as add(elem) or add(0, elem)
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
result = merge(sorted, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <E extends Comparable<? super E>>
|
||||
LinkedList<E> merge(LinkedList<E> left, LinkedList<E> right){
|
||||
LinkedList<E> result = new LinkedList<E>();
|
||||
while(!left.isEmpty() && !right.isEmpty()){
|
||||
//change the direction of this comparison to change the direction of the sort
|
||||
if(left.peek().compareTo(right.peek()) <= 0)
|
||||
result.add(left.remove());
|
||||
else
|
||||
result.add(right.remove());
|
||||
}
|
||||
result.addAll(left);
|
||||
result.addAll(right);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
System.out.println(strandSort(new LinkedList<Integer>(Arrays.asList(3,1,2,4,5))));
|
||||
System.out.println(strandSort(new LinkedList<Integer>(Arrays.asList(3,3,1,2,4,5))));
|
||||
System.out.println(strandSort(new LinkedList<Integer>(Arrays.asList(3,3,1,2,4,3,5,6))));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
StrandSort[ input_ ] := Module[ {results = {}, A = input},
|
||||
While[Length@A > 0,
|
||||
sublist = {A[[1]]}; A = A[[2;;All]];
|
||||
For[i = 1, i < Length@A, i++,
|
||||
If[ A[[i]] > Last@sublist, AppendTo[sublist, A[[i]]]; A = Delete[A, i];]
|
||||
];
|
||||
results = #[[Ordering@#]]&@Join[sublist, results];];
|
||||
results ]
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* NetRexx */
|
||||
options replace format comments java crossref savelog symbols binary
|
||||
|
||||
import java.util.List
|
||||
|
||||
placesList = [String -
|
||||
"UK London", "US New York", "US Boston", "US Washington" -
|
||||
, "UK Washington", "US Birmingham", "UK Birmingham", "UK Boston" -
|
||||
]
|
||||
|
||||
lists = [ -
|
||||
placesList -
|
||||
, strandSort(String[] Arrays.copyOf(placesList, placesList.length)) -
|
||||
]
|
||||
|
||||
loop ln = 0 to lists.length - 1
|
||||
cl = lists[ln]
|
||||
loop ct = 0 to cl.length - 1
|
||||
say cl[ct]
|
||||
end ct
|
||||
say
|
||||
end ln
|
||||
|
||||
return
|
||||
|
||||
method strandSort(A = String[]) public constant binary returns String[]
|
||||
|
||||
rl = String[A.length]
|
||||
al = List strandSort(Arrays.asList(A))
|
||||
al.toArray(rl)
|
||||
|
||||
return rl
|
||||
|
||||
method strandSort(Alst = List) public constant binary returns ArrayList
|
||||
|
||||
A = ArrayList(Alst)
|
||||
result = ArrayList()
|
||||
loop label A_ while A.size > 0
|
||||
sublist = ArrayList()
|
||||
sublist.add(A.get(0))
|
||||
A.remove(0)
|
||||
loop i_ = 0 while i_ < A.size - 1
|
||||
if (Comparable A.get(i_)).compareTo(Comparable sublist.get(sublist.size - 1)) > 0 then do
|
||||
sublist.add(A.get(i_))
|
||||
A.remove(i_)
|
||||
end
|
||||
end i_
|
||||
result = merge(result, sublist)
|
||||
end A_
|
||||
|
||||
return result
|
||||
|
||||
method merge(left = List, right = List) public constant binary returns ArrayList
|
||||
|
||||
result = ArrayList()
|
||||
loop label mx while left.size > 0 & right.size > 0
|
||||
if (Comparable left.get(0)).compareTo(Comparable right.get(0)) <= 0 then do
|
||||
result.add(left.get(0))
|
||||
left.remove(0)
|
||||
end
|
||||
else do
|
||||
result.add(right.get(0))
|
||||
right.remove(0)
|
||||
end
|
||||
end mx
|
||||
if left.size > 0 then do
|
||||
result.addAll(left)
|
||||
end
|
||||
if right.size > 0 then do
|
||||
result.addAll(right)
|
||||
end
|
||||
|
||||
return result
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
let rec strand_sort (cmp : 'a -> 'a -> int) : 'a list -> 'a list = function
|
||||
[] -> []
|
||||
| x::xs ->
|
||||
let rec extract_strand x = function
|
||||
[] -> [x], []
|
||||
| x1::xs when cmp x x1 <= 0 ->
|
||||
let strand, rest = extract_strand x1 xs in x::strand, rest
|
||||
| x1::xs ->
|
||||
let strand, rest = extract_strand x xs in strand, x1::rest
|
||||
in
|
||||
let strand, rest = extract_strand x xs in
|
||||
List.merge cmp strand (strand_sort cmp rest)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
strandSort(v)={
|
||||
my(sorted=[],unsorted=v,remaining,working);
|
||||
while(#unsorted,
|
||||
remaining=working=List();
|
||||
listput(working, unsorted[1]);
|
||||
for(i=2,#unsorted,
|
||||
if(unsorted[i]<working[#working],
|
||||
listput(remaining, unsorted[i])
|
||||
,
|
||||
listput(working, unsorted[i])
|
||||
)
|
||||
);
|
||||
unsorted=Vec(remaining);
|
||||
sorted=merge(sorted, Vec(working))
|
||||
);
|
||||
sorted
|
||||
};
|
||||
merge(u,v)={
|
||||
my(ret=vector(#u+#v),i=1,j=1);
|
||||
for(k=1,#ret,
|
||||
if(i<=#u & (j>#v | u[i]<v[j]),
|
||||
ret[k]=u[i];
|
||||
i++
|
||||
,
|
||||
ret[k]=v[j];
|
||||
j++
|
||||
)
|
||||
);
|
||||
ret
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
$lst = new SplDoublyLinkedList();
|
||||
foreach (array(1,20,64,72,48,75,96,55,42,74) as $v)
|
||||
$lst->push($v);
|
||||
foreach (strandSort($lst) as $v)
|
||||
echo "$v ";
|
||||
|
||||
function strandSort(SplDoublyLinkedList $lst) {
|
||||
$result = new SplDoublyLinkedList();
|
||||
while (!$lst->isEmpty()) {
|
||||
$sorted = new SplDoublyLinkedList();
|
||||
$remain = new SplDoublyLinkedList();
|
||||
$sorted->push($lst->shift());
|
||||
foreach ($lst as $item) {
|
||||
if ($sorted->top() <= $item) {
|
||||
$sorted->push($item);
|
||||
} else {
|
||||
$remain->push($item);
|
||||
}
|
||||
}
|
||||
$result = _merge($sorted, $result);
|
||||
$lst = $remain;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function _merge(SplDoublyLinkedList $left, SplDoublyLinkedList $right) {
|
||||
$res = new SplDoublyLinkedList();
|
||||
while (!$left->isEmpty() && !$right->isEmpty()) {
|
||||
if ($left->bottom() <= $right->bottom()) {
|
||||
$res->push($left->shift());
|
||||
} else {
|
||||
$res->push($right->shift());
|
||||
}
|
||||
}
|
||||
foreach ($left as $v) $res->push($v);
|
||||
foreach ($right as $v) $res->push($v);
|
||||
return $res;
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
strand: procedure options (main); /* 27 Oct. 2012 */
|
||||
declare A(100) fixed, used(100) bit (1), sorted fixed controlled;
|
||||
declare (temp, work) fixed controlled;
|
||||
declare (i, j, k, n) fixed binary;
|
||||
|
||||
n = hbound(A, 1);
|
||||
used = '1'b;
|
||||
A = random()*99;
|
||||
|
||||
put edit (A) (f(3));
|
||||
|
||||
do while (allocation(sorted) < n);
|
||||
call fetch (A, work);
|
||||
call move (temp, work);
|
||||
|
||||
call merge(sorted, temp);
|
||||
/* Merges elements in SORTED with elements in TEMP. */
|
||||
end;
|
||||
/* Transfer the sorted elements to A. */
|
||||
do i = 1 to allocation(sorted);
|
||||
A(i) = sorted; free sorted;
|
||||
end;
|
||||
/* Print the sorted values. */
|
||||
put skip list ('The sorted values are:');
|
||||
put skip edit (A) (f(3));
|
||||
|
||||
/* Merges elements of SORTED with elements of TEMP and places */
|
||||
/* the result in SORTED. */
|
||||
/* Elements in SORTED and TEMP are in forward order. */
|
||||
merge: procedure (sorted, temp);
|
||||
declare (sorted, temp) fixed controlled;
|
||||
declare work fixed controlled;
|
||||
declare (j_ok, k_ok) bit (1);
|
||||
|
||||
do until ((k_ok | j_ok) = '0'b);
|
||||
k_ok = allocation(sorted) > 0;
|
||||
j_ok = allocation(temp) > 0;
|
||||
if k_ok & j_ok then
|
||||
do;
|
||||
if sorted <= temp then
|
||||
do; allocate work; work = sorted; free sorted; end;
|
||||
else
|
||||
do; allocate work; work = temp; free temp; end;
|
||||
end;
|
||||
else
|
||||
if allocation(temp) = 0 then
|
||||
/* temp is empty; copy remainder of sorted into work */
|
||||
do while (allocation(sorted) > 0);
|
||||
allocate work; work = sorted; free sorted;
|
||||
end;
|
||||
else
|
||||
/* sorted is empty; copy remainder of temp onto work */
|
||||
do while (allocation(temp) > 0);
|
||||
allocate work; work = temp; free temp;
|
||||
end;
|
||||
end;
|
||||
|
||||
call move (sorted, work); /* Move the values to SORTED. */
|
||||
|
||||
end merge;
|
||||
|
||||
/* Collect a thread of ascending values from aray A, and stack them in temp. */
|
||||
/* Note: the values in temp are in reverse order. */
|
||||
fetch: procedure (A, temp);
|
||||
declare A(*) fixed, temp controlled fixed;
|
||||
declare i fixed binary;
|
||||
|
||||
do i = 1 to hbound(A,1);
|
||||
if used(i) then
|
||||
do; allocate temp; temp = A(i); used(i) = '0'b; go to found; end;
|
||||
end;
|
||||
found:
|
||||
do i = i+1 to hbound(A,1);
|
||||
if (temp <= A(i)) & used(i) then
|
||||
do; allocate temp; temp = A(i); used(i) = '0'b; end;
|
||||
end;
|
||||
end fetch;
|
||||
|
||||
/* Copy the stack at TEMP to the stack at SORTED. */
|
||||
/* In TEMP, elements are in reverse order; */
|
||||
/* in SORTED, elements are in forward order. */
|
||||
move: procedure (sorted, temp);
|
||||
declare (sorted, temp) fixed controlled;
|
||||
|
||||
do while (allocation(sorted) > 0); free sorted; end;
|
||||
do while (allocation (temp) > 0);
|
||||
allocate sorted; sorted = temp; free temp;
|
||||
end;
|
||||
end move;
|
||||
|
||||
end strand;
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
program StrandSortDemo;
|
||||
|
||||
type
|
||||
TIntArray = array of integer;
|
||||
|
||||
function merge(left: TIntArray; right: TIntArray): TIntArray;
|
||||
var
|
||||
i, j, k: integer;
|
||||
begin
|
||||
setlength(merge, length(left) + length(right));
|
||||
i := low(merge);
|
||||
j := low(left);
|
||||
k := low(right);
|
||||
repeat
|
||||
if ((left[j] <= right[k]) and (j <= high(left))) or (k > high(right)) then
|
||||
begin
|
||||
merge[i] := left[j];
|
||||
inc(j);
|
||||
end
|
||||
else
|
||||
begin
|
||||
merge[i] := right[k];
|
||||
inc(k);
|
||||
end;
|
||||
inc(i);
|
||||
until i > high(merge);
|
||||
end;
|
||||
|
||||
function StrandSort(s: TIntArray): TIntArray;
|
||||
var
|
||||
strand: TIntArray;
|
||||
i, j: integer;
|
||||
begin
|
||||
setlength(StrandSort, length(s));
|
||||
setlength(strand, length(s));
|
||||
i := low(s);
|
||||
repeat
|
||||
StrandSort[i] := s[i];
|
||||
inc(i);
|
||||
until (s[i] < s[i-1]);
|
||||
setlength(StrandSort, i);
|
||||
repeat
|
||||
setlength(strand, 1);
|
||||
j := low(strand);
|
||||
strand[j] := s[i];
|
||||
while (s[i+1] > s[i]) and (i < high(s)) do
|
||||
begin
|
||||
inc(i);
|
||||
inc(j);
|
||||
setlength(strand, length(strand) + 1);
|
||||
Strand[j] := s[i];
|
||||
end;
|
||||
StrandSort := merge(StrandSort, strand);
|
||||
inc(i);
|
||||
until (i > high(s));
|
||||
end;
|
||||
|
||||
var
|
||||
data: TIntArray;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
setlength(data, 8);
|
||||
Randomize;
|
||||
writeln('The data before sorting:');
|
||||
for i := low(data) to high(data) do
|
||||
begin
|
||||
data[i] := Random(high(data));
|
||||
write(data[i]:4);
|
||||
end;
|
||||
writeln;
|
||||
data := StrandSort(data);
|
||||
writeln('The data after sorting:');
|
||||
for i := low(data) to high(data) do
|
||||
begin
|
||||
write(data[i]:4);
|
||||
end;
|
||||
writeln;
|
||||
end.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
sub infix:<M> (@x, @y) {
|
||||
gather {
|
||||
while @x and @y {
|
||||
given @x[0] cmp @y[0] {
|
||||
when Increase { take @x.shift }
|
||||
when Decrease { take @y.shift }
|
||||
when Same { take @x.shift, @y.shift }
|
||||
}
|
||||
}
|
||||
take @x, @y;
|
||||
}
|
||||
}
|
||||
|
||||
sub strand (@x is rw) {
|
||||
my $prev = -Inf;
|
||||
my $i = 0;
|
||||
gather while $i < @x {
|
||||
if @x[$i] before $prev {
|
||||
$i++;
|
||||
}
|
||||
else {
|
||||
take $prev = splice(@x, $i, 1)[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub strand_sort (@x is copy) {
|
||||
my @out;
|
||||
@out M= strand(@x) while @x;
|
||||
@out;
|
||||
}
|
||||
|
||||
my @a = (^100).roll(10);
|
||||
say "Before @a[]";
|
||||
@a = strand_sort(@a);
|
||||
say "After @a[]";
|
||||
|
||||
@a = <The quick brown fox jumps over the lazy dog>;
|
||||
say "Before @a[]";
|
||||
@a = strand_sort(@a);
|
||||
say "After @a[]";
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
use 5.10.0; # for given/when
|
||||
sub merge {
|
||||
my ($x, $y) = @_;
|
||||
my @out;
|
||||
while (@$x and @$y) {
|
||||
given ($x->[-1] <=> $y->[-1]) {
|
||||
when( 1) { unshift @out, pop @$x }
|
||||
when(-1) { unshift @out, pop @$y }
|
||||
default { splice @out, 0, 0, pop(@$x), pop(@$y) }
|
||||
}
|
||||
}
|
||||
return @$x, @$y, @out
|
||||
}
|
||||
|
||||
sub strand {
|
||||
my $x = shift;
|
||||
my @out = shift @$x // return;
|
||||
if (@$x) {
|
||||
for (-@$x .. -1) {
|
||||
if ($x->[$_] >= $out[-1]) {
|
||||
push @out, splice @$x, $_, 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return @out
|
||||
}
|
||||
|
||||
sub strand_sort {
|
||||
my @x = @_;
|
||||
my @out;
|
||||
while (my @strand = strand(\@x)) {
|
||||
@out = merge(\@out, \@strand)
|
||||
}
|
||||
@out
|
||||
}
|
||||
|
||||
my @a = map (int rand(100), 1 .. 10);
|
||||
say "Before @a";
|
||||
@a = strand_sort(@a);
|
||||
say "After @a";
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(de strandSort (Lst)
|
||||
(let Res NIL # Result list
|
||||
(while Lst
|
||||
(let Sub (circ (car Lst)) # Build sublist as fifo
|
||||
(setq
|
||||
Lst (filter
|
||||
'((X)
|
||||
(or
|
||||
(> (car Sub) X)
|
||||
(nil (fifo 'Sub X)) ) )
|
||||
(cdr Lst) )
|
||||
Res (make
|
||||
(while (or Res Sub) # Merge
|
||||
(link
|
||||
(if2 Res Sub
|
||||
(if (>= (car Res) (cadr Sub))
|
||||
(fifo 'Sub)
|
||||
(pop 'Res) )
|
||||
(pop 'Res)
|
||||
(fifo 'Sub) ) ) ) ) ) ) )
|
||||
Res ) )
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
Procedure strandSort(List a())
|
||||
Protected NewList subList()
|
||||
Protected NewList results()
|
||||
|
||||
While ListSize(a()) > 0
|
||||
ClearList(subList())
|
||||
AddElement(subList())
|
||||
FirstElement(a())
|
||||
subList() = a()
|
||||
DeleteElement(a())
|
||||
ForEach a()
|
||||
If a() >= subList()
|
||||
AddElement(subList())
|
||||
subList() = a()
|
||||
DeleteElement(a())
|
||||
EndIf
|
||||
Next
|
||||
|
||||
;merge lists
|
||||
FirstElement(subList())
|
||||
If Not FirstElement(results())
|
||||
;copy all of sublist() to results()
|
||||
MergeLists(subList(), results(), #PB_List_Last)
|
||||
Else
|
||||
Repeat
|
||||
If subList() < results()
|
||||
InsertElement(results())
|
||||
results() = subList()
|
||||
DeleteElement(subList())
|
||||
If Not NextElement(subList())
|
||||
Break
|
||||
EndIf
|
||||
ElseIf Not NextElement(results())
|
||||
;add remainder of sublist() to end of results()
|
||||
MergeLists(subList(), results(), #PB_List_Last)
|
||||
Break
|
||||
EndIf
|
||||
ForEver
|
||||
EndIf
|
||||
|
||||
Wend
|
||||
CopyList(results(), a())
|
||||
EndProcedure
|
||||
|
||||
Procedure.s listContents(List a())
|
||||
Protected output.s
|
||||
PushListPosition(a())
|
||||
ForEach a()
|
||||
output + Str(a()) + ","
|
||||
Next
|
||||
PopListPosition(a())
|
||||
ProcedureReturn Left(output, Len(output) - 1)
|
||||
EndProcedure
|
||||
|
||||
Procedure setupList(List a())
|
||||
ClearList(a())
|
||||
Protected elementCount, i
|
||||
|
||||
elementCount = Random(5) + 10
|
||||
For i = 1 To elementCount
|
||||
AddElement(a())
|
||||
a() = Random(10) - 5
|
||||
Next
|
||||
EndProcedure
|
||||
|
||||
|
||||
If OpenConsole()
|
||||
NewList sample()
|
||||
Define i
|
||||
|
||||
For i = 1 To 3
|
||||
setupList(sample())
|
||||
PrintN("List " + Str(i) + ":")
|
||||
PrintN(" Before: " + listContents(sample()))
|
||||
strandSort(sample())
|
||||
PrintN(" After : " + listContents(sample()))
|
||||
PrintN("")
|
||||
Next
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
def merge_list(a, b):
|
||||
out = []
|
||||
while len(a) and len(b):
|
||||
if a[0] < b[0]:
|
||||
out.append(a.pop(0))
|
||||
else:
|
||||
out.append(b.pop(0))
|
||||
out += a
|
||||
out += b
|
||||
return out
|
||||
|
||||
def strand(a):
|
||||
i, s = 0, [a.pop(0)]
|
||||
while i < len(a):
|
||||
if a[i] > s[-1]:
|
||||
s.append(a.pop(i))
|
||||
else:
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def strand_sort(a):
|
||||
out = strand(a)
|
||||
while len(a):
|
||||
out = merge_list(out, strand(a))
|
||||
return out
|
||||
|
||||
print strand_sort([1, 6, 3, 2, 1, 7, 5, 3])
|
||||
|
|
@ -0,0 +1 @@
|
|||
[1, 1, 2, 3, 3, 5, 6, 7]
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*REXX program uses a strand sort to sort a random list of words | nums.*/
|
||||
parse arg size minv maxv,old /*get options from command line. */
|
||||
if size=='' then size=20 /*no size? Then use the default.*/
|
||||
if minv=='' then minv=0 /*no minV? " " " " */
|
||||
if maxv=='' then maxv=size /*no maxV? " " " " */
|
||||
do i=1 for size /*generate random # list*/
|
||||
old=old random(0,maxv-minv)+minv
|
||||
end /*i*/
|
||||
old=space(old) /*remove any extraneous blanks. */
|
||||
say center('unsorted list',length(old),"="); say old; say
|
||||
new=strand_sort(old) /*sort the list of random numbers*/
|
||||
say center('sorted list' ,length(new),"="); say new
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────STRAND_SORT subroutine──────────────*/
|
||||
strand_sort: procedure; parse arg x; y=
|
||||
do while words(x)\==0; w=words(x)
|
||||
do j=1 for w-1 /*any number|word out of order?*/
|
||||
if word(x,j)>word(x,j+1) then do; w=j; leave; end
|
||||
end /*j*/
|
||||
y=merge(y,subword(x,1,w)); x=subword(x,w+1)
|
||||
end /*while words(x)\==0*/
|
||||
return y
|
||||
/*──────────────────────────────────MERGE subroutine────────────────────*/
|
||||
merge: procedure; parse arg a.1,a.2; p=
|
||||
do forever /*keep at it while 2 lists exist.*/
|
||||
do i=1 to 2; w.i=words(a.i); end /*find number of entries in lists*/
|
||||
if w.1*w.2==0 then leave /*if any list is empty, then stop*/
|
||||
if word(a.1,w.1) <= word(a.2,1) then leave /*lists are now sorted?*/
|
||||
if word(a.2,w.2) <= word(a.1,1) then return space(p a.2 a.1)
|
||||
#=1+(word(a.1,1) >= word(a.2,1)); p=p word(a.#,1); a.#=subword(a.#,2)
|
||||
end /*forever*/
|
||||
return space(p a.1 a.2)
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
class Array
|
||||
def strandsort
|
||||
a = self.dup
|
||||
result = []
|
||||
while a.length > 0
|
||||
sublist = [a.shift]
|
||||
a.each_with_index .
|
||||
inject([]) do |remove, (val, idx)|
|
||||
if val > sublist[-1]
|
||||
sublist << val
|
||||
remove.unshift(idx)
|
||||
end
|
||||
remove
|
||||
end .
|
||||
each {|idx| a.delete_at(idx)}
|
||||
|
||||
idx = 0
|
||||
while idx < result.length and not sublist.empty?
|
||||
if sublist[0] < result[idx]
|
||||
result.insert(idx, sublist.shift)
|
||||
end
|
||||
idx += 1
|
||||
end
|
||||
result += sublist if not sublist.empty?
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def strandsort!
|
||||
self.replace(strandsort)
|
||||
end
|
||||
end
|
||||
|
||||
p [1, 6, 3, 2, 1, 7, 5, 3].strandsort
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
proc merge {listVar toMerge} {
|
||||
upvar 1 $listVar v
|
||||
set i [set j 0]
|
||||
set out {}
|
||||
while {$i<[llength $v] && $j<[llength $toMerge]} {
|
||||
if {[set a [lindex $v $i]] < [set b [lindex $toMerge $j]]} {
|
||||
lappend out $a
|
||||
incr i
|
||||
} else {
|
||||
lappend out $b
|
||||
incr j
|
||||
}
|
||||
}
|
||||
# Done the merge, but will be one source with something left
|
||||
# This will handle all that by doing a merge of the remnants onto the end
|
||||
set v [concat $out [lrange $v $i end] [lrange $toMerge $j end]]
|
||||
return
|
||||
}
|
||||
|
||||
proc strandSort A {
|
||||
set results {}
|
||||
while {[llength $A]} {
|
||||
set sublist [lrange $A 0 0]
|
||||
# We build a list of items that weren't filtered rather than removing "in place"
|
||||
# because this fits better with the way Tcl values work (the underlying data
|
||||
# structure is an array, not a linked list).
|
||||
set newA {}
|
||||
foreach a [lrange $A 1 end] {
|
||||
if {$a > [lindex $sublist end]} {
|
||||
lappend sublist $a
|
||||
} else {
|
||||
lappend newA $a
|
||||
}
|
||||
}
|
||||
set A $newA
|
||||
merge results $sublist
|
||||
}
|
||||
return $results
|
||||
}
|
||||
|
||||
puts [strandSort {3 1 5 4 2}]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
strand_sort "r" = # parameterized by a relational predicate "r"
|
||||
|
||||
@NiX -+
|
||||
:-0 ~&B^?a\~&Y@a "r"?abh/~&alh2faltPrXPRC ~&arh2falrtPXPRC,
|
||||
~&r->l ^|rlPlCrrPX/~& @hNCNXtX ~&r->lbx "r"?rllPXh/~&llPrhPlrPCXrtPX ~&rhPllPClrPXrtPX+-
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#cast %nL
|
||||
|
||||
x = (strand_sort nat-nleq) <3,1,5,4,2>
|
||||
Loading…
Add table
Add a link
Reference in a new issue