mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
add basic quicksort support (#816)
* lib/std/sort: refactor binarysearch namespace to prepare for sorting Signed-off-by: Pierre Curto <pierre.curto@gmail.com> * std/lib/sort: add basic quicksort support Signed-off-by: Pierre Curto <pierre.curto@gmail.com> * lib/std/hash: use method first parameter inferred type Signed-off-by: Pierre Curto <pierre.curto@gmail.com> * lib/std/hash: add fnv64a support Signed-off-by: Pierre Curto <pierre.curto@gmail.com> --------- Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
module std::sort::binarysearch;
|
||||
module std::sort;
|
||||
|
||||
/**
|
||||
* Perform a binary search over the sorted array and return the smallest index
|
||||
* in [0, array.len) where cmp(i) is true and cmp(j) is true for j in [i, array.len).
|
||||
* @require is_searchable(list) "The list must be indexable and support .len or .len()"
|
||||
* @require is_comparer(cmp, list) "Expeced a comparison function which compares values"
|
||||
* @require is_comparer(cmp, list) "Expected a comparison function which compares values"
|
||||
**/
|
||||
macro usz cmp_search(list, x, cmp)
|
||||
macro usz binarysearch_with(list, x, cmp)
|
||||
{
|
||||
usz i;
|
||||
usz len = @len_from_list(list);
|
||||
@@ -34,7 +34,7 @@ macro usz cmp_search(list, x, cmp)
|
||||
* @require is_searchable(list) "The list must be indexable and support .len or .len()"
|
||||
* @checked less(list[0], x) "The values must be comparable"
|
||||
**/
|
||||
macro usz search(list, x)
|
||||
macro usz binarysearch(list, x)
|
||||
{
|
||||
usz i;
|
||||
usz len = @len_from_list(list);
|
||||
@@ -48,24 +48,4 @@ macro usz search(list, x)
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
macro bool is_searchable(list) @local
|
||||
{
|
||||
return $checks(list[0]) && ($checks(list.len) || $checks(list.len()));
|
||||
}
|
||||
|
||||
macro usz @len_from_list(&list) @local
|
||||
{
|
||||
$if $checks(list.len()):
|
||||
return list.len();
|
||||
$else
|
||||
return list.len;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool is_comparer(cmp, list)
|
||||
{
|
||||
return $checks(int i = cmp(list[0], list[0]))
|
||||
|| $checks(int i = cmp(&list[0], &list[0]));
|
||||
}
|
||||
}
|
||||
66
lib/std/sort/quicksort.c3
Normal file
66
lib/std/sort/quicksort.c3
Normal file
@@ -0,0 +1,66 @@
|
||||
module std::sort;
|
||||
|
||||
/**
|
||||
* @require is_searchable(list) "The list must be indexable and support .len or .len()"
|
||||
**/
|
||||
macro quicksort(list, $Type)
|
||||
{
|
||||
(($Type)(list)).sort(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @require is_searchable(list) "The list must be indexable and support .len or .len()"
|
||||
* @require is_comparer(cmp, list) "Expected a comparison function which compares values"
|
||||
**/
|
||||
macro quicksort_with(list, $Type, cmp)
|
||||
{
|
||||
(($Type)(list)).sort(cmp);
|
||||
}
|
||||
|
||||
module std::sort::quicksort<Type, Comparer>;
|
||||
import std::sort;
|
||||
|
||||
def Quicksort = distinct Type[];
|
||||
|
||||
fn void Quicksort.sort(qs, Comparer cmp)
|
||||
{
|
||||
usz len = sort::@len_from_list(qs);
|
||||
qs.qsort(0, (isz)len - 1, cmp);
|
||||
}
|
||||
|
||||
fn void Quicksort.qsort(Quicksort qs, isz low, isz high, Comparer cmp) @private
|
||||
{
|
||||
if (low < high)
|
||||
{
|
||||
isz p = qs.partition(low, high, cmp);
|
||||
qs.qsort(low, p - 1, cmp);
|
||||
qs.qsort(p + 1, high, cmp);
|
||||
}
|
||||
}
|
||||
|
||||
fn isz Quicksort.partition(qs, isz low, isz high, Comparer cmp) @inline @private
|
||||
{
|
||||
Type pivot = qs[high];
|
||||
isz i = low - 1;
|
||||
for (isz j = low; j < high; j++)
|
||||
{
|
||||
$if $checks(cmp(qs[0], qs[0])):
|
||||
int res = cmp(qs[j], pivot);
|
||||
$else
|
||||
$if $checks(cmp(&qs[0], &qs[0])):
|
||||
int res = cmp(&qs[j], &pivot);
|
||||
$else
|
||||
int res;
|
||||
if (greater(qs[j], pivot)) res = 1;
|
||||
$endif
|
||||
$endif
|
||||
if (res <= 0)
|
||||
{
|
||||
i++;
|
||||
@swap(qs[i], qs[j]);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
@swap(qs[i], qs[high]);
|
||||
return i;
|
||||
}
|
||||
21
lib/std/sort/sort.c3
Normal file
21
lib/std/sort/sort.c3
Normal file
@@ -0,0 +1,21 @@
|
||||
module std::sort;
|
||||
|
||||
macro bool is_searchable(list)
|
||||
{
|
||||
return $checks(list[0]) && ($checks(list.len) || $checks(list.len()));
|
||||
}
|
||||
|
||||
macro usz @len_from_list(&list)
|
||||
{
|
||||
$if $checks(list.len()):
|
||||
return list.len();
|
||||
$else
|
||||
return list.len;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro bool is_comparer(cmp, list)
|
||||
{
|
||||
return $checks(int i = cmp(list[0], list[0]))
|
||||
|| $checks(int i = cmp(&list[0], &list[0]));
|
||||
}
|
||||
Reference in New Issue
Block a user