Skip to content

Commit

Permalink
day 358: refactor due to new common package
Browse files Browse the repository at this point in the history
  • Loading branch information
vaskoz committed Oct 28, 2020
1 parent ee886e5 commit c7aae1c
Showing 1 changed file with 17 additions and 135 deletions.
152 changes: 17 additions & 135 deletions day358/problem.go
Original file line number Diff line number Diff line change
@@ -1,152 +1,34 @@
package day358

import "container/list"
import "github.com/algds/minmaxcnt"

// BigOhOne is a data structure that performs all operations
// in O(1) time: constant time operations.
type BigOhOne interface {

// Plus adds a key with value 1.
// If the key already exists, increment its value by one.
Plus(key interface{})

// Minus decrements the value of a key.
// If the key's value is currently 1, remove it.
Minus(key interface{})

// Max returns the key with the highest value.
Max() (interface{}, int)

// Min returns the key with the lowest value.
Min() (interface{}, int)
type Wrapper struct {
delegate minmaxcnt.Interface
}

type bigOhOne struct {
entryList *list.List
lookupEntryByKey map[interface{}]*list.Element
lookupListByCount map[int]*list.Element
func (w Wrapper) Plus(key interface{}) {
w.delegate.Increment(key)
}

type entry struct {
count int
values *list.List
lookupByKey map[interface{}]*list.Element
func (w Wrapper) Minus(key interface{}) {
w.delegate.Decrement(key)
}

func (bo *bigOhOne) Plus(key interface{}) {
eSource := bo.lookupEntryByKey[key]

if eSource == nil {
vals := list.New()
lookup := make(map[interface{}]*list.Element)
lookup[key] = vals.PushFront(key)
func (w Wrapper) Max() (interface{}, int) {
val, count := w.delegate.Max()

newEntry := &entry{
count: 0,
values: vals,
lookupByKey: lookup,
}
eSource = bo.entryList.PushFront(newEntry)
}

sourceEntry := eSource.Value.(*entry)

eTarget := bo.lookupListByCount[sourceEntry.count+1]

if eTarget == nil {
newEntry := &entry{
count: sourceEntry.count + 1,
values: list.New(),
lookupByKey: make(map[interface{}]*list.Element),
}
eTarget = bo.entryList.InsertAfter(newEntry, eSource)
}

targetEntry := eTarget.Value.(*entry)

bo.lookupEntryByKey[key] = eTarget
bo.lookupListByCount[targetEntry.count] = eTarget
targetEntry.lookupByKey[key] = targetEntry.values.PushFront(key)

sourceEntryKey := sourceEntry.lookupByKey[key]
sourceEntry.values.Remove(sourceEntryKey)
delete(sourceEntry.lookupByKey, key)

if len(sourceEntry.lookupByKey) == 0 {
delete(bo.lookupListByCount, sourceEntry.count)
bo.entryList.Remove(eSource)
}
return val, int(count)
}

func (bo *bigOhOne) Minus(key interface{}) {
eSource := bo.lookupEntryByKey[key]

if eSource == nil {
return
}

sourceEntry := eSource.Value.(*entry)

eTarget := bo.lookupListByCount[sourceEntry.count-1]

if eTarget == nil {
newEntry := &entry{
count: sourceEntry.count - 1,
values: list.New(),
lookupByKey: make(map[interface{}]*list.Element),
}
eTarget = bo.entryList.InsertBefore(newEntry, eSource)
}

targetEntry := eTarget.Value.(*entry)

bo.lookupEntryByKey[key] = eTarget
bo.lookupListByCount[targetEntry.count] = eTarget
targetEntry.lookupByKey[key] = targetEntry.values.PushFront(key)

sourceEntryKey := sourceEntry.lookupByKey[key]
sourceEntry.values.Remove(sourceEntryKey)
delete(sourceEntry.lookupByKey, key)

if len(sourceEntry.lookupByKey) == 0 {
delete(bo.lookupListByCount, sourceEntry.count)
bo.entryList.Remove(eSource)
}

if targetEntry.count == 0 {
delete(bo.lookupEntryByKey, key)
delete(bo.lookupListByCount, targetEntry.count)
bo.entryList.Remove(eTarget)
}
}

func (bo *bigOhOne) Max() (interface{}, int) {
if bo.entryList.Len() == 0 {
return nil, 0
}

back := bo.entryList.Back().Value.(*entry)
val := back.values.Back().Value

return val, back.count
}

func (bo *bigOhOne) Min() (interface{}, int) {
if bo.entryList.Len() == 0 {
return nil, 0
}

front := bo.entryList.Front().Value.(*entry)
val := front.values.Front().Value
func (w Wrapper) Min() (interface{}, int) {
val, count := w.delegate.Min()

return val, front.count
return val, int(count)
}

// New returns a new instance of a BigOhOne data structure.
func New() BigOhOne {
return &bigOhOne{
entryList: list.New(),
lookupEntryByKey: make(map[interface{}]*list.Element),
lookupListByCount: make(map[int]*list.Element),
// New returns a new instance of a Wrapper data structure.
func New() Wrapper {
return Wrapper{
minmaxcnt.New(),
}
}

0 comments on commit c7aae1c

Please sign in to comment.