aboutsummaryrefslogtreecommitdiff
path: root/lib/ints/ints.go
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-12-28 22:14:09 +0700
committerShulhan <ms@kilabit.info>2024-12-29 00:06:17 +0700
commit7a57091317cd86b9c88f4c6b5127c76bee0f6ede (patch)
treef1ec2aac093ff02890a62068001be177c93c1486 /lib/ints/ints.go
parent5a00dfe102a3a06ddee1b79800060dd70231055b (diff)
downloadpakakeh.go-7a57091317cd86b9c88f4c6b5127c76bee0f6ede.tar.xz
all: merge package "lib/ints" and "lib/ints64" into "slices"
Now that Go has type parameter, we can use it to use the same function that accept different types for working with slice of int, int64.
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
-}