September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,15 @@
fun mergeSort(m):
return m if m.size <= 1
let middle = m.size / 2
let left = merge(m[:middle])
let right = merge(m[middle:]);
fun merge(left, right):
let result = []
while |left or right|.!empty:
result ++ (left.shift() if |left <= right|.first ...
else right.shift())
result ++ left ++ right
let arr = [7, 6, 5, 9, 8, 4, 3, 1, 2, 0]
print mergeSort arr

View file

@ -1,60 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
inline
void merge(int *left, int l_len, int *right, int r_len, int *out)
{
int i, j, k;
for (i = j = k = 0; i < l_len && j < r_len; )
out[k++] = left[i] < right[j] ? left[i++] : right[j++];
while (i < l_len) out[k++] = left[i++];
while (j < r_len) out[k++] = right[j++];
}
/* inner recursion of merge sort */
void recur(int *buf, int *tmp, int len)
{
int l = len / 2;
if (len <= 1) return;
/* note that buf and tmp are swapped */
recur(tmp, buf, l);
recur(tmp + l, buf + l, len - l);
merge(tmp, l, tmp + l, len - l, buf);
}
/* preparation work before recursion */
void merge_sort(int *buf, int len)
{
/* call alloc, copy and free only once */
int *tmp = malloc(sizeof(int) * len);
memcpy(tmp, buf, sizeof(int) * len);
recur(buf, tmp, len);
free(tmp);
}
int main()
{
# define LEN 20
int i, x[LEN];
for (i = 0; i < LEN; i++)
x[i] = rand() % LEN;
puts("before sort:");
for (i = 0; i < LEN; i++) printf("%d ", x[i]);
putchar('\n');
merge_sort(x, LEN);
puts("after sort:");
for (i = 0; i < LEN; i++) printf("%d ", x[i]);
putchar('\n');
return 0;
}

View file

@ -1,70 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
typedef struct link_s *link, link_t;
struct link_s { double v; link next; };
const link_t fnil = { 0./0., &fnil }; // sentinel
const link const nil = &fnil;
link list_from_array(double *a, int len)
{
link p = nil;
while (len--) {
link pp = malloc(sizeof(*pp));
pp->v = a[len];
pp->next = p;
p = pp;
}
return p;
}
void show_list(link a)
{
for (; a != nil; a = a->next)
printf("%g ", a->v);
putchar('\n');
}
link merge(link a, link b)
{
link head = &(link_t){0, nil}, tail = head;
while (a != nil && b != nil) {
link *p = a->v <= b->v ? &a : &b;
tail->next = *p;
*p = (*p)->next;
tail = tail->next;
}
tail->next = a != nil ? a : b;
return head->next;
}
link merge_sort(link p)
{
if (p->next == nil) return p;
link tail = p, mid = p;
// Seek to the middle of the list. This is O(n) for list
// length, so O(n log n) complexity to overall merge sort
// that an array wouldn't have to deal with.
while (1) {
tail = tail->next->next;
if (tail == nil) break;
mid = mid->next;
}
tail = mid->next;
mid->next = nil;
return merge(merge_sort(p), merge_sort(tail));
}
int main(void)
{
double x[] = {5,3,6,1,2,6,2,0,3,5,7,8,2,4,9};
link p = list_from_array(x, sizeof(x)/sizeof(x[0]));
puts("list: "); show_list(p);
puts("sort: "); show_list(merge_sort(p));
return 0;
}

View file

@ -0,0 +1,74 @@
' FB 1.05.0 Win64
Sub copyArray(a() As Integer, iBegin As Integer, iEnd As Integer, b() As Integer)
Redim b(iBegin To iEnd - 1) As Integer
For k As Integer = iBegin To iEnd - 1
b(k) = a(k)
Next
End Sub
' Left source half is a(iBegin To iMiddle-1).
' Right source half is a(iMiddle To iEnd-1).
' Result is b(iBegin To iEnd-1).
Sub topDownMerge(a() As Integer, iBegin As Integer, iMiddle As Integer, iEnd As Integer, b() As Integer)
Dim i As Integer = iBegin
Dim j As Integer = iMiddle
' While there are elements in the left or right runs...
For k As Integer = iBegin To iEnd - 1
' If left run head exists and is <= existing right run head.
If i < iMiddle AndAlso (j >= iEnd OrElse a(i) <= a(j)) Then
b(k) = a(i)
i += 1
Else
b(k) = a(j)
j += 1
End If
Next
End Sub
' Sort the given run of array a() using array b() as a source.
' iBegin is inclusive; iEnd is exclusive (a(iEnd) is not in the set).
Sub topDownSplitMerge(b() As Integer, iBegin As Integer, iEnd As Integer, a() As Integer)
If (iEnd - iBegin) < 2 Then Return '' If run size = 1, consider it sorted
' split the run longer than 1 item into halves
Dim iMiddle As Integer = (iEnd + iBegin) \ 2 '' iMiddle = mid point
' recursively sort both runs from array a() into b()
topDownSplitMerge(a(), iBegin, iMiddle, b()) '' sort the left run
topDownSplitMerge(a(), iMiddle, iEnd, b()) '' sort the right run
' merge the resulting runs from array b() into a()
topDownMerge(b(), iBegin, iMiddle, iEnd, a())
End Sub
' Array a() has the items to sort; array b() is a work array (empty initially).
Sub topDownMergeSort(a() As Integer, b() As Integer, n As Integer)
copyArray(a(), 0, n, b()) '' duplicate array a() into b()
topDownSplitMerge(b(), 0, n, a()) '' sort data from b() into a()
End Sub
Sub printArray(a() As Integer)
For i As Integer = LBound(a) To UBound(a)
Print Using "####"; a(i);
Next
Print
End Sub
Dim a(0 To 9) As Integer = {4, 65, 2, -31, 0, 99, 2, 83, 782, 1}
Dim b() As Integer
Print "Unsorted : ";
printArray(a())
topDownMergeSort a(), b(), 10
Print "Sorted : ";
printArray(a())
Print
Dim a2(0 To 8) As Integer = {7, 5, 2, 6, 1, 4, 2, 6, 3}
Erase b
Print "Unsorted : ";
printArray(a2())
topDownMergeSort a2(), b(), 9
Print "Sorted : ";
printArray(a2())
Print
Print "Press any key to quit"
Sleep

View file

@ -1,29 +1,27 @@
func merge(left, right) {
var result = [];
while (!left.is_empty && !right.is_empty) {
result.append([right,left][left.first <= right.first].shift);
};
result + left + right;
var result = []
while (left && right) {
result << [right,left].min_by{.first}.shift
}
result + left + right
}
 
func mergesort(array) {
var len = array.len;
len < 2 && return array;
var len = array.len
len < 2 && return array
 
var mid = (len/2 -> int);
var left = array.ft(0, mid-1);
var right = array.ft(mid);
var (left, right) = array.part(len//2)
 
left = __FUNC__(left);
right = __FUNC__(right);
left = __FUNC__(left)
right = __FUNC__(right)
 
merge(left, right);
merge(left, right)
}
 
# Numeric sort
var nums = (0..7 -> shuffle);
say mergesort(nums);
var nums = rand(1..100, 10)
say mergesort(nums)
 
# String sort
var strings = ('a'..'e' -> shuffle);
say mergesort(strings);
var strings = rand('a'..'z', 10)
say mergesort(strings)

View file

@ -0,0 +1,13 @@
fcn _merge(left,right){
if (not left) return(right);
if (not right) return(left);
l:=left[0]; r:=right[0];
if (l<=r) return(L(l).extend(self.fcn(left[1,*],right)));
else return(L(r).extend(self.fcn(left,right[1,*])));
}
fcn merge_sort(L){
if (L.len()<2) return(L);
n:=L.len()/2;
return(_merge(self.fcn(L[0,n]), self.fcn(L[n,*])));
}

View file

@ -0,0 +1,2 @@
merge_sort(T(1,3,5,7,9,8,6,4,2)).println();
merge_sort("big fjords vex quick waltz nymph").concat().println();

View file

@ -0,0 +1,5 @@
fcn mergeSort(L){
if (L.len()<2) return(L.copy());
n:=L.len()/2;
self.fcn(L[0,n]).merge(self.fcn(L[n,*]));
}

View file

@ -0,0 +1,2 @@
mergeSort(T(1,3,5,7,9,8,6,4,2)).println();
mergeSort("big fjords vex quick waltz nymph".split("")).concat().println();