// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The sort package provides primitives for sorting arrays
// and user-defined collections.
package sort

// SortInterface is the interface that a type, typically a collection,
// must implement for its contents to be sorted in increasing order.
// Its methods require that the elements of the collection be enumerated
// by an integer index.
type SortInterface interface {
	// Len is the number of elements in the collection.
	Len() int;
	// Less returns whether the element with index i is should sort
	// before the element with index j.
	// TODO(r): should this method be renamed Before?
	Less(i, j int) bool;
	// Swap swaps the elements with indexes i and j.
	Swap(i, j int);
}

func min(a, b int) int {
	if a < b {
		return a;
	}
	return b;
}

// Insertion sort
func insertionSort(data SortInterface, a, b int) {
	for i := a+1; i < b; i++ {
		for j := i; j > a && data.Less(j, j-1); j-- {
			data.Swap(j, j-1);
		}
	}
}

// Quicksort, following Bentley and McIlroy,
// ``Engineering a Sort Function,'' SP&E November 1993.

// Move the median of the three values data[a], data[b], data[c] into data[a].
func medianOfThree(data SortInterface, a, b, c int) {
	m0 := b;
	m1 := a;
	m2 := c;
	// bubble sort on 3 elements
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	if data.Less(m2, m1) { data.Swap(m2, m1); }
	if data.Less(m1, m0) { data.Swap(m1, m0); }
	// now data[m0] <= data[m1] <= data[m2]
}

func swapRange(data SortInterface, a, b, n int) {
	for i := 0; i < n; i++ {
		data.Swap(a+i, b+i);
	}
}

func doPivot(data SortInterface, lo, hi int) (midlo, midhi int) {
	m := (lo+hi)/2;
	if hi - lo > 40 {
		// Tukey's ``Ninther,'' median of three medians of three.
		s := (hi - lo) / 8;
		medianOfThree(data, lo, lo+s, lo+2*s);
		medianOfThree(data, m, m-s, m+s);
		medianOfThree(data, hi-1, hi-1-s, hi-1-2*s);
	}
	medianOfThree(data, lo, m, hi-1);

	// Invariants are:
	//	data[lo] = pivot (set up by ChoosePivot)
	//	data[lo <= i < a] = pivot
	//	data[a <= i < b] < pivot
	//	data[b <= i < c] is unexamined
	//	data[c <= i < d] > pivot
	//	data[d <= i < hi] = pivot
	//
	// Once b meets c, can swap the "= pivot" sections
	// into the middle of the array.
	pivot := lo;
	a, b, c, d := lo+1, lo+1, hi, hi;
	for b < c {
		if data.Less(b, pivot) {	// data[b] < pivot
			b++;
			continue;
		}
		if !data.Less(pivot, b) {	// data[b] = pivot
			data.Swap(a, b);
			a++;
			b++;
			continue;
		}
		if data.Less(pivot, c-1) {	// data[c-1] > pivot
			c--;
			continue;
		}
		if !data.Less(c-1, pivot) {	// data[c-1] = pivot
			data.Swap(c-1, d-1);
			c--;
			d--;
			continue;
		}
		// data[b] > pivot; data[c-1] < pivot
		data.Swap(b, c-1);
		b++;
		c--;
	}

	n := min(b-a, a-lo);
	swapRange(data, lo, b-n, n);

	n = min(hi-d, d-c);
	swapRange(data, c, hi-n, n);

	return lo+b-a, hi-(d-c);
}

func quickSort(data SortInterface, a, b int) {
	if b - a > 7 {
		mlo, mhi := doPivot(data, a, b);
		quickSort(data, a, mlo);
		quickSort(data, mhi, b);
	} else if b - a > 1 {
		insertionSort(data, a, b);
	}
}

func Sort(data SortInterface) {
	quickSort(data, 0, data.Len());
}


func IsSorted(data SortInterface) bool {
	n := data.Len();
	for i := n - 1; i > 0; i-- {
		if data.Less(i, i - 1) {
			return false;
		}
	}
	return true;
}


// Convenience types for common cases

// IntArray attaches the methods of SortInterface to []int, sorting in increasing order.
type IntArray []int

func (p IntArray) Len() int            { return len(p); }
func (p IntArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p IntArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p IntArray) Sort()       { Sort(p); }


// FloatArray attaches the methods of SortInterface to []float, sorting in increasing order.
type FloatArray  []float

func (p FloatArray) Len() int            { return len(p); }
func (p FloatArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p FloatArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p FloatArray) Sort()       { Sort(p); }


// StringArray attaches the methods of SortInterface to []string, sorting in increasing order.
type StringArray []string

func (p StringArray) Len() int            { return len(p); }
func (p StringArray) Less(i, j int) bool  { return p[i] < p[j]; }
func (p StringArray) Swap(i, j int)       { p[i], p[j] = p[j], p[i]; }

// Sort is a convenience method.
func (p StringArray) Sort()       { Sort(p); }


// Convenience wrappers for common cases

// SortInts sorts an array of ints in increasing order.
func SortInts(a []int)        { Sort(IntArray(a)); }
// SortFloats sorts an array of floats in increasing order.
func SortFloats(a []float)    { Sort(FloatArray(a)); }
// SortStrings sorts an array of strings in increasing order.
func SortStrings(a []string)  { Sort(StringArray(a)); }


// IntsAreSorted tests whether an array of ints is sorted in increasing order.
func IntsAreSorted(a []int) bool       { return IsSorted(IntArray(a)); }
// FloatsAreSorted tests whether an array of floats is sorted in increasing order.
func FloatsAreSorted(a []float) bool   { return IsSorted(FloatArray(a)); }
// StringsAreSorted tests whether an array of strings is sorted in increasing order.
func StringsAreSorted(a []string) bool { return IsSorted(StringArray(a)); }
