diff --git a/src/cmd/ll/main.go b/src/cmd/ll/main.go new file mode 100644 index 0000000..7d8c709 --- /dev/null +++ b/src/cmd/ll/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "github.com/mojosa-software/godat/src/llx" + + "fmt" +) + +func main() { + ll := llx.New[string]() + ll.Append("zero") + ll.Append("one") + ll.Append("two") + ll.Append("three") + ll.Append("four") + ll.Push("minus one") + + ll.Swap(1, 3) + + for p := range ll.Chan() { + fmt.Println(p.K, p.V) + } +} + diff --git a/src/cmd/pool/main.go b/src/cmd/pool/main.go new file mode 100644 index 0000000..b174f42 --- /dev/null +++ b/src/cmd/pool/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "github.com/mojosa-software/godat/src/poolx" + + "fmt" +) + +func main() { + values := []string{ + "zero", "one", + "should be deleted", + "two", "three", + } + pool := poolx.New[string]() + for _, v := range values { + pool.Append(v) + } + + pool.DeleteValue("should be deleted") + + for p := range pool.Chan() { + fmt.Println(p.K, p.V) + } +} + diff --git a/src/cmd/sparse/main.go b/src/cmd/sparse/main.go index e6ca2c2..69494e8 100644 --- a/src/cmd/sparse/main.go +++ b/src/cmd/sparse/main.go @@ -12,12 +12,12 @@ func main() { unord.Set(-4, "die") unord.Set(-1000, "withme") - for v := range unord.Vals() { - fmt.Println(v.K, v.V) + for p := range unord.Chan() { + fmt.Println(p.K, p.V) } unord.Sort() - for v := range unord.Vals() { - fmt.Println(v.K, v.V) + for p := range unord.Chan() { + fmt.Println(p.K, p.V) } } diff --git a/src/iterx/pair.go b/src/iterx/chan.go similarity index 100% rename from src/iterx/pair.go rename to src/iterx/chan.go diff --git a/src/iterx/misc.go b/src/iterx/misc.go new file mode 100644 index 0000000..a797eb1 --- /dev/null +++ b/src/iterx/misc.go @@ -0,0 +1,11 @@ +package iterx + +func ChanToSlice[V any](c chan V) []V { + ret := []V{} + for v := range c { + ret = append(ret, v) + } + + return ret +} + diff --git a/src/llx/main.go b/src/llx/main.go index e62a8fd..c6b0c87 100644 --- a/src/llx/main.go +++ b/src/llx/main.go @@ -5,6 +5,11 @@ package llx // linked list than in standard library since it uses // the new conception of generics. +import ( + "github.com/mojosa-software/godat/src/iterx" +) + +// The type represents linked list data structure. type LinkedList[V any] struct { // First empty element (not used to store values). // For fast pushing. @@ -15,17 +20,12 @@ type LinkedList[V any] struct { ln int } +// The type represents element of the linked list. type Element[V any] struct { next *Element[V] value V } -type Pair[V any] struct { - I int - V V -} - - // Returns new empty linked list storing the V type. func New[V any]() *LinkedList[V] { return &LinkedList[V]{ @@ -36,7 +36,7 @@ func New[V any]() *LinkedList[V] { } // Get length of the linked list. -func (ll *LinkedList[V]) Len() int { +func (ll *LinkedList[V]) Length() int { return ll.ln } @@ -75,7 +75,25 @@ func (ll *LinkedList[V]) Set(i int, v V) (bool) { return true } -func (ll *LinkedList[V]) Del(i int) (bool) { +func (ll *LinkedList[V]) Swap(i1, i2 int) { + if i1 == i2 { + return + } + + max := ll.ln - 1 + if i1 < 0 || i2 < 0 || i1 > max || i2 > max { + panic("index out of range") + } + + el1, _ := ll.GetEl(i1) + el2, _ := ll.GetEl(i2) + + el1.value, el2.value = + el2.value, el1.value +} + +// Deletes the element by its index. +func (ll *LinkedList[V]) Delete(i int) (bool) { if ll.ln <= i { return false } @@ -133,32 +151,40 @@ func (ll *LinkedList[V]) Append(v V) { ll.ln++ } +// Returns the first element of the linked list. func (ll *LinkedList[V]) First() *Element[V] { return ll.before.next } +// Get elements value. func (ll *Element[V]) Value() V { return ll.value } +// Returns the next element. If the returned value == nil, +// then it is the last element. func (ll *Element[V]) Next() *Element[V] { return ll.next } +// Returns the last element. func (ll *LinkedList[V]) Last() *Element[V] { return ll.last } // Returns a channel of Pair that contains index and the value. -func (ll *LinkedList[V]) Range() chan Pair[V] { - chn := make(chan Pair[V]) +func (ll *LinkedList[V]) Chan() iterx.PairChan[int, V] { + chn := make(iterx.PairChan[int, V]) go func(){ i := -1 el := ll.before for el.next != nil { i++ el = el.next - chn <- Pair[V]{i, el.value} + chn <- iterx.Pair[int, V]{ + K: i, + V: el.value, + } } close(chn) }() diff --git a/src/mapx/main.go b/src/mapx/main.go index 2d0f285..d0590f5 100644 --- a/src/mapx/main.go +++ b/src/mapx/main.go @@ -6,6 +6,7 @@ import ( // The package implements some more specific // map structures for special uses. +// Implemented mostly to be embedded to other structures. // General map type, wrap for the built-in one. type Map[K comparable, V any] map[K] V diff --git a/src/mapx/misc.go b/src/mapx/misc.go new file mode 100644 index 0000000..2499c53 --- /dev/null +++ b/src/mapx/misc.go @@ -0,0 +1,10 @@ +package mapx + +func Reversed[K, V comparable](m map[K] V) map[V] K { + r := make(map[V] K) + for k, v := range m { + r[v] = k + } + return r +} + diff --git a/src/poolx/main.go b/src/poolx/main.go index 220ecf9..102661f 100644 --- a/src/poolx/main.go +++ b/src/poolx/main.go @@ -2,6 +2,7 @@ package poolx import ( "github.com/mojosa-software/godat/src/llx" + "github.com/mojosa-software/godat/src/iterx" ) // Ordered value-only based structure. @@ -24,12 +25,12 @@ func (p *Pool[V]) Append(v V) { } // Deletes the first appearance of the value in the list. -func (p *Pool[V]) Del(v V) bool { +func (p *Pool[V]) DeleteValue(v V) bool { i := 0 ll := p.store for e := ll.First() ; e != nil ; e = e.Next() { if e.Value() == v { - ll.Del(i) + ll.Delete(i) return true } @@ -39,7 +40,7 @@ func (p *Pool[V]) Del(v V) bool { return false } -func (p *Pool[V]) Range() chan llx.Pair[V] { - return p.store.Range() +func (p *Pool[V]) Chan() iterx.PairChan[int, V] { + return p.store.Chan() } diff --git a/src/sparsex/main.go b/src/sparsex/main.go index bcfcb3f..2d392bc 100644 --- a/src/sparsex/main.go +++ b/src/sparsex/main.go @@ -3,38 +3,38 @@ package sparsex import ( "sort" cons "golang.org/x/exp/constraints" + "github.com/mojosa-software/godat/src/iterx" ) // The package implements a simple ordered map. // In fact can be used as a sparse array so it is // where the name comes from. -type Pair[K cons.Ordered, V any] struct { - K K - V V -} - +// The sparse array type. type Sparse[K cons.Ordered, V any] struct { store map[K] V keys []K shouldSort bool } -// Returns new sparse array -func New[K cons.Ordered, V any](s bool) *Sparse[K, V] { +// Returns new sparse array. +// If shouldSort == true then it will sort the array on +// each change. +func New[K cons.Ordered, V any](shouldSort bool) *Sparse[K, V] { return &Sparse[K, V]{ store: make(map[K] V), keys: []K{}, - shouldSort: s, + shouldSort: shouldSort, } } - +// Get the value by the key. func (s *Sparse[K, V]) Get(key K) (V, bool) { val, ok := s.store[key] return val, ok } +// Set the value to the key. func (s *Sparse[K, V]) Set(k K, v V) { _, ok := s.store[k] if !ok { @@ -47,7 +47,8 @@ func (s *Sparse[K, V]) Set(k K, v V) { s.store[k] = v } -func (s Sparse[K, V]) Del(k K) { +// Delete the value by the key. +func (s Sparse[K, V]) Delete(k K) { delete(s.store, k) // To know if the loop was run. @@ -68,16 +69,18 @@ func (s Sparse[K, V]) Del(k K) { } } -func (s *Sparse[K, V]) Vals( -) chan Pair[K, V] { +// Returns channel of pairs. +func (s *Sparse[K, V]) Chan( +) iterx.PairChan[K, V] { keys := s.keys store := s.store - ret := make(chan Pair[K, V]) + ret := make(iterx.PairChan[K, V]) go func() { - for _, v := range keys { - ret <- Pair[K, V]{ - v, store[v], + for _, k := range keys { + ret <- iterx.Pair[K, V]{ + K: k, + V: store[k], } } close(ret)