Skip to content

Commit

Permalink
Merge pull request #5 from geniussportsgroup/develop
Browse files Browse the repository at this point in the history
Added rotate and reverse methods
  • Loading branch information
lrleon authored Mar 24, 2021
2 parents ef3d5fa + 1eff977 commit b8c61e3
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
60 changes: 59 additions & 1 deletion slist.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func (seq *Slist) RemoveFirst() interface{} {
return ret
}

// Return the first element of the list
func (seq *Slist) First() interface{} {

if seq == nil {
Expand All @@ -124,13 +125,15 @@ func (seq *Slist) First() interface{} {
return seq.head.item
}

// Return the last element of the list
func (seq *Slist) Last() interface{} {
if seq == nil {
return nil
}
return seq.tail.item
}

// Return true if the list is empty
func (seq *Slist) Empty() *Slist {
seq.head = nil
seq.tail = nil
Expand All @@ -156,6 +159,7 @@ func (seq *Slist) staticAppendList(l *Slist) *Slist {
return seq
}

// Append to seq the received lists. Complexity O(n) where n is the number of received list
func (seq *Slist) AppendList(l *Slist, ln ...*Slist) *Slist {
seq.staticAppendList(l)
for _, ll := range ln {
Expand All @@ -169,47 +173,55 @@ type Iterator struct {
curr *Snode
}

// Return an iterator to the list
func NewIterator(seq *Slist) *Iterator {
it := new(Iterator)
it.listPtr = seq
it.curr = seq.head
return it
}

// Return an iterator to the list
func (seq *Slist) CreateIterator() interface{} {

return NewIterator(seq)
}

// Reset the iterator to the first element of the list
func (it *Iterator) ResetFirst() interface{} {

it.curr = it.listPtr.head
return it
}

// Return true if the iterator is positioned on a valid element
func (it *Iterator) HasCurr() bool {
return it.curr != nil
}

// Return true if the current element of the list is the last of the list
func (it *Iterator) IsLast() bool {
return it.curr == it.listPtr.tail
}

// Return the current element of the list
func (it *Iterator) GetCurr() interface{} {
if it.curr == nil {
return nil
}
return it.curr.item
}

// Advance the iterator to the next element of the list
func (it *Iterator) Next() interface{} {
it.curr = it.curr.next
if it.curr == nil {
return nil
}
return it.curr.item
return it
}

// Return the number of elements of the list
func (seq *Slist) Size() int {

n := 0
Expand All @@ -219,6 +231,8 @@ func (seq *Slist) Size() int {
return n
}

// Traverse the list and execute operation. It stops if the operation return false. Return true if
// all the elements of the list were traversed
func (seq *Slist) Traverse(operation func(key interface{}) bool) bool {

for it := NewIterator(seq); it.HasCurr(); it.Next() {
Expand All @@ -229,3 +243,47 @@ func (seq *Slist) Traverse(operation func(key interface{}) bool) bool {

return true
}

func (seq *Slist) clone() *Slist {
ret := New()
for it := NewIterator(seq); it.HasCurr(); it.Next() {
ret.Append(it.GetCurr())
}
return ret
}

// Reverse the list in place
func (seq *Slist) ReverseInPlace() *Slist {

tmp := New()

for !seq.IsEmpty() {
tmp.Insert(seq.RemoveFirst())
}

return seq.Swap(tmp).(*Slist)
}

// Return a reversed copy of seq
func (seq *Slist) Reverse() *Slist {
return seq.clone().ReverseInPlace()
}

// Rotate in place n positions to left
func (seq *Slist) RotateLeftInPlace(n int) *Slist {

if seq.IsEmpty() || n == 0 {
return seq
}

for i := 0; i < n; i++ {
seq.Append(seq.RemoveFirst())
}

return seq
}

// Return a copy of seq rotated n positions to left
func (seq *Slist) RotateLeft(n int) *Slist {
return seq.clone().RotateLeftInPlace(n)
}
48 changes: 48 additions & 0 deletions slist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,51 @@ func TestSlist_ToSlice(t *testing.T) {
i++
}
}

func TestSlist_clone(t *testing.T) {

l1 := New(1, 2, 3)
l2 := l1.clone()
for it1, it2 := NewIterator(l1), NewIterator(l2); it1.HasCurr() && it2.HasCurr(); {
assert.Equal(t, it1.GetCurr().(int), it2.GetCurr().(int))
it1.Next()
it2.Next()
}
}

func TestSlist_ReverseInPlace(t *testing.T) {

l := New(1, 2, 3)

l.ReverseInPlace()
assert.Equal(t, l.Size(), 3)
assert.Equal(t, l.First(), 3)
assert.Equal(t, l.Last(), 1)
}

func TestSlist_Reverse(t *testing.T) {

l := New(1, 2, 3)
r := l.Reverse()

assert.Equal(t, l.Size(), 3)
assert.Equal(t, l.First(), 1)
assert.Equal(t, l.Last(), 3)

assert.Equal(t, r.Size(), 3)
assert.Equal(t, r.First(), 3)
assert.Equal(t, r.Last(), 1)
}

func TestSlist_RotateLeftInPlace(t *testing.T) {

l := New(1, 2, 3, 4, 5)
lp := l.RotateLeft(2)
l.RotateLeftInPlace(2)

for it1, it2 := NewIterator(l), NewIterator(lp); it1.HasCurr() && it2.HasCurr(); {
assert.Equal(t, it1.GetCurr().(int), it2.GetCurr().(int))
it1.Next()
it2.Next()
}
}

0 comments on commit b8c61e3

Please sign in to comment.