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:
Pierre Curto
2023-07-04 20:15:03 +02:00
committed by GitHub
parent 6231cc83d9
commit f8a3e4f6f0
10 changed files with 255 additions and 57 deletions

View File

@@ -1,16 +1,16 @@
module binarysearch_test @test;
import std::sort::binarysearch;
module sort_test @test;
import std::sort;
struct SearchTest
struct BinarySearchTest
{
int[] data;
int x;
int index;
}
fn void search()
fn void binarysearch()
{
SearchTest[] tcases = {
BinarySearchTest[] tcases = {
{ {}, 0, 0 },
{ {1, 2, 3}, 1, 0 },
{ {1, 2, 3}, 2, 1 },
@@ -22,28 +22,17 @@ fn void search()
foreach (tc : tcases)
{
usz idx = binarysearch::search(tc.data, tc.x);
usz idx = sort::binarysearch(tc.data, tc.x);
assert(idx == tc.index, "%s: got %d; want %d", tc.data, idx, tc.index);
usz cmp_idx = binarysearch::cmp_search(tc.data, tc.x, &cmp_int);
usz cmp_idx = sort::binarysearch_with(tc.data, tc.x, &sort::cmp_int);
assert(cmp_idx == tc.index, "%s: got %d; want %d", tc.data, cmp_idx, tc.index);
usz cmp_idx2 = binarysearch::cmp_search(tc.data, tc.x, &cmp_int2);
usz cmp_idx2 = sort::binarysearch_with(tc.data, tc.x, &sort::cmp_int2);
assert(cmp_idx2 == tc.index, "%s: got %d; want %d", tc.data, cmp_idx2, tc.index);
usz cmp_idx3 = binarysearch::cmp_search(tc.data, tc.x, fn int(int a, int b) => a - b);
usz cmp_idx3 = sort::binarysearch_with(tc.data, tc.x, fn int(int a, int b) => a - b);
assert(cmp_idx3 == tc.index, "%s: got %d; want %d", tc.data, cmp_idx2, tc.index);
}
}
module binarysearch_test;
fn int cmp_int(void* x, void* y) {
return *(int*)x - *(int*)y;
}
fn int cmp_int2(int x, int y) {
return x - y;
}
}

View File

@@ -0,0 +1,92 @@
module sort_test @test;
import std::sort;
import std::sort::quicksort;
def QSInt = quicksort::Quicksort<int, void*>;
fn void quicksort()
{
int[][] tcases = {
{},
{10, 3},
{3, 2, 1},
{1, 2, 3},
{2, 1, 3},
};
foreach (tc : tcases)
{
sort::quicksort(tc, QSInt);
assert(sort::check_int_sort(tc));
}
}
def Cmp = fn int (void*, void*);
def QSIntCmp = quicksort::Quicksort<int, Cmp>;
fn void quicksort_with()
{
int[][] tcases = {
{},
{10, 3},
{3, 2, 1},
{1, 2, 3},
{2, 1, 3},
};
foreach (tc : tcases)
{
sort::quicksort_with(tc, QSIntCmp, &sort::cmp_int);
assert(sort::check_int_sort(tc));
}
}
def Cmp2 = fn int (int, int);
def QSIntCmp2 = quicksort::Quicksort<int, Cmp2>;
fn void quicksort_with2()
{
int[][] tcases = {
{},
{10, 3},
{3, 2, 1},
{1, 2, 3},
{2, 1, 3},
};
foreach (tc : tcases)
{
sort::quicksort_with(tc, QSIntCmp2, &sort::cmp_int2);
assert(sort::check_int_sort(tc));
}
}
fn void quicksort_with_lambda()
{
int[][] tcases = {
{},
{10, 3},
{3, 2, 1},
{1, 2, 3},
{2, 1, 3},
};
foreach (tc : tcases)
{
sort::quicksort_with(tc, QSIntCmp2, fn int(int a, int b) => a - b);
assert(sort::check_int_sort(tc));
}
}
module std::sort;
fn bool check_int_sort(int[] list)
{
int prev = int.min;
foreach (x : list)
{
if (prev > x) return false;
prev = x;
}
return true;
}

View File

@@ -0,0 +1,9 @@
module std::sort;
fn int cmp_int(void* x, void* y) {
return *(int*)x - *(int*)y;
}
fn int cmp_int2(int x, int y) {
return x - y;
}