Skip to content

Commit

Permalink
Merge pull request #279 from vaskoz/day134
Browse files Browse the repository at this point in the history
Day134
  • Loading branch information
vaskoz committed Jan 3, 2019
2 parents c780962 + 8514cd6 commit 41cc56e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,4 @@ problems from
* [Day 131](https://github.com/vaskoz/dailycodingproblem-go/issues/270)
* [Day 132](https://github.com/vaskoz/dailycodingproblem-go/issues/272)
* [Day 133](https://github.com/vaskoz/dailycodingproblem-go/issues/275)
* [Day 134](https://github.com/vaskoz/dailycodingproblem-go/issues/278)
56 changes: 56 additions & 0 deletions day134/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package day134

import "fmt"

// SparseArray is a space-efficient array for one containing
// mostly zeros.
type SparseArray struct {
data map[int]int
size int
}

var errIndexOutOfRange = fmt.Errorf("Index is out of range")

// ErrIndexOutOfRange returns the error that's associated with access beyond
// the limits of the SparseArray.
func ErrIndexOutOfRange() error {
return errIndexOutOfRange
}

// NewSparseArray initializes a SparseArray with an original array.
func NewSparseArray(arr []int) *SparseArray {
sa := &SparseArray{make(map[int]int), len(arr)}
for i := range arr {
if arr[i] != 0 {
sa.data[i] = arr[i]
}
}
return sa
}

// Set mutates the value at position 'i' with value 'val'.
func (sa *SparseArray) Set(i, val int) error {
if sa == nil {
return fmt.Errorf("Create with NewSparseArray")
}
if i >= sa.size || i < 0 {
return errIndexOutOfRange
}
if val == 0 {
delete(sa.data, i)
} else {
sa.data[i] = val
}
return nil
}

// Get returns the value at position 'i'.
func (sa *SparseArray) Get(i int) (int, error) {
if sa == nil {
return 0, fmt.Errorf("Create with NewSparseArray")
}
if i >= sa.size || i < 0 {
return 0, errIndexOutOfRange
}
return sa.data[i], nil
}
59 changes: 59 additions & 0 deletions day134/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package day134

import (
"testing"
)

func TestSparseArray(t *testing.T) {
t.Parallel()
arr := []int{0, 0, 0, 0, 9, 8, 7, 6, 0, 0}
sa := NewSparseArray(arr)
for i, val := range arr {
if result, err := sa.Get(i); result != val || err != nil {
t.Errorf("Expected (%v,%v) got (%v,%v)", val, nil, result, err)
}
}
sa.Set(0, 10)
if result, err := sa.Get(0); result != 10 || err != nil {
t.Errorf("Set didn't work properly")
}
sa.Set(0, 0)
for i, val := range arr {
if result, err := sa.Get(i); result != val || err != nil {
t.Errorf("Expected (%v,%v) got (%v,%v)", val, nil, result, err)
}
}
}

func TestSparseArrayNoInit(t *testing.T) {
t.Parallel()
var sa *SparseArray
if err := sa.Set(0, 1); err == nil {
t.Errorf("Set returns an error if called before Init")
}
if _, err := sa.Get(0); err == nil {
t.Errorf("Get returns an error if called before Init")
}
}

func TestSparseArrayOutOfRange(t *testing.T) {
t.Parallel()
sa := NewSparseArray([]int{1})
if err := sa.Set(1, 1); err != ErrIndexOutOfRange() {
t.Errorf("Index 1 is out of range")
}
if _, err := sa.Get(-1); err != ErrIndexOutOfRange() {
t.Errorf("Index -1 is out of range")
}
}

func BenchmarkSparseArray(b *testing.B) {
arr := []int{0, 0, 0, 0, 9, 8, 7, 6, 0, 0}
sa := NewSparseArray(arr)
for i := 0; i < b.N; i++ {
sa.Set(0, 10)
sa.Get(0)
sa.Set(0, 0)

}
}

0 comments on commit 41cc56e

Please sign in to comment.