Skip to content

Commit

Permalink
#1 3.3 Stack of Plates implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
krlv committed Apr 26, 2021
1 parent bca73c6 commit 1c8b4ea
Show file tree
Hide file tree
Showing 3 changed files with 622 additions and 1 deletion.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Solving programming questions from ["Cracking the Coding Interview 6th Edition"]
|---|-------------------------------|:-------------:|:---------:|
|3.1| [Three in one][39] | [tests][40] ||
|3.2| [Stack Min][41] | [tests][42] ||
|3.3| Stack of Plates | tests | |
|3.3| [Stack of Plates][43] | [tests][44] | |
|3.4| Queue via Stacks | tests | |
|3.5| Sort Stack | tests | |
|3.6| Animal Shelter | tests | |
Expand Down Expand Up @@ -87,3 +87,5 @@ Solving programming questions from ["Cracking the Coding Interview 6th Edition"]
[40]: ch03/01_three_in_one_test.go
[41]: ch03/02_stack_min.go
[42]: ch03/02_stack_min_test.go
[43]: ch03/03_stack_of_plates.go
[44]: ch03/03_stack_of_plates_test.go
135 changes: 135 additions & 0 deletions ch03/03_stack_of_plates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package ch03

import (
"errors"
)

// StackSet represents set of fixed (capped) stacks
type StackSet struct {
stacks []*FixedStack
}

// Pop returns (and removes) the top item from the top stack
// If the top stack is empty, it will be removed from the set
func (set *StackSet) Pop() (int, error) {
stack, err := set.topStack()
if err != nil {
return 0, err
}

value, err := stack.Pop()
if err != nil {
return 0, err
}

if stack.IsEmpty() {
set.removeStack()
}

return value, nil
}

// Push add an item to the top stack
// If the top stack is full, new stack will be created
// and appended to the set
func (set *StackSet) Push(data int) error {
stack, err := set.topStack()
if err != nil {
stack = set.appendStack()
}

if stack.IsFull() {
stack = set.appendStack()
}

return stack.Push(data)
}

// TopStack returns the top stack from the set
func (set *StackSet) topStack() (*FixedStack, error) {
n := len(set.stacks) - 1
if n < 0 {
return nil, errors.New("set is empty")
}

return set.stacks[n], nil
}

// AppendStack adds a new stack to the set
func (set *StackSet) appendStack() *FixedStack {
stack := NewFixedStack(3)
set.stacks = append(set.stacks, stack)

return stack
}

// RemoveStack removes top stack from the set
func (set *StackSet) removeStack() {
n := len(set.stacks) - 1
if n >= 0 {
set.stacks = set.stacks[:n]
}
}

// FixedStack is a capped stack (stack length is limited to cap)
type FixedStack struct {
top *Item
len int
cap int
}

// NewFixedStack desc
func NewFixedStack(cap int) *FixedStack {
stack := new(FixedStack)
stack.len = 0
stack.cap = cap

return stack
}

// Pop returns (and removes) the top item from the stack
func (stack *FixedStack) Pop() (int, error) {
if stack.IsEmpty() {
return 0, errors.New("empty stack error")
}

top := stack.top
stack.top = top.next
stack.len--

return top.data, nil
}

// Push add an item to the stack
func (stack *FixedStack) Push(data int) error {
if stack.IsFull() {
return errors.New("full stack error")
}

top := New(data)
top.next = stack.top

stack.top = top
stack.len++

return nil
}

// Peek returns the top item from the satck (without removing it)
func (stack *FixedStack) Peek() (int, error) {
if stack.top == nil {
return 0, errors.New("empty Stack error")
}

return stack.top.data, nil
}

// IsEmpty returns true when stack is empty, false otherwise
func (stack *FixedStack) IsEmpty() bool {
return stack.top == nil
}

// IsFull returns true when stack is its max capacity, false otherwise
func (stack *FixedStack) IsFull() bool {
return stack.cap == stack.len
}
Loading

0 comments on commit 1c8b4ea

Please sign in to comment.