aboutsummaryrefslogtreecommitdiff
path: root/lib/ints/ints.go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ints/ints.go')
-rw-r--r--lib/ints/ints.go396
1 files changed, 0 insertions, 396 deletions
diff --git a/lib/ints/ints.go b/lib/ints/ints.go
deleted file mode 100644
index 4e252420..00000000
--- a/lib/ints/ints.go
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ints provide a library for working with slice of integer.
-package ints
-
-import (
- "sort"
-)
-
-// Count number of class in data.
-func Count(d []int, class int) (count int) {
- if len(d) == 0 {
- return
- }
- for x := 0; x < len(d); x++ {
- if d[x] == class {
- count++
- }
- }
- return
-}
-
-// Counts number of each class in slice.
-//
-// For example, if data is "[1,1,2]" and classes is "[1,2]", this function
-// will return "[2,1]".
-func Counts(d, classes []int) (counts []int) {
- if len(classes) == 0 {
- return
- }
- counts = make([]int, len(classes))
- for x, c := range classes {
- counts[x] = Count(d, c)
- }
- return
-}
-
-// IndirectSort sort the data and return the sorted index.
-func IndirectSort(d []int, asc bool) (sortedIdx []int) {
- sortedIdx = make([]int, len(d))
- for i := 0; i < len(d); i++ {
- sortedIdx[i] = i
- }
-
- InplaceMergesort(d, sortedIdx, 0, len(d), asc)
-
- return
-}
-
-// InplaceInsertionSort will sort the data and their index using
-// insertion-sort algorithm.
-//
-// Parameters:
-// `d` is slice that will be sorted,
-// `ids` is indices of data,
-// `l` is starting index of slice to be sorted, and
-// `r` is end index of slice to be sorted.
-func InplaceInsertionSort(d, ids []int, l, r int, asc bool) {
- for x := l; x < r; x++ {
- for y := x + 1; y < r; y++ {
- if asc {
- if d[x] > d[y] {
- Swap(ids, x, y)
- Swap(d, x, y)
- }
- } else {
- if d[x] < d[y] {
- Swap(ids, x, y)
- Swap(d, x, y)
- }
- }
- }
- }
-}
-
-// InplaceMergesort sort the slice "d" in-place, without memory allocation,
-// using mergesort algorithm.
-func InplaceMergesort(d []int, idx []int, l, r int, asc bool) {
- if l+7 >= r {
- // If data length <= Threshold, then use insertion sort.
- InplaceInsertionSort(d, idx, l, r, asc)
- return
- }
-
- // Divide into left and right.
- c := ((r + l) / 2) + (r+l)%2
-
- // Sort left.
- InplaceMergesort(d, idx, l, c, asc)
-
- // Sort right.
- InplaceMergesort(d, idx, c, r, asc)
-
- // Merge sorted left and right.
- if asc {
- if d[c-1] <= d[c] {
- // If the last element of the left is lower then
- // the first element of the right, i.e. [1 2] [3 4];
- // no merging needed, return immediately.
- return
- }
- } else {
- if d[c-1] >= d[c] {
- return
- }
- }
-
- inplaceMerge(d, idx, l, c, r, asc)
-}
-
-// IsExist will return true if value `v` exist in slice of `d`,
-// otherwise it will return false.
-func IsExist(d []int, v int) bool {
- for x := 0; x < len(d); x++ {
- if d[x] == v {
- return true
- }
- }
- return false
-}
-
-// Max find the maximum value in slice and return its value and index.
-//
-// If slice is empty, it will return false in ok.
-func Max(d []int) (v int, i int, ok bool) {
- if len(d) == 0 {
- return
- }
- v = d[0]
- i = 0
- for x := 1; x < len(d); x++ {
- if d[x] > v {
- v = d[x]
- i = x
- }
- }
- return v, i, true
-}
-
-// MaxCountOf count number of occurrence of each element of classes
-// in data and return the class with maximum count.
-//
-// If `classes` is empty, it will return -1 and false.
-// If `data` is empty, it will return -2 and false.
-// If classes has the same count value, then the first max in the class will be
-// returned.
-//
-// For example, given a data [5, 6, 5, 6, 5] and classes [5, 6, 7], the
-// function will count 5 as 3, 6 as 2, and 7 as 0.
-// Since frequency of 5 is greater than 6 and 7, then it will return `5` and
-// `true`.
-func MaxCountOf(d, classes []int) (int, bool) {
- if len(classes) == 0 {
- return -1, false
- }
- if len(d) == 0 {
- return -2, false
- }
-
- counts := Counts(d, classes)
-
- _, i, _ := Max(counts)
-
- return classes[i], true
-}
-
-// MaxRange find the (last) maximum value in slice between index "l" and "r".
-//
-// WARNING: This function does not check index out of range.
-func MaxRange(d []int, l, r int) (v, i int) {
- v = d[l]
- i = l
- for l++; l < r; l++ {
- if d[l] >= v {
- v = d[l]
- i = l
- }
- }
- return
-}
-
-// MergeByDistance merge two slice of integers by their distance between each
-// others.
-//
-// For example, if slice a contains "{1, 5, 9}" and b contains
-// "{4, 11, 15}" and the distance is 3, the output of merged is
-// "{1, 5, 9, 15}". The 4 and 11 are not included because 4 is in
-// range between 1 and (1+3), and 11 is in range between 9 and 9+3.
-func MergeByDistance(a, b []int, distance int) (out []int) {
- lenab := len(a) + len(b)
- if lenab == 0 {
- return nil
- }
-
- ab := make([]int, 0, lenab)
- ab = append(ab, a...)
- ab = append(ab, b...)
-
- sort.Ints(ab)
-
- out = append(out, ab[0])
- last := ab[0]
- for x := 1; x < len(ab); x++ {
- if ab[x] > last+distance {
- out = append(out, ab[x])
- last = ab[x]
- continue
- }
- }
-
- return out
-}
-
-// Min find the minimum value in slice and return its value and index.
-//
-// If slice is empty, it will return false in ok.
-func Min(d []int) (v int, i int, ok bool) {
- if len(d) == 0 {
- return
- }
- v = d[0]
- i = 0
- for x := 1; x < len(d); x++ {
- if d[x] < v {
- v = d[x]
- i = x
- }
- }
- return v, i, true
-}
-
-// MinRange find the (last) minimum value in slice between index "l" and "r".
-//
-// WARNING: This function does not check index out of range.
-func MinRange(d []int, l, r int) (v, i int) {
- v = d[l]
- i = l
- for l++; l < r; l++ {
- if d[l] <= v {
- v = d[l]
- i = l
- }
- }
- return
-}
-
-// Remove value "v" from slice if its exist and return new slice and true;
-// otherwise, if not found, return unmodified slice and false.
-func Remove(d []int, v int) ([]int, bool) {
- for x := 0; x < len(d); x++ {
- if d[x] == v {
- d = append(d[:x], d[x+1:]...)
- return d, true
- }
- }
- return d, false
-}
-
-// SortByIndex will sort the slice `d` using sorted index `sortedListID`.
-func SortByIndex(d *[]int, sortedListID []int) {
- newd := make([]int, len(*d))
-
- for x := 0; x < len(sortedListID); x++ {
- newd[x] = (*d)[sortedListID[x]]
- }
-
- (*d) = newd
-}
-
-// Sum all value in slice.
-func Sum(d []int) (sum int) {
- for x := 0; x < len(d); x++ {
- sum += d[x]
- }
- return
-}
-
-// Swap two indices value of slice.
-func Swap(d []int, x, y int) {
- if x == y || len(d) <= 1 || x > len(d) || y > len(d) {
- return
- }
- d[x], d[y] = d[y], d[x]
-}
-
-// To64 convert slice of integer to 64 bit values.
-func To64(ints []int) []int64 {
- i64 := make([]int64, len(ints))
- for x, v := range ints {
- i64[x] = int64(v)
- }
- return i64
-}
-
-// Let `x` be the first index of left-side, `y` be the first index of
-// the right-side, and `r` as length of slice `d`
-func inplaceMerge(d []int, idx []int, x, y, r int, asc bool) {
- var ylast int
-
- // (4.3) Loop until either x or y reached the maximum slice.
- for x < r && y < r {
- // (4.3.1) IF DATA[x] <= DATA[y]
- if asc {
- if d[x] <= d[y] {
- x++
-
- // (4.3.1.2) IF x > y THEN GOTO 4.3
- if x >= y {
- goto next
- }
-
- // (4.3.1.3) GOTO 4.3
- continue
- }
- } else {
- if d[x] >= d[y] {
- x++
-
- if x >= y {
- goto next
- }
-
- continue
- }
- }
-
- // (4.3.2) LET YLAST := the next DATA[y] that is less DATA[x]
- ylast = moveY(d, x, y, r, asc)
-
- // (4.3.3) SWAP DATA, X, Y, YLAST
- inplaceMultiswap(d, idx, x, y, ylast)
-
- next:
- // (4.3.4) LET Y := the minimum value between x and r on `d`
- minY(d, &x, &y, r, asc)
- }
-}
-
-func inplaceMultiswap(d []int, idx []int, x, y, ylast int) int {
- for y < ylast {
- Swap(idx, x, y)
- Swap(d, x, y)
- x++
- y++
- if y >= ylast {
- return y
- }
- if d[x] <= d[y] {
- return y
- }
- }
-
- return y
-}
-
-// (4.3.4) LET Y := the minimum value between x and r on `d`.
-func minY(d []int, x, y *int, r int, asc bool) {
- for *x < r {
- if asc {
- _, *y = MinRange(d, *x, r)
- } else {
- _, *y = MaxRange(d, *x, r)
- }
-
- if *y != *x {
- break
- }
- (*x)++
- }
-}
-
-func moveY(d []int, x, y, r int, asc bool) int {
- yorg := y
- y++
- for y < r {
- if asc {
- if d[y] >= d[x] {
- break
- }
- if d[y] < d[yorg] {
- break
- }
- } else {
- if d[y] <= d[x] {
- break
- }
- if d[y] > d[yorg] {
- break
- }
- }
- y++
- }
- return y
-}