From ac20be21e482fa1696a18a37f06d05774ac0d108 Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Fri, 6 Jan 2023 11:41:41 +0100 Subject: [PATCH] Added constructor function on linked list and stack data structures --- pkg/collection/linked_list.go | 8 +++ pkg/collection/linked_list_test.go | 106 +++++++++++++---------------- pkg/collection/stack.go | 31 ++++++++- pkg/collection/stack_test.go | 26 +++---- 4 files changed, 95 insertions(+), 76 deletions(-) diff --git a/pkg/collection/linked_list.go b/pkg/collection/linked_list.go index b7b65c6..bb3240d 100644 --- a/pkg/collection/linked_list.go +++ b/pkg/collection/linked_list.go @@ -70,6 +70,14 @@ type LinkedList[E any] struct { size int } +func NewLinkedList[E any](items ...E) *LinkedList[E] { + lst := &LinkedList[E]{} + for _, item := range items { + lst.PushBack(item) + } + return lst +} + func (l *LinkedList[E]) Iterator() Iterator[E] { if l.Empty() { return &emptyListIterator[E]{} diff --git a/pkg/collection/linked_list_test.go b/pkg/collection/linked_list_test.go index 521e81f..2eee8be 100644 --- a/pkg/collection/linked_list_test.go +++ b/pkg/collection/linked_list_test.go @@ -10,9 +10,9 @@ func TestLinkedList_Empty(t *testing.T) { list *LinkedList[int] want bool }{ - {description: "no items in list", list: newList(), want: true}, - {description: "one item in list", list: newList(1), want: false}, - {description: "more items in list", list: newList(1, 2, 3), want: false}, + {description: "no items in list", list: NewLinkedList[int](), want: true}, + {description: "one item in list", list: NewLinkedList(1), want: false}, + {description: "more items in list", list: NewLinkedList(1, 2, 3), want: false}, } for _, tt := range useCases { @@ -29,9 +29,9 @@ func TestLinkedList_Size(t *testing.T) { list *LinkedList[int] want int }{ - {description: "no items in list", list: newList(), want: 0}, - {description: "one item in list", list: newList(1), want: 1}, - {description: "more items in list", list: newList(1, 2, 3), want: 3}, + {description: "no items in list", list: NewLinkedList[int](), want: 0}, + {description: "one item in list", list: NewLinkedList(1), want: 1}, + {description: "more items in list", list: NewLinkedList(1, 2, 3), want: 3}, } for _, tt := range useCases { @@ -50,13 +50,13 @@ func TestLinkedList_GetAt(t *testing.T) { err error want int }{ - {description: "get first item", list: newList(1, 2, 3), pos: 0, want: 1, err: nil}, - {description: "get middle item", list: newList(1, 2, 3), pos: 1, want: 2, err: nil}, - {description: "get last item", list: newList(1, 2, 3), pos: 2, want: 3, err: nil}, - {description: "get last item", list: newList(1, 2, 3), pos: 2, want: 3, err: nil}, - {description: "no items in list return zero value of the type", list: newList(), pos: 0, want: 0, err: ErrEmptyList}, - {description: "get item with negative position", list: newList(1, 2, 3), pos: -1, want: 0, err: ErrPositionNegative}, - {description: "get item with index out of bound", list: newList(1, 2, 3), pos: 4, want: 0, err: ErrIndexOutOfBound{4, 3}}, + {description: "get first item", list: NewLinkedList(1, 2, 3), pos: 0, want: 1, err: nil}, + {description: "get middle item", list: NewLinkedList(1, 2, 3), pos: 1, want: 2, err: nil}, + {description: "get last item", list: NewLinkedList(1, 2, 3), pos: 2, want: 3, err: nil}, + {description: "get last item", list: NewLinkedList(1, 2, 3), pos: 2, want: 3, err: nil}, + {description: "no items in list return zero value of the type", list: NewLinkedList[int](), pos: 0, want: 0, err: ErrEmptyList}, + {description: "get item with negative position", list: NewLinkedList(1, 2, 3), pos: -1, want: 0, err: ErrPositionNegative}, + {description: "get item with index out of bound", list: NewLinkedList(1, 2, 3), pos: 4, want: 0, err: ErrIndexOutOfBound{4, 3}}, } for _, tt := range useCases { @@ -74,9 +74,9 @@ func TestLinkedList_Back(t *testing.T) { err error want int }{ - {description: "no items in list return zero value of the type", list: newList(), want: 0, err: ErrEmptyList}, - {description: "singleton list return first element", list: newList(1), want: 1}, - {description: "get last item", list: newList(1, 2, 3), want: 3}, + {description: "no items in list return zero value of the type", list: NewLinkedList[int](), want: 0, err: ErrEmptyList}, + {description: "singleton list return first element", list: NewLinkedList(1), want: 1}, + {description: "get last item", list: NewLinkedList(1, 2, 3), want: 3}, } for _, tt := range useCases { @@ -94,9 +94,9 @@ func TestLinkedList_Front(t *testing.T) { err error want int }{ - {description: "no items in list return zero value of the type", list: newList(), want: 0, err: ErrEmptyList}, - {description: "singleton list return first element", list: newList(1), want: 1}, - {description: "get first item", list: newList(1, 2, 3), want: 1}, + {description: "no items in list return zero value of the type", list: NewLinkedList[int](), want: 0, err: ErrEmptyList}, + {description: "singleton list return first element", list: NewLinkedList(1), want: 1}, + {description: "get first item", list: NewLinkedList(1, 2, 3), want: 1}, } for _, tt := range useCases { @@ -116,23 +116,23 @@ func TestLinkedList_PushAt(t *testing.T) { item int }{ {description: "add item in first position in empty list", - original: newList(), - modified: newList(1), + original: NewLinkedList[int](), + modified: NewLinkedList(1), pos: 0, item: 1}, {description: "add item in first position in full list", - original: newList(1, 2, 3), - modified: newList(0, 1, 2, 3), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(0, 1, 2, 3), pos: 0, item: 0}, {description: "add item in middle position in full list", - original: newList(1, 2, 3), - modified: newList(1, 2, 0, 3), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(1, 2, 0, 3), pos: 2, item: 0}, {description: "add item in last position in full list", - original: newList(1, 2, 3), - modified: newList(1, 2, 3, 0), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(1, 2, 3, 0), pos: 3, item: 0}, } @@ -154,16 +154,16 @@ func TestLinkedList_PushBack(t *testing.T) { item int }{ {description: "add item in first position in empty list", - original: newList(), - modified: newList(1), + original: NewLinkedList[int](), + modified: NewLinkedList(1), item: 1}, {description: "add item in singleton list", - original: newList(1), - modified: newList(1, 0), + original: NewLinkedList(1), + modified: NewLinkedList(1, 0), item: 0}, {description: "add item in full list", - original: newList(1, 2, 3), - modified: newList(1, 2, 3, 0), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(1, 2, 3, 0), item: 0}, } @@ -184,16 +184,16 @@ func TestLinkedList_PushFront(t *testing.T) { item int }{ {description: "add item in first position in empty list", - original: newList(), - modified: newList(1), + original: NewLinkedList[int](), + modified: NewLinkedList(1), item: 1}, {description: "add item in singleton list", - original: newList(1), - modified: newList(0, 1), + original: NewLinkedList(1), + modified: NewLinkedList(0, 1), item: 0}, {description: "add item in full list", - original: newList(1, 2, 3), - modified: newList(0, 1, 2, 3), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(0, 1, 2, 3), item: 0}, } @@ -214,33 +214,33 @@ func TestLinkedList_DeleteAt(t *testing.T) { err error }{ {description: "delete item with negative position", - original: newList(), + original: NewLinkedList[int](), modified: nil, pos: -1, err: ErrPositionNegative}, {description: "delete item in empty list", - original: newList(), + original: NewLinkedList[int](), modified: nil, pos: 0, err: ErrEmptyList}, {description: "delete item in position not found", - original: newList(1, 2, 3), - modified: newList(), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList[int](), pos: 5, err: ErrNodeNotFound}, {description: "delete item in first position", - original: newList(1, 2, 3), - modified: newList(2, 3), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(2, 3), pos: 0, err: nil}, {description: "delete item in middle position", - original: newList(1, 2, 3), - modified: newList(1, 3), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(1, 3), pos: 1, err: nil}, {description: "delete item in last position", - original: newList(1, 2, 3), - modified: newList(1, 2), + original: NewLinkedList(1, 2, 3), + modified: NewLinkedList(1, 2), pos: 2, err: nil}, } @@ -253,14 +253,6 @@ func TestLinkedList_DeleteAt(t *testing.T) { } } -func newList(items ...int) *LinkedList[int] { - lst := &LinkedList[int]{} - for _, item := range items { - lst.PushBack(item) - } - return lst -} - func compareLists(lst1, lst2 *LinkedList[int]) bool { for it := lst1.Iterator(); it.HasNext(); { i, item1 := it.NextWithIndex() diff --git a/pkg/collection/stack.go b/pkg/collection/stack.go index f4cebbc..05ce936 100644 --- a/pkg/collection/stack.go +++ b/pkg/collection/stack.go @@ -1,6 +1,9 @@ package collection -import "fmt" +import ( + "fmt" + "strings" +) var ( // ErrEmptyStack is error when you have an empty stack structure @@ -12,6 +15,15 @@ type Stack[E any] struct { items []E } +// NewStack is a constructor function for stack +func NewStack[E any](items ...E) *Stack[E] { + stack := &Stack[E]{} + for _, item := range items { + stack.Push(item) + } + return stack +} + // Size returns the number of items in the stack. func (s *Stack[E]) Size() int { return len(s.items) @@ -47,3 +59,20 @@ func (s *Stack[E]) Push(item E) error { s.items = append(s.items, item) return nil } + +func (s *Stack[E]) String() string { + var sb strings.Builder + sb.WriteString("[") + for i := 0; i < s.Size(); i++ { + var str string + item := s.items[i] + if i >= s.Size()-1 { + str = fmt.Sprintf("%v", item) + } else { + str = fmt.Sprintf("%v, ", item) + } + sb.WriteString(str) + } + sb.WriteString("]") + return sb.String() +} diff --git a/pkg/collection/stack_test.go b/pkg/collection/stack_test.go index 7b60e07..eb0e0ef 100644 --- a/pkg/collection/stack_test.go +++ b/pkg/collection/stack_test.go @@ -1,9 +1,7 @@ -package collection_test +package collection import ( "testing" - - "github.com/asd/pkg/collection" ) type pair struct { @@ -13,22 +11,22 @@ type pair struct { var staticTests = []struct { description string - input *collection.Stack[int] + input *Stack[int] empty bool size int top pair }{ - {"empty stack", newStack([]int{}), true, 0, pair{0, collection.ErrEmptyStack}}, - {"stack with items", newStack([]int{1, 2, 3}), false, 3, pair{3, nil}}, + {"empty stack", NewStack[int](), true, 0, pair{0, ErrEmptyStack}}, + {"stack with items", NewStack(1, 2, 3), false, 3, pair{3, nil}}, } var popTests = []struct { description string - input *collection.Stack[int] + input *Stack[int] item pair }{ - {"empty stack pop item", newStack([]int{}), pair{0, collection.ErrEmptyStack}}, - {"stack with items pop item", newStack([]int{1, 2, 3}), pair{3, nil}}, + {"empty stack pop item", NewStack[int](), pair{0, ErrEmptyStack}}, + {"stack with items pop item", NewStack(1, 2, 3), pair{3, nil}}, } var pushTests = []struct { @@ -79,7 +77,7 @@ func TestPush(t *testing.T) { for i, tt := range pushTests { t.Logf("Test %v: %s\n", i, tt.description) - stack := &collection.Stack[int]{} + stack := NewStack[int]() for _, item := range tt.items { stack.Push(item) } @@ -89,11 +87,3 @@ func TestPush(t *testing.T) { } } } - -func newStack(slice []int) *collection.Stack[int] { - stack := &collection.Stack[int]{} - for _, x := range slice { - stack.Push(x) - } - return stack -}