Implement a circular queue. If you haven’t used that before, a circular queue is a data structure in which the operations are performed based on the “First In First Out” principle, and the last position is connected back to the first position to make a circle.
Last active
April 27, 2020 18:51
-
-
Save thzinc/7d88746afb8263c8b32a5cc77aa52194 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module fifo-question | |
go 1.13 | |
require github.com/stretchr/testify v1.5.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | |
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | |
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= | |
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | |
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | |
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | |
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"strconv" | |
) | |
func main() { | |
// First argument is number of iterations through the queue | |
iterations, err := strconv.Atoi(os.Args[1]) | |
if err != nil { | |
panic(err) | |
} | |
// Remaining arguments are enqueued into the circular queue | |
queue := NewCircularQueue() | |
for _, a := range os.Args[2:] { | |
queue.Enqueue(a) | |
} | |
for i := 0; i < iterations; i++ { | |
if queue.TryMoveNext() { | |
item, err := queue.Current() | |
if err != nil { | |
panic(err) | |
} | |
fmt.Printf("%s\n", item) | |
} | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "errors" | |
type item struct { | |
value string | |
next *item | |
} | |
// CircularQueue is an implementation of a circular queue | |
type CircularQueue struct { | |
next *item | |
head *item | |
end *item | |
} | |
// NewCircularQueue creates a new circular queue | |
func NewCircularQueue() *CircularQueue { | |
return &CircularQueue{} | |
} | |
// Enqueue adds a value to the queue | |
func (q *CircularQueue) Enqueue(value string) { | |
new := &item{ | |
value: value, | |
} | |
if q.end == nil { | |
q.end = new | |
} else { | |
q.end.next = new | |
q.end = q.end.next | |
} | |
if q.head == nil { | |
q.head = q.end | |
} | |
} | |
// TryMoveNext attempts to move current to the next item | |
func (q *CircularQueue) TryMoveNext() bool { | |
if q.end == nil { | |
return false | |
} | |
if q.next == nil { | |
q.next = q.head | |
return true | |
} | |
q.next = q.next.next | |
if q.next == nil { | |
q.next = q.head | |
} | |
return true | |
} | |
// Current returns the current item | |
func (q *CircularQueue) Current() (string, error) { | |
if q.next == nil { | |
return "", errors.New("failed to get current item") | |
} | |
return q.next.value, nil | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"testing" | |
"github.com/stretchr/testify/assert" | |
) | |
func Test_Enqueue_SingleItem(t *testing.T) { | |
queue := NewCircularQueue() | |
assert.NotNil(t, queue) | |
queue.Enqueue("test") | |
ok := queue.TryMoveNext() | |
assert.True(t, ok) | |
item, err := queue.Current() | |
assert.Nil(t, err) | |
assert.EqualValues(t, "test", item) | |
ok = queue.TryMoveNext() | |
assert.True(t, ok) | |
item, err = queue.Current() | |
assert.Nil(t, err) | |
assert.EqualValues(t, "test", item) | |
} | |
func Test_Enqueue_MultipleItems(t *testing.T) { | |
queue := NewCircularQueue() | |
assert.NotNil(t, queue) | |
queue.Enqueue("one") | |
queue.Enqueue("two") | |
queue.Enqueue("three") | |
ok := queue.TryMoveNext() | |
assert.True(t, ok) | |
item, err := queue.Current() | |
assert.Nil(t, err) | |
assert.EqualValues(t, "one", item) | |
ok = queue.TryMoveNext() | |
assert.True(t, ok) | |
item, err = queue.Current() | |
assert.Nil(t, err) | |
assert.EqualValues(t, "two", item) | |
ok = queue.TryMoveNext() | |
assert.True(t, ok) | |
item, err = queue.Current() | |
assert.Nil(t, err) | |
assert.EqualValues(t, "three", item) | |
ok = queue.TryMoveNext() | |
assert.True(t, ok) | |
item, err = queue.Current() | |
assert.Nil(t, err) | |
assert.EqualValues(t, "one", item) | |
} | |
func Test_TryMoveNextBeforeEnqueue(t *testing.T) { | |
queue := NewCircularQueue() | |
assert.NotNil(t, queue) | |
ok := queue.TryMoveNext() | |
assert.False(t, ok) | |
} | |
func Test_CurrentBeforeEnqueue(t *testing.T) { | |
queue := NewCircularQueue() | |
assert.NotNil(t, queue) | |
_, err := queue.Current() | |
assert.NotNil(t, err) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment