diff --git a/algorithm/sorter.go b/algorithm/sorter.go new file mode 100644 index 0000000..77aec69 --- /dev/null +++ b/algorithm/sorter.go @@ -0,0 +1,53 @@ +// Copyright 2021 dudaodong@gmail.com. All rights reserved. +// Use of this source code is governed by MIT license + +// Package algorithm contain some algorithm functions. eg. sort, find, list, linklist, stack, queue, tree, graph. TODO +package algorithm + +import "github.com/duke-git/lancet/lancetconstraints" + +// SelectionSort use selection to sort slice, +func SelectionSort[T any](slice []T, comparator lancetconstraints.Comparator) []T { + for i := 0; i < len(slice); i++ { + min := i + + for j := i + 1; j < len(slice); j++ { + if comparator.Compare(slice[j], slice[min]) == -1 { + min = j + } + } + swap(slice, i, min) + } + return slice +} + +// func QuickSort[T comparable](slice []T, low, high int) []T { +// if low < high { +// var p int +// slice, p = partitionForQuickSort(slice, low, high) +// slice = quickSort(slice, low, p-1) +// slice = quickSort(slice, p+1, high) +// } + +// return slice +// } + +// swap two slice value at index i and j +func swap[T any](slice []T, i, j int) { + slice[i], slice[j] = slice[j], slice[i] +} + +// func partition[T comparable](slice []T, low, high int) ([]T, int) { +// p := slice[high] +// i := low +// for j := low; j < high; j++ { +// //???, error: comparable don't support operator < +// if slice[j] < p { +// slice[i], slice[j] = slice[j], slice[i] +// i++ +// } +// } +// slice[i], slice[high] = slice[high], slice[i] + +// return slice, i +// } diff --git a/algorithm/sorter_test.go b/algorithm/sorter_test.go new file mode 100644 index 0000000..e6724cb --- /dev/null +++ b/algorithm/sorter_test.go @@ -0,0 +1,58 @@ +package algorithm + +import ( + "fmt" + "testing" + + "github.com/duke-git/lancet/internal" +) + +// People test mock data +type People struct { + Name string + Age int +} + +// PeopleAageComparator sort people slice by age field +type PeopleAageComparator struct{} + +// Compare implements github.com/duke-git/lancet/lancetconstraints/constraints.go/Comparator +func (pc *PeopleAageComparator) Compare(v1 interface{}, v2 interface{}) int { + p1, _ := v1.(People) + p2, _ := v2.(People) + + //ascending order + if p1.Age < p2.Age { + return -1 + } else if p1.Age > p2.Age { + return 1 + } + return 0 + + //decending order + // if p1.Age > p2.Age { + // return -1 + // } else if p1.Age < p2.Age { + // return 1 + // } +} + +var peoples = []People{ + {Name: "a", Age: 20}, + {Name: "b", Age: 10}, + {Name: "c", Age: 17}, + {Name: "d", Age: 8}, + {Name: "e", Age: 28}, +} + +func TestSelectionSort(t *testing.T) { + asssert := internal.NewAssert(t, "TestSelectionSort") + comparator := &PeopleAageComparator{} + sortedPeopleByAge := SelectionSort(peoples, comparator) + t.Log(sortedPeopleByAge) + + expected := "[{d 8} {b 10} {c 17} {a 20} {e 28}]" + actual := fmt.Sprintf("%v", sortedPeopleByAge) + + asssert.Equal(expected, actual) +} diff --git a/lancetconstraints/constraints.go b/lancetconstraints/constraints.go new file mode 100644 index 0000000..b7f7774 --- /dev/null +++ b/lancetconstraints/constraints.go @@ -0,0 +1,13 @@ +// Copyright 2021 dudaodong@gmail.com. All rights reserved. +// Use of this source code is governed by MIT license + +// Package lancetconstraints contain some comstomer constraints. +package lancetconstraints + +// Comparator is for comparing two values +type Comparator interface { + // Compare v1 and v2 + // Ascending order: should return 1 -> v1 > v2, 0 -> v1 = v2, -1 -> v1 < v2 + // Descending order: should return 1 -> v1 < v2, 0 -> v1 = v2, -1 -> v1 > v2 + Compare(v1, v2 interface{}) int +} diff --git a/myconstraints/constraints.go b/myconstraints/constraints.go deleted file mode 100644 index 6e25096..0000000 --- a/myconstraints/constraints.go +++ /dev/null @@ -1,5 +0,0 @@ -package myconstraints - -type Number interface { - int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64 | complex64 | complex128 -} diff --git a/slice/slice_util.go b/slice/slice_util.go index 6f94503..b3113f1 100644 --- a/slice/slice_util.go +++ b/slice/slice_util.go @@ -5,31 +5,6 @@ import ( "reflect" ) -// func quickSort[T comparable](slice []T, low, high int) []T { -// if low < high { -// var p int -// slice, p = partitionForQuickSort(slice, low, high) -// slice = quickSort(slice, low, p-1) -// slice = quickSort(slice, p+1, high) -// } - -// return slice -// } - -// func partitionForQuickSort[T comparable](slice []T, low, high int) ([]T, int) { -// p := slice[high] -// i := low -// for j := low; j < high; j++ { -// //???, error: comparable don't support operator < -// if slice[j] < p { -// slice[i], slice[j] = slice[j], slice[i] -// i++ -// } -// } -// slice[i], slice[high] = slice[high], slice[i] -// return slice, i -// } - // sliceValue return the reflect value of a slice func sliceValue(slice interface{}) reflect.Value { v := reflect.ValueOf(slice)