Created
April 2, 2016 05:03
-
-
Save caelifer/05c5bad2aa37359f64aa38e091ec4fa0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"regexp" | |
"sort" | |
) | |
func main() { | |
cm := NewCMR(4) | |
for _, s := range []string{"A", "BB", "Z", "XXX", "CCC", "SSS", "AAA", "AA"} { | |
if cm.HasCapacity(s) { | |
fmt.Println("Accepted:", s) | |
} else { | |
fmt.Println("Rejected:", s) | |
} | |
} | |
fmt.Println(cm) | |
fmt.Println("---") | |
cm = NewCMbyM(2) | |
for _, s := range []string{"A", "BB", "Z", "XXX", "CCC", "SSS", "AAA", "AA"} { | |
if cm.HasCapacity(s) { | |
fmt.Println("Accepted:", s) | |
} else { | |
fmt.Println("Rejected:", s) | |
} | |
} | |
fmt.Println(cm) | |
} | |
type CapManager struct { | |
maxCap int | |
capmap map[*regexp.Regexp]int | |
} | |
func (cm *CapManager) HasCapacity(s string) bool { | |
for rx, cap := range cm.capmap { | |
if rx.Match([]byte(s)) && cap > 0 { | |
cap-- | |
cm.capmap[rx] = cap | |
return true | |
} | |
} | |
return false | |
} | |
func (cm CapManager) String() string { | |
r := "CapMap:" | |
keys := RXSlice(make([]*regexp.Regexp, 0, len(cm.capmap))) | |
for k := range cm.capmap { | |
keys = append(keys, k) | |
} | |
sort.Sort(keys) | |
for _, rx := range keys { | |
cap := cm.capmap[rx] | |
r += fmt.Sprintf("\n\t%v: %d filled (%d left)", rx, cm.maxCap-cap, cap) | |
} | |
return r | |
} | |
func NewCMR(slots int) *CapManager { | |
cap := slots / 2 | |
return &CapManager{ | |
maxCap: cap, | |
capmap: map[*regexp.Regexp]int{ | |
regexp.MustCompile("^[A-M]"): cap, | |
regexp.MustCompile("^[N-Z]"): cap, | |
}, | |
} | |
} | |
func NewCMbyM(slots int) *CapManager { | |
return &CapManager{ | |
maxCap: slots, | |
capmap: map[*regexp.Regexp]int{ | |
regexp.MustCompile("^A"): slots, | |
regexp.MustCompile("^B"): slots, | |
regexp.MustCompile("^C"): slots, | |
regexp.MustCompile("^D"): slots, | |
regexp.MustCompile("^E"): slots, | |
regexp.MustCompile("^F"): slots, | |
regexp.MustCompile("^G"): slots, | |
regexp.MustCompile("^H"): slots, | |
regexp.MustCompile("^I"): slots, | |
regexp.MustCompile("^J"): slots, | |
regexp.MustCompile("^K"): slots, | |
regexp.MustCompile("^L"): slots, | |
regexp.MustCompile("^M"): slots, | |
regexp.MustCompile("^N"): slots, | |
regexp.MustCompile("^O"): slots, | |
regexp.MustCompile("^P"): slots, | |
regexp.MustCompile("^Q"): slots, | |
regexp.MustCompile("^R"): slots, | |
regexp.MustCompile("^S"): slots, | |
regexp.MustCompile("^T"): slots, | |
regexp.MustCompile("^U"): slots, | |
regexp.MustCompile("^V"): slots, | |
regexp.MustCompile("^W"): slots, | |
regexp.MustCompile("^X"): slots, | |
regexp.MustCompile("^Y"): slots, | |
regexp.MustCompile("^Z"): slots, | |
}, | |
} | |
} | |
type RXSlice []*regexp.Regexp | |
func (rxs RXSlice) Len() int { | |
return len(rxs) | |
} | |
func (rxs RXSlice) Less(i, j int) bool { | |
if rxs[i] == nil || rxs[j] == nil { | |
return false | |
} | |
return rxs[i].String() < rxs[j].String() | |
} | |
func (rxs RXSlice) Swap(i, j int) { | |
rxs[i], rxs[j] = rxs[j], rxs[i] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Live code - http://play.golang.org/p/1R_CN3y_Pe
Output: