diff --git a/algs4/src/go/Makefile b/algs4/src/go/Makefile index 1ba1a92..21e6d38 100644 --- a/algs4/src/go/Makefile +++ b/algs4/src/go/Makefile @@ -9,7 +9,8 @@ TARGETS := \ $(REPO_BASE)/algs4-average \ $(REPO_BASE)/algs4-interval2d \ $(REPO_BASE)/algs4-date \ - $(REPO_BASE)/algs4-test-accumulator + $(REPO_BASE)/algs4-test-accumulator \ + $(REPO_BASE)/algs4-stats test: build diff --git a/algs4/src/go/algs4-stats/main.go b/algs4/src/go/algs4-stats/main.go new file mode 100644 index 0000000..7be5878 --- /dev/null +++ b/algs4/src/go/algs4-stats/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + "math" + "os" + + "github.com/meatballhat/box-o-sand/algs4/src/go/algs4" +) + +func die(err error) { + fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) + os.Exit(1) +} + +func main() { + numbers := algs4.NewBag() + + for !algs4.Stdin.IsEmpty() { + d, err := algs4.Stdin.ReadDouble() + if err != nil { + break + } + numbers.Add(d) + } + + n := numbers.Size() + sum := float64(0.0) + + for x := range numbers.Each() { + if val, ok := x.(float64); ok { + sum += val + } else { + fmt.Fprintf(os.Stderr, "%v is not a float64!", x) + } + } + + mean := sum / float64(n) + + sum = float64(0.0) + for x := range numbers.Each() { + if val, ok := x.(float64); ok { + sum += (val - mean) * (val - mean) + } else { + fmt.Fprintf(os.Stderr, "%v is not a float64!", x) + } + } + + std := math.Sqrt(sum / (float64(n) - float64(1))) + + fmt.Printf("Mean: %.2f\n", mean) + fmt.Printf("Std dev: %.2f\n", std) +} diff --git a/algs4/src/go/algs4/bag.go b/algs4/src/go/algs4/bag.go new file mode 100644 index 0000000..53833a0 --- /dev/null +++ b/algs4/src/go/algs4/bag.go @@ -0,0 +1,50 @@ +package algs4 + +import ( + "fmt" + "reflect" +) + +type Bag struct { + items map[string]interface{} +} + +type Item struct { + Name string +} + +func NewBag() *Bag { + return &Bag{ + items: map[string]interface{}{}, + } +} + +func (me *Bag) Add(item interface{}) { + me.items[me.hashItem(item)] = item +} + +func (me *Bag) IsEmpty() bool { + return len(me.items) == 0 +} + +func (me *Bag) Size() int { + return len(me.items) +} + +func (me *Bag) Each() <-chan interface{} { + out := make(chan interface{}) + + go func() { + defer close(out) + for _, item := range me.items { + out <- item + } + }() + + return (<-chan interface{})(out) +} + +func (me *Bag) hashItem(item interface{}) string { + t := reflect.TypeOf(item) + return fmt.Sprintf("%s%s%v", t.Name(), t.String(), &t) +} diff --git a/algs4/src/go/algs4/io.go b/algs4/src/go/algs4/io.go index b04e30c..fe859bb 100644 --- a/algs4/src/go/algs4/io.go +++ b/algs4/src/go/algs4/io.go @@ -35,6 +35,15 @@ func (in *inputWrapper) ReadDouble() (float64, error) { return dbl, nil } +func (in *inputWrapper) IsEmpty() bool { + _, err := in.Inbuf.Peek(1) + if err != nil { + return true + } + + return false +} + func ReadInts(inbuf io.Reader) ([]int, error) { ints := make([]int, 0) diff --git a/algs4/src/go/algs4/queue.go b/algs4/src/go/algs4/queue.go new file mode 100644 index 0000000..9f34dfa --- /dev/null +++ b/algs4/src/go/algs4/queue.go @@ -0,0 +1,34 @@ +package algs4 + +type Queue struct { + items []interface{} +} + +func NewQueue() *Queue { + return &Queue{ + items: []interface{}{}, + } +} + +func (me *Queue) Enqueue(item interface{}) { + me.items = append(me.items, item) +} + +func (me *Queue) Dequeue() interface{} { + if me.IsEmpty() { + return nil + } + + ret := me.items[0] + me.items = me.items[1:] + + return ret +} + +func (me *Queue) Size() int { + return len(me.items) +} + +func (me *Queue) IsEmpty() bool { + return len(me.items) == 0 +} diff --git a/algs4/src/go/algs4/stack.go b/algs4/src/go/algs4/stack.go new file mode 100644 index 0000000..e1d022a --- /dev/null +++ b/algs4/src/go/algs4/stack.go @@ -0,0 +1,35 @@ +package algs4 + +type Stack struct { + items []interface{} +} + +func NewStack() *Stack { + return &Stack{ + items: []interface{}{}, + } +} + +func (me *Stack) Push(item interface{}) { + me.items = append(me.items, item) +} + +func (me *Stack) Pop() interface{} { + if me.IsEmpty() { + return nil + } + + lastIdx := me.Size() - 1 + lastItem := me.items[lastIdx] + me.items = me.items[:lastIdx] + + return lastItem +} + +func (me *Stack) IsEmpty() bool { + return len(me.items) == 0 +} + +func (me *Stack) Size() int { + return len(me.items) +}