sort.um

type Arr* = interface {
len(): int
swap(i, j: int)
}

type CmpFn* = fn(a: Arr, i, j: int): bool

fn sort

fn sort*(a: Arr, f: CmpFn) {

type IntArr* = []int

fn (this: ^IntArr) len(): int {
return len(this^)
}

fn (this: ^IntArr) swap(i, j: int) {
t := this[i]
this[i] = this[j]
this[j] = t
}

fn sortInt*(a: []int) {
sort(IntArr(a), CmpFn{
ia := []int(a)
return ia[i] < ia[j]
})
}

fn main() {
nums := []int{ 3, 1, 4, 1, 5, 9, 2 }
printf("nums: %v\n", nums)
sortInt(nums)
printf("nums: %v\n", nums)
}


//~~
type Arr* = interface {
	len(): int
	swap(i, j: int)
}

type CmpFn* = fn(a: Arr, i, j: int): bool
//~~

fn partition(a: Arr, f: CmpFn, s, e: int): int {
	i := s - 1
	for j:=s; j < e; j++ {
		if !f(a, j, e - 1) { continue }

		i++
		a.swap(i, j)
	}

	i++
	a.swap(i, e - 1)

	return i
}

fn quicksort(a: Arr, f: CmpFn, s, e: int) {
	if s >= e || s < 0 { return }

	pivot := partition(a, f, s, e)

	quicksort(a, f, s, pivot)
	quicksort(a, f, pivot + 1, e)
}

//~~fn sort
fn sort*(a: Arr, f: CmpFn) {
//~~
	quicksort(a, f, 0, a.len())
}

//~~
type IntArr* = []int

fn (this: ^IntArr) len(): int {
	return len(this^)
}

fn (this: ^IntArr) swap(i, j: int) {
	t := this[i]
	this[i] = this[j]
	this[j] = t
}

fn sortInt*(a: []int) {
	sort(IntArr(a), CmpFn{
		ia := []int(a)
		return ia[i] < ia[j]
	})
}

fn main() {
	nums := []int{ 3, 1, 4, 1, 5, 9, 2 }
	printf("nums: %v\n", nums)
	sortInt(nums)
	printf("nums: %v\n", nums)
}
//~~