Rebranding.

This commit is contained in:
Andrey Parhomenko 2023-10-24 00:48:29 +03:00
parent 8009ad0e84
commit 75a5d77699
13 changed files with 213 additions and 116 deletions

View file

@ -2,13 +2,28 @@ package main
import ( import (
"fmt" "fmt"
"github.com/mojosa-software/godat/llx" "github.com/reklesio/gods/lists"
) )
func main() { func main() {
ll := llx.New[string]("zero", "one", "two", "three", "four", "five") list := lists.NewSingly[string]("zero", "one", "two", "three", "four", "five")
ll.Push("-one", "-two") fmt.Println(list)
list.Push("-one", "-two")
fmt.Println(list)
ll.Swap(0, 2) list.Swap(0, 2)
fmt.Println(ll.Slice()) fmt.Println(list)
intList := lists.NewSingly[int](100, 5, -1, 1000, 200, 1337)
fmt.Println(intList)
intList.Sort(func(vi, vj int) bool {
return vi < vj
})
fmt.Println(intList)
intList.Sort(func(vi, vj int) bool {
return vj < vi
})
fmt.Println(intList)
} }

14
container.go Normal file
View file

@ -0,0 +1,14 @@
package gods
// All the containers must implement the interface.
type Container[V any] interface {
Empty() bool
Size() int
Clear()
Values() []V
//String() string
}
type Comparator[V any] interface {
Less(v1, v2 V)
}

10
errors.go Normal file
View file

@ -0,0 +1,10 @@
package gods
import (
"errors"
)
var (
IndexRangeErr = errors.New("index out of range")
)

2
go.mod
View file

@ -1,4 +1,4 @@
module github.com/mojosa-software/godat module github.com/reklesio/gods
go 1.19 go 1.19

34
lists/main.go Normal file
View file

@ -0,0 +1,34 @@
package lists
import (
"github.com/reklesio/gods"
)
// The interface all the lists must implement.
type List[V any] interface {
gods.Container[V]
Push(...V)
// Get length of the list
Len() int
// Get the value by index.
Get(int) V
// Delete the value by index.
Del(int)
// Change already existing value.
Set(int, V)
// Add the values
Add(...V)
// Insert the value before the specifed index.
InsB(V, int)
// Insert the value after the specified index.
InsA(int, V)
// Swap elements by indexes specified in arguments.
Swap(i, j int)
// The sort function that gets the Less function as argument
// and sorts the list corresponding to it.
Sort(gods.LessFunc[V])
}

View file

@ -1,111 +1,111 @@
package llx package lists
import (
"github.com/reklesio/gods"
"sort"
"fmt"
)
// Linked list X . // Linked list X .
// The package implements better variation of // The package implements better variation of
// linked list than in standard library since it uses // linked list than in standard library since it uses
// the new conception of generics. // the new conception of generics.
// The type represents linked list data structure. // The type represents singly linked list data structure.
type LinkedList[V any] struct { type sLinkedList[V any] struct {
// First empty element (not used to store values). // First empty element (not used to store values).
// For fast pushing. // For fast pushing.
before *Element[V] before *sElement[V]
// Points to the last for fast appending. // Points to the last for fast appending.
last *Element[V] last *sElement[V]
// Length. // Length.
ln int ln int
} }
// The type represents element of the linked list. // The type represents element of the linked list.
type Element[V any] struct { type sElement[V any] struct {
next *Element[V] next *sElement[V]
value V value V
} }
// Returns new empty linked list storing the V type. func newSingly[V any](values ...V) *sLinkedList[V] {
func New[V any](values ...V) *LinkedList[V] { ret := &sLinkedList[V]{
ret := &LinkedList[V]{ before: &sElement[V]{},
&Element[V]{}, last: nil,
nil, ln: 0,
0,
} }
ret.Append(values...) ret.Add(values...)
return ret return ret
} }
// Get length of the linked list. // Returns new empty linked list storing the V type.
func (ll *LinkedList[V]) Length() int { func NewSingly[V any](values ...V) List[V] {
return newSingly[V](values...)
}
func (ll *sLinkedList[V]) Empty() bool {
return ll == nil
}
func (ll *sLinkedList[V]) Size() int {
return ll.ln return ll.ln
} }
func (ll *LinkedList[V]) Len() int { func (ll *sLinkedList[V]) Clear() {
return ll.Length() buf := newSingly[V]()
*ll = *buf
} }
func (ll *sLinkedList[V]) Len() int {
return ll.ln
}
// Get the index-indexed element itself. // Get the index-indexed element itself.
func (ll *LinkedList[V]) GetEl(index int) (*Element[V], bool) { func (ll *sLinkedList[V]) getEl(index int) *sElement[V] {
if ll.ln <= index { if ll.ln <= index || index < 0 {
return nil, false panic(gods.IndexRangeErr)
} }
p := ll.before p := ll.before
for i := 0 ; i <= index ; i++ { for i := 0 ; i <= index ; i++ {
p = p.next p = p.next
} }
return p, true return p
} }
// Get the value of index-indexed element. // Get the value of index-indexed element.
func (ll *LinkedList[V]) Get(index int) (V, bool) { func (ll *sLinkedList[V]) Get(index int) V {
el, ok := ll.GetEl(index) return ll.getEl(index).value
var v V
if ok {
v = el.value
}
return v, ok
} }
// Set the new value in i-indexed element. // Set the new value in i-indexed element.
func (ll *LinkedList[V]) Set(i int, v V) (bool) { func (ll *sLinkedList[V]) Set(i int, v V) {
el, ok := ll.GetEl(i) el := ll.getEl(i)
if !ok {
return false
}
el.value = v el.value = v
return true
} }
// Insert the V value before the i-th element. // Insert the V value before the i-th element.
func (ll *LinkedList[V]) InsertBefore(v V, i int) { func (ll *sLinkedList[V]) InsB(v V, i int) {
if i == 0 { if i == 0 {
ll.before = &Element[V]{ ll.before = &sElement[V]{
value: v, value: v,
next: ll.before.next, next: ll.before.next,
} }
return return
} }
el, ok := ll.GetEl(i-1) el := ll.getEl(i-1)
if !ok { el.next = &sElement[V]{
panic("index out of range")
}
el.next = &Element[V]{
value: v, value: v,
next: el.next, next: el.next,
} }
} }
// Insert the V value after the i-th element. // Insert the V value after the i-th element.
func (ll *LinkedList[V]) InsertAfter(i int, v V) { func (ll *sLinkedList[V]) InsA(i int, v V) {
el, ok := ll.GetEl(i) el := ll.getEl(i)
if !ok { el.next = &sElement[V]{
panic("index out of range")
}
el.next = &Element[V]{
value: v, value: v,
next: el.next, next: el.next,
} }
@ -113,29 +113,20 @@ func (ll *LinkedList[V]) InsertAfter(i int, v V) {
// Swap element values indexed by i1 and i2. // Swap element values indexed by i1 and i2.
// Panic on "index out of range". // Panic on "index out of range".
func (ll *LinkedList[V]) Swap(i1, i2 int) { func (ll *sLinkedList[V]) Swap(i1, i2 int) {
if i1 == i2 { if i1 == i2 {
return return
} }
max := ll.ln - 1 el1 := ll.getEl(i1)
if i1 < 0 || i2 < 0 || i1 > max || i2 > max { el2 := ll.getEl(i2)
panic("index out of range")
}
el1, _ := ll.GetEl(i1)
el2, _ := ll.GetEl(i2)
el1.value, el2.value = el1.value, el2.value =
el2.value, el1.value el2.value, el1.value
} }
// Deletes the element by its index. // Deletes the element by its index.
func (ll *LinkedList[V]) Delete(i int) { func (ll *sLinkedList[V]) Del(i int) {
if ll.ln <= i && i < 0 {
panic("index out of range")
}
if i == 0 { if i == 0 {
ll.before.next = ll.before.next =
ll.before.next.next ll.before.next.next
@ -143,33 +134,28 @@ func (ll *LinkedList[V]) Delete(i int) {
return return
} }
el1, _ := ll.GetEl(i-1) el1 := ll.getEl(i-1)
if i == ll.ln - 1 { if i == ll.ln - 1 {
el1.next = nil el1.next = nil
} else { } else {
el2, _ := ll.GetEl(i+1) el2 := ll.getEl(i+1)
el1.next = el2 el1.next = el2
} }
ll.ln-- ll.ln--
} }
// Alias to Delete method.
func (ll *LinkedList[V]) Del(i int) {
ll.Delete(i)
}
// Push in the beginning of the list. // Push in the beginning of the list.
func (ll *LinkedList[V]) Push(values ...V) { func (ll *sLinkedList[V]) Push(values ...V) {
for _, value := range values { for _, value := range values {
ll.push(value) ll.push(value)
} }
} }
// Push in the beginning of the list. // Push in the beginning of the list.
func (ll *LinkedList[V]) push(v V) { func (ll *sLinkedList[V]) push(v V) {
prevNext := ll.before.next prevNext := ll.before.next
nextNext := &Element[V]{ nextNext := &sElement[V]{
next: prevNext, next: prevNext,
value: v, value: v,
} }
@ -182,19 +168,19 @@ func (ll *LinkedList[V]) push(v V) {
} }
// Append to the end of the list. // Append to the end of the list.
func (ll *LinkedList[V]) Append(values ...V) { func (ll *sLinkedList[V]) Add(values ...V) {
for _, value := range values { for _, value := range values {
ll.gappend(value) ll.gappend(value)
} }
} }
func (ll *LinkedList[V]) gappend(v V) { func (ll *sLinkedList[V]) gappend(v V) {
if ll.ln == 0 { if ll.ln == 0 {
ll.Push(v) ll.Push(v)
return return
} }
last := &Element[V]{ last := &sElement[V]{
next: nil, next: nil,
value: v, value: v,
} }
@ -207,28 +193,28 @@ func (ll *LinkedList[V]) gappend(v V) {
} }
// Returns the first element of the linked list. // Returns the first element of the linked list.
func (ll *LinkedList[V]) First() *Element[V] { func (ll *sLinkedList[V]) First() *sElement[V] {
return ll.before.next return ll.before.next
} }
// Get elements value. // Get elements value.
func (ll *Element[V]) Value() V { func (ll *sElement[V]) Value() V {
return ll.value return ll.value
} }
// Returns the next element. If the returned value == nil, // Returns the next element. If the returned value == nil,
// then it is the last element. // then it is the last element.
func (ll *Element[V]) Next() *Element[V] { func (ll *sElement[V]) Next() *sElement[V] {
return ll.next return ll.next
} }
// Returns the last element. // Returns the last element.
func (ll *LinkedList[V]) Last() *Element[V] { func (ll *sLinkedList[V]) Last() *sElement[V] {
return ll.last return ll.last
} }
// Returns a channel with values ordered as in list. // Returns a channel with values ordered as in list.
func (ll *LinkedList[V]) Chan() chan V { func (ll *sLinkedList[V]) Chan() chan V {
chn := make(chan V) chn := make(chan V)
go func(){ go func(){
el := ll.before el := ll.before
@ -242,19 +228,27 @@ func (ll *LinkedList[V]) Chan() chan V {
} }
// Returns slice of values in the list ordered as in the list. // Returns slice of values in the list ordered as in the list.
func (ll *LinkedList[V]) Slice() []V { func (ll *sLinkedList[V]) Values() []V {
buf := make([]V, ll.Length()) buf := make([]V, ll.Len())
chn := ll.Chan()
i := 0 i := 0
for v := range chn { el := ll.before
buf[i] = v for el.next != nil {
el = el.next
buf[i] = el.value
i++ i++
} }
return buf return buf
} }
func (ll *LinkedList[V]) Sort() { func (ll *sLinkedList[V]) String() string {
return fmt.Sprintf("%v", ll.Values())
}
func (ll *sLinkedList[V]) Sort(fn gods.LessFunc[V]) {
sort.Sort(gods.CustomSort[V]{
CustomSorter: ll,
LessFunc: fn,
})
} }

BIN
media/gopher.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View file

@ -1,5 +0,0 @@
MKSHELL = sh
<$(MKINCDIR)/config
WATCH_FILES = src tmpl
CC = cc

7
mkfile
View file

@ -1,7 +0,0 @@
all: build
build:V:
go build -o ./exe/ ./cmd/...
clean:V:
rm -f ./exe/*

8
readme
View file

@ -1,8 +0,0 @@
# godat
Golang custom data structures for specific purposes.
- Linked list: llx
- List: listx
- Sparse array: sparsex

10
readme.md Normal file
View file

@ -0,0 +1,10 @@
# Gods
![Put a gopher image here, please](https://raw.githubusercontent.com/reklesio/gods/main/media/gopher.png)
Golang data structures.
# Tasks
- [ ] Write the tasks

29
sort.go Normal file
View file

@ -0,0 +1,29 @@
package gods
type Getter[V any] interface {
Get(int) V
}
type Swapper interface {
Swap(i, j int)
Len() int
}
type CustomSorter[V any] interface {
Getter[V]
Swapper
}
type LessFunc[V any] func(v1, v2 V) bool
// The type implements way to sort
// swappers via custom function.
type CustomSort[V any] struct {
CustomSorter[V]
LessFunc LessFunc[V]
}
func (cs CustomSort[V]) Less(i, j int) bool {
vi, vj := cs.Get(i), cs.Get(j)
return cs.LessFunc(vi, vj)
}

11
stacks/main.go Normal file
View file

@ -0,0 +1,11 @@
package stacks
import (
"github.com/reklesio/gods"
)
type Stack[V any] interface {
gods.Container[V]
Push(V)
Pop() V
}