Skip to content

Commit

Permalink
Merge 024df3f into 5599f40
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Aug 30, 2019
2 parents 5599f40 + 024df3f commit fe93d6d
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ problems from
* [Day 350](https://github.com/vaskoz/dailycodingproblem-go/issues/695)
* [Day 352](https://github.com/vaskoz/dailycodingproblem-go/issues/699)
* [Day 353](https://github.com/vaskoz/dailycodingproblem-go/issues/701)
* [Day 356](https://github.com/vaskoz/dailycodingproblem-go/issues/705)
* [Day 359](https://github.com/vaskoz/dailycodingproblem-go/issues/708)
* [Day 360](https://github.com/vaskoz/dailycodingproblem-go/issues/709)
* [Day 361](https://github.com/vaskoz/dailycodingproblem-go/issues/712)
Expand Down
102 changes: 102 additions & 0 deletions day356/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package day356

import "errors"

const fixedArraySize = 10

var errEmpty = errors.New("queue is empty")
var errFull = errors.New("queue is full")

// ErrEmpty is the error returned if queue is empty.
func ErrEmpty() error {
return errEmpty
}

// ErrFull is the error returned if queue is full.
func ErrFull() error {
return errFull
}

// NewQueueFLA returns a new instance of QueueFLA
// with a given capacity.
func NewQueueFLA(capacity int) QueueFLA {
slots := capacity / fixedArraySize
if capacity%fixedArraySize != 0 {
slots++
}
return &queueFLA{
set: make([][fixedArraySize]interface{}, slots),
size: 0,
capacity: capacity,
frontSlot: -1,
frontPos: -1,
backSlot: -1,
backPos: -1,
}
}

// QueueFLA is a queue implemented using a set
// of fixed-length arrays.
// In this implementation, the fixed array size is 10.
type QueueFLA interface {
Enqueue(interface{}) error
Dequeue() (interface{}, error)
Size() int
}

type queueFLA struct {
set [][fixedArraySize]interface{}
size, capacity int
frontSlot, frontPos int
backSlot, backPos int
}

// Enqueue attempts to add an item to the queue if there is room.
func (q *queueFLA) Enqueue(item interface{}) error {
if q.size == q.capacity {
return errFull
}
q.size++
if q.frontSlot == -1 && q.frontPos == -1 {
q.frontSlot++
q.frontPos++
q.set[q.frontSlot][q.frontPos] = item
q.backSlot++
q.backPos++
} else {
q.backPos++
if q.backPos == fixedArraySize {
q.backPos = 0
q.backSlot++
if q.backSlot == len(q.set) {
q.backSlot = 0
}
}
q.set[q.backSlot][q.backPos] = item
}
return nil
}

// Dequeue attempts to remove an item from the queue if
// the queue is not empty.
func (q *queueFLA) Dequeue() (interface{}, error) {
if q.size == 0 {
return nil, errEmpty
}
q.size--
res := q.set[q.frontSlot][q.frontPos]
q.frontPos++
if q.frontPos == fixedArraySize {
q.frontPos = 0
q.frontSlot++
if q.frontSlot == len(q.set) {
q.frontSlot = 0
}
}
return res, nil
}

// Size returns the number of elements currently in the queue.
func (q *queueFLA) Size() int {
return q.size
}
81 changes: 81 additions & 0 deletions day356/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package day356

import "testing"

type action struct {
act string
data interface{}
err error
}

// nolint
var testcases = []struct {
actions []action
}{
{
[]action{
{"E", 100, nil}, {"S", 1, nil}, {"D", 100, nil},
{"D", nil, ErrEmpty()},
},
},
{
[]action{
{"E", 100, nil}, {"E", 200, nil}, {"E", 300, nil}, {"E", 400, nil}, {"E", 500, nil},
{"S", 5, nil}, {"E", 1000, ErrFull()},
{"D", 100, nil}, {"D", 200, nil},
{"S", 3, nil},
{"D", 300, nil}, {"D", 400, nil},
{"S", 1, nil},
{"E", 600, nil}, {"E", 700, nil}, {"E", 800, nil}, {"E", 900, nil},
{"E", 1000, ErrFull()},
{"D", 500, nil}, {"D", 600, nil}, {"D", 700, nil}, {"D", 800, nil},
{"S", 1, nil},
{"E", 1000, nil}, {"E", 1100, nil}, {"E", 1200, nil}, {"E", 1300, nil},
{"S", 5, nil},
{"D", 900, nil}, {"D", 1000, nil}, {"D", 1100, nil}, {"D", 1200, nil}, {"D", 1300, nil},
{"S", 0, nil},
{"D", nil, ErrEmpty()},
},
},
}

func TestQueueFLA(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
q := NewQueueFLA(5)
for _, action := range tc.actions {
switch action.act {
case "E":
if err := q.Enqueue(action.data); err != action.err {
t.Errorf("Expected %v, got %v", action.err, err)
}
case "D":
if item, err := q.Dequeue(); item != action.data || err != action.err {
t.Errorf("Expected (%v,%v), got (%v,%v)", action.data, action.err, item, err)
}
case "S":
if s := q.Size(); s != action.data {
t.Errorf("Expected a size of %d, got %d", action.data, s)
}
}
}
}
}

func BenchmarkQueueFLA(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
q := NewQueueFLA(5)
for _, action := range tc.actions {
switch action.act {
case "E":
q.Enqueue(action.data) // nolint
case "D":
q.Dequeue() // nolint
case "S":
q.Size()
}
}
}
}
}

0 comments on commit fe93d6d

Please sign in to comment.