Refactoring : isolate stack manipulation into their own package

This commit is contained in:
Julien Dessaux 2021-11-12 15:26:16 +01:00
parent 71099a8a4e
commit c913c2ae46
7 changed files with 195 additions and 146 deletions

8
pkg/stack/min.go Normal file
View file

@ -0,0 +1,8 @@
package stack
func min(a, b int) int {
if a < b {
return a
}
return b
}

105
pkg/stack/stack.go Normal file
View file

@ -0,0 +1,105 @@
package stack
type Stack struct {
size int
height int
data []int
next *Stack // Pointer to the next element in the stack stack
}
func NewStack(size int, next *Stack) *Stack {
return &Stack{
size: size,
height: 0,
data: make([]int, size),
next: next,
}
}
func (s *Stack) Clear() {
s.height = 0
}
func (s *Stack) Duplicate() {
if s.height > 0 {
s.Push(s.data[s.height-1])
} else {
s.Push(0)
s.Push(0)
}
}
func (s *Stack) Pop() int {
if s.height > 0 {
s.height--
return s.data[s.height]
}
return 0
}
func (s *Stack) Push(value int) {
if s.height >= s.size {
s.size += 32
s.data = append(s.data, make([]int, 32)...)
}
s.data[s.height] = value
s.height++
}
func (s *Stack) Swap() {
a := s.Pop()
b := s.Pop()
s.Push(a)
s.Push(b)
}
func (s Stack) GetHeights() []int {
if s.next != nil {
return append(s.next.GetHeights(), s.height)
} else {
return []int{s.height}
}
}
func (toss *Stack) Transfert(soss *Stack, n int) {
// Implements a value transfert between two stacks, intended for use with the '{'
// (aka begin) and '}' (aka end) stackstack commands
toss.height += n
if toss.height > toss.size {
toss.data = append(toss.data, make([]int, toss.height-toss.size)...)
toss.size = toss.height
}
for i := 1; i <= min(soss.height, n); i++ {
toss.data[toss.height-i] = soss.data[soss.height-i]
for i := min(soss.height, n) + 1; i <= n; i++ {
toss.data[toss.height-i] = 0
}
}
soss.height -= n
if soss.height < 0 {
soss.height = 0
}
}
func (s Stack) Next() *Stack {
return s.next
}
func (s *Stack) Discard(n int) {
// Implements a discard mechanism intended for use with the '}'(aka end) stackstack command
s.height -= n
if s.height < 0 {
s.height = 0
}
}
func (s *Stack) YCommandPick(n int, h int) {
if n > s.height {
s.height = 1
s.data[0] = 0
} else {
v := s.data[s.height-n]
s.height = h
s.Push(v)
}
}

83
pkg/stack/stack_test.go Normal file
View file

@ -0,0 +1,83 @@
package stack
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestClear(t *testing.T) {
s := NewStack(32, nil)
s.Clear()
require.Equal(t, 0, s.height)
}
func TestDupicate(t *testing.T) {
expected := NewStack(32, nil)
expected.height = 2
s := NewStack(32, nil)
s.Duplicate()
require.Equal(t, expected.height, s.height)
s.Push(12)
s.Duplicate()
expected.Push(12)
expected.Push(12)
require.Equal(t, expected.height, s.height)
require.Equal(t, expected.data, s.data)
}
func TestPop(t *testing.T) {
s := NewStack(32, nil)
v := s.Pop()
require.Equal(t, 0, v)
s.Push(12)
s.Push(14)
v = s.Pop()
require.Equal(t, 14, v)
v = s.Pop()
require.Equal(t, 12, v)
v = s.Pop()
require.Equal(t, 0, v)
}
func TestPush(t *testing.T) {
s := NewStack(32, nil)
for i := 0; i < 32; i++ {
s.Push(i)
}
require.Equal(t, 32, s.size)
s.Push(-1)
require.Equal(t, 64, s.size)
}
func TestSwap(t *testing.T) {
s := NewStack(32, nil)
s2 := NewStack(32, nil)
s.Swap()
s2.Push(0)
s2.Push(0)
require.Equal(t, s2, s)
s.Clear()
s.Push(1)
s.Swap()
s2.Clear()
s2.Push(1)
s2.Push(0)
require.Equal(t, s2, s)
s.Clear()
s.Push(1)
s.Push(2)
s2.Clear()
s2.Push(2)
s2.Push(1)
s.Swap()
require.Equal(t, s2, s)
}
func TestHeights(t *testing.T) {
// TODO
}
func TestTransfert(t *testing.T) {
// TODO
}