diff --git a/go.mod b/go.mod index 00af88c..c15a03b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module go-dsa -go 1.22 +go 1.23 diff --git a/go.work b/go.work index aa31f9e..d631528 100644 --- a/go.work +++ b/go.work @@ -1,3 +1,10 @@ -go 1.22.6 +go 1.23 + +toolchain go1.23.3 use ./hash_set + +use ( + . + ./stack +) diff --git a/readme.md b/readme.md index 8d97217..262cd68 100644 --- a/readme.md +++ b/readme.md @@ -7,8 +7,8 @@ What better way to learn a language and new concepts exists other than practicin ## Data Structures -* Hash - Set [Implementation](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set.go) | [Tests](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set_test.go) +* Hash Set [Implementation](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set.go) | [Tests](https://github.com/dnutiu/dsa-go/blob/master/hash_set/hash_set/hash_set_test.go) +* Generic Stack ### Other diff --git a/stack/go.mod b/stack/go.mod new file mode 100644 index 0000000..9b1277c --- /dev/null +++ b/stack/go.mod @@ -0,0 +1,10 @@ +module stack + +go 1.23 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.10.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/stack/stack.go b/stack/stack.go new file mode 100644 index 0000000..96c35ae --- /dev/null +++ b/stack/stack.go @@ -0,0 +1,49 @@ +package main + +import "errors" + +// Stack is a simple stack implementation that holds uint16 data. +type Stack[T any] struct { + storage []T + stackSize uint32 +} + +// NewStack creates a new Stack instance. +func NewStack[T any]() *Stack[T] { + return &Stack[T]{ + storage: make([]T, 0, 128), + stackSize: 0, + } +} + +// Push pushes data into the stack. +func (s *Stack[T]) Push(data T) { + s.stackSize += 1 + s.storage = append(s.storage, data) +} + +// Pop pops an element from the stack. +func (s *Stack[T]) Pop() (T, error) { + var whatever T + if s.stackSize == 0 { + return whatever, errors.New("stack is empty") + } + data := s.storage[s.stackSize-1] + s.stackSize -= 1 + return data, nil +} + +// Peek peeks at the latest data stored on the stack. +func (s *Stack[T]) Peek() T { + return s.storage[s.stackSize-1] +} + +// Size returns the current size of the stack. +func (s *Stack[T]) Size() uint32 { + return s.stackSize +} + +// IsEmpty returns true if the stack is empty, false otherwise. +func (s *Stack[T]) IsEmpty() bool { + return s.stackSize == 0 +} diff --git a/stack/stack_test.go b/stack/stack_test.go new file mode 100644 index 0000000..d3dd7d8 --- /dev/null +++ b/stack/stack_test.go @@ -0,0 +1,52 @@ +package main + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestStack_NewStack(t *testing.T) { + // Given + stack := NewStack[string]() + + // Then + assert.NotNil(t, stack) +} + +func TestStack_BasicOperations(t *testing.T) { + // Given + stack := NewStack[uint16]() + + // Then + stack.Push(uint16(2)) + stack.Push(uint16(13)) + + assert.Equal(t, uint32(2), stack.Size()) + assert.Equal(t, uint16(13), stack.Peek()) + + data, err := stack.Pop() + assert.Equal(t, uint16(13), data) + assert.Equal(t, uint32(1), stack.Size()) + assert.NoError(t, err) + data, err = stack.Pop() + assert.Equal(t, uint16(2), data) + assert.Equal(t, uint32(0), stack.Size()) + assert.NoError(t, err) + + data, err = stack.Pop() + assert.Error(t, err) +} + +func TestStack_IsEmpty(t *testing.T) { + // Given + stack := NewStack[int]() + + // Then + assert.True(t, stack.IsEmpty()) + + stack.Push(1) + assert.False(t, stack.IsEmpty()) + + _, _ = stack.Pop() + assert.True(t, stack.IsEmpty()) +}