package pieceordering
import (
- "github.com/glenn-brown/skiplist"
+ "math/rand"
+
+ "github.com/ryszard/goskiplist/skiplist"
)
type Instance struct {
- sl *skiplist.T
+ sl *skiplist.SkipList
pieceKeys map[int]int
}
func New() *Instance {
return &Instance{
- sl: skiplist.New(),
+ sl: skiplist.NewIntMap(),
}
}
}
me.removeKeyPiece(existingKey, piece)
}
- me.sl.Insert(key, piece)
+ var itemSl []int
+ if exItem, ok := me.sl.Get(key); ok {
+ itemSl = exItem.([]int)
+ }
+ me.sl.Set(key, append(itemSl, piece))
if me.pieceKeys == nil {
me.pieceKeys = make(map[int]int)
}
me.pieceKeys[piece] = key
+ me.shuffleItem(key)
+}
+
+func (me *Instance) shuffleItem(key int) {
+ _item, ok := me.sl.Get(key)
+ if !ok {
+ return
+ }
+ item := _item.([]int)
+ for i := range item {
+ j := i + rand.Intn(len(item)-i)
+ item[i], item[j] = item[j], item[i]
+ }
+ me.sl.Set(key, item)
}
func (me *Instance) removeKeyPiece(key, piece int) {
- if me.sl.Remove(key).Value.(int) != piece {
- panic("piecekeys map lied to us")
+ item, ok := me.sl.Get(key)
+ if !ok {
+ panic("no item for key")
+ }
+ itemSl := item.([]int)
+ for i, piece1 := range itemSl {
+ if piece1 == piece {
+ itemSl[i] = itemSl[len(itemSl)-1]
+ itemSl = itemSl[:len(itemSl)-1]
+ break
+ }
}
- if me.sl.Remove(key) != nil {
- panic("duplicate key")
+ if len(itemSl) == 0 {
+ me.sl.Delete(key)
+ } else {
+ me.sl.Set(key, itemSl)
}
}
}
func (me Instance) First() Element {
- e := me.sl.Front()
- if e == nil {
+ i := me.sl.SeekToFirst()
+ if i == nil {
return nil
}
- return element{e}
+ return &element{i, i.Value().([]int)}
}
type Element interface {
}
type element struct {
- sle *skiplist.Element
+ i skiplist.Iterator
+ sl []int
}
-func (e element) Next() Element {
- sle := e.sle.Next()
- if sle == nil {
+func (e *element) Next() Element {
+ e.sl = e.sl[1:]
+ if len(e.sl) > 0 {
+ return e
+ }
+ ok := e.i.Next()
+ if !ok {
return nil
}
- return element{sle}
+ e.sl = e.i.Value().([]int)
+ return e
}
func (e element) Piece() int {
- return e.sle.Value.(int)
+ return e.sl[0]
}
package pieceordering
import (
+ "sort"
"testing"
)
return
}
-func checkOrder(t *testing.T, i *Instance, pp []int) {
+func sameContents(a, b []int) bool {
+ if len(a) != len(b) {
+ panic("y u pass different length slices")
+ }
+ sort.IntSlice(a).Sort()
+ sort.IntSlice(b).Sort()
+ for i := range a {
+ if a[i] != b[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func checkOrder(t *testing.T, i *Instance, ppp ...[]int) {
fatal := func() {
- t.Fatalf("have %v, expected %v", instanceSlice(i), pp)
+ t.Fatalf("have %v, expected %v", instanceSlice(i), ppp)
}
e := i.First()
- for _, p := range pp {
- if p != e.Piece() {
+ for _, pp := range ppp {
+ var pp_ []int
+ for len(pp_) != len(pp) {
+ pp_ = append(pp_, e.Piece())
+ e = e.Next()
+ }
+ if !sameContents(pp, pp_) {
fatal()
}
- e = e.Next()
}
if e != nil {
fatal()
checkOrder(t, i, []int{3, 1, 2})
// Move a piece that isn't the youngest in a key.
i.SetPiece(1, -1)
- checkOrder(t, i, []int{1, 3, 2})
+ checkOrder(t, i, []int{1}, []int{3, 2})
i.DeletePiece(2)
i.DeletePiece(3)
i.DeletePiece(1)