parent
93e5e11194
commit
8747a22ec7
@ -0,0 +1,10 @@
|
||||
package sortedList
|
||||
|
||||
//List is empty
|
||||
type ErrListEmpty struct {
|
||||
S string
|
||||
}
|
||||
|
||||
func (err ErrListEmpty) Error() string {
|
||||
return err.S
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package sortedList
|
||||
|
||||
type num float64
|
||||
type elem interface{}
|
||||
|
||||
type SortedList struct {
|
||||
elems []*listElem
|
||||
}
|
||||
|
||||
type listElem struct {
|
||||
value num
|
||||
elem elem
|
||||
}
|
||||
|
||||
func (sl *SortedList) Insert(elem elem, value num) {
|
||||
newElem := listElem{
|
||||
value,
|
||||
elem,
|
||||
}
|
||||
|
||||
if len(sl.elems) == 0 {
|
||||
sl.elems = append(sl.elems, &newElem)
|
||||
} else {
|
||||
|
||||
//find i such that sl.elems[i].value < newElen.value
|
||||
var i int
|
||||
for i = 0; i < len(sl.elems) && sl.elems[i].value < newElem.value; i++ {
|
||||
}
|
||||
|
||||
//actual instertion at index = i
|
||||
previousElems := sl.elems[:i]
|
||||
forwardElems := make([]*listElem, len(sl.elems[i:]))
|
||||
copy(forwardElems, sl.elems[i:])
|
||||
|
||||
sl.elems = append(previousElems, &newElem)
|
||||
sl.elems = append(sl.elems, forwardElems...)
|
||||
}
|
||||
}
|
||||
|
||||
func (sl *SortedList) Nearest(value num) (elem, error) {
|
||||
|
||||
if len(sl.elems) == 0 {
|
||||
return listElem{}, &ErrListEmpty{"List has no nearest element"}
|
||||
}
|
||||
|
||||
if sl.elems[0].value > value {
|
||||
return sl.elems[0].elem, nil
|
||||
} else if len(sl.elems) == 1 {
|
||||
return sl.elems[0].elem, nil
|
||||
} else {
|
||||
//Find i such that sl.elems[i].value > value
|
||||
var i int
|
||||
for i = 1; i < len(sl.elems) && sl.elems[i].value < value; i++ {
|
||||
}
|
||||
//If there is no bigger elemet return last element
|
||||
if i == len(sl.elems) {
|
||||
return sl.elems[i-1].elem, nil
|
||||
|
||||
}
|
||||
biggerElem := sl.elems[i]
|
||||
smallerElem := sl.elems[i-1]
|
||||
|
||||
//Return the element closer to value
|
||||
switch {
|
||||
case (value - smallerElem.value) <= (biggerElem.value - value):
|
||||
return smallerElem.elem, nil
|
||||
case (value - smallerElem.value) > (biggerElem.value - value):
|
||||
return biggerElem.elem, nil
|
||||
}
|
||||
}
|
||||
panic("reached unreachable statement")
|
||||
}
|
||||
|
||||
func (sl *SortedList) Elems() []*listElem {
|
||||
return sl.elems
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package sortedList
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tools "gitlab.com/Pixdigit/goTestTools"
|
||||
)
|
||||
|
||||
func TestSortedList(t *testing.T) {
|
||||
list := SortedList{}
|
||||
list.Insert("a", 1)
|
||||
list.Insert("b", 2)
|
||||
list.Insert("c", 3)
|
||||
list.Insert("d", 5)
|
||||
list.Insert("e", 4)
|
||||
value, err := list.Nearest(3.2); if err != nil {tools.WrapErr(err, "could not get element from list", t)}
|
||||
tools.Test(value == "c", "did not get corrent element", t)
|
||||
value, err = list.Nearest(3.8); if err != nil {tools.WrapErr(err, "could not get element from list", t)}
|
||||
tools.Test(value == "e", "did not get corrent element", t)
|
||||
value, err = list.Nearest(8); if err != nil {tools.WrapErr(err, "could not get element from list", t)}
|
||||
tools.Test(value == "d", "did not get corrent element", t)
|
||||
value, err = list.Nearest(-2); if err != nil {tools.WrapErr(err, "could not get element from list", t)}
|
||||
tools.Test(value == "a", "did not get corrent element", t)
|
||||
value, err = list.Nearest(2); if err != nil {tools.WrapErr(err, "could not get element from list", t)}
|
||||
tools.Test(value == "b", "did not get corrent element", t)
|
||||
|
||||
}
|
Loading…
Reference in new issue