Skip to content

Commit

Permalink
Merge pull request #321 from vaskoz/day154
Browse files Browse the repository at this point in the history
Day154
  • Loading branch information
vaskoz committed Jan 24, 2019
2 parents 7e0d2fc + 8fef55b commit bd446c1
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,4 @@ problems from
* [Day 150](https://github.com/vaskoz/dailycodingproblem-go/issues/312)
* [Day 151](https://github.com/vaskoz/dailycodingproblem-go/issues/313)
* [Day 153](https://github.com/vaskoz/dailycodingproblem-go/issues/316)
* [Day 154](https://github.com/vaskoz/dailycodingproblem-go/issues/320)
45 changes: 45 additions & 0 deletions day154/problem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package day154

import "container/heap"

// StackHeap is a stack implemented using only a heap.
// Runs in O(N log N) time.
// Also contains a flaw with the counter due to overflow.
type StackHeap struct {
heap maxHeap
counter uint64
}

type item struct {
index uint64
value interface{}
}

type maxHeap []item

func (h maxHeap) Len() int { return len(h) }
func (h maxHeap) Less(i, j int) bool { return h[i].index > h[j].index }
func (h maxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }

func (h *maxHeap) Push(x interface{}) {
*h = append(*h, x.(item))
}

func (h *maxHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1].value
*h = old[:n-1]
return x
}

// Push adds an element to the stack.
func (sh *StackHeap) Push(v interface{}) {
heap.Push(&sh.heap, item{sh.counter, v})
sh.counter++
}

// Pop removes an element from the stack.
func (sh *StackHeap) Pop() interface{} {
return heap.Pop(&sh.heap)
}
39 changes: 39 additions & 0 deletions day154/problem_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package day154

import "testing"

var testcases = []struct {
items []interface{}
}{
{[]interface{}{"foo", "bar", 1, 3, 5}},
{[]interface{}{10, 20, 30, 15, 30, 55}},
}

func TestStackHeap(t *testing.T) {
t.Parallel()
for _, tc := range testcases {
var stack StackHeap
for i := range tc.items {
stack.Push(tc.items[i])
}
for i := range tc.items {
if result := stack.Pop(); result != tc.items[len(tc.items)-1-i] {
t.Errorf("Expected %v got %v", tc.items[len(tc.items)-1-i], result)
}
}
}
}

func BenchmarkStackHeap(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, tc := range testcases {
var stack StackHeap
for i := range tc.items {
stack.Push(tc.items[i])
}
for range tc.items {
stack.Pop()
}
}
}
}

0 comments on commit bd446c1

Please sign in to comment.