Skip to content

Instantly share code, notes, and snippets.

@caelifer
Created April 2, 2016 05:03
Show Gist options
  • Save caelifer/05c5bad2aa37359f64aa38e091ec4fa0 to your computer and use it in GitHub Desktop.
Save caelifer/05c5bad2aa37359f64aa38e091ec4fa0 to your computer and use it in GitHub Desktop.
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]
}
@caelifer
Copy link
Author

caelifer commented Apr 2, 2016

Live code - http://play.golang.org/p/1R_CN3y_Pe

Output:

Accepted: A
Accepted: BB
Accepted: Z
Accepted: XXX
Rejected: CCC
Rejected: SSS
Rejected: AAA
Rejected: AA
CapMap:
    ^[A-M]: 2 filled (0 left)
    ^[N-Z]: 2 filled (0 left)

---
Accepted: A
Accepted: BB
Accepted: Z
Accepted: XXX
Accepted: CCC
Accepted: SSS
Accepted: AAA
Rejected: AA
CapMap:
    ^A: 2 filled (0 left)
    ^B: 1 filled (1 left)
    ^C: 1 filled (1 left)
    ^D: 0 filled (2 left)
    ^E: 0 filled (2 left)
    ^F: 0 filled (2 left)
    ^G: 0 filled (2 left)
    ^H: 0 filled (2 left)
    ^I: 0 filled (2 left)
    ^J: 0 filled (2 left)
    ^K: 0 filled (2 left)
    ^L: 0 filled (2 left)
    ^M: 0 filled (2 left)
    ^N: 0 filled (2 left)
    ^O: 0 filled (2 left)
    ^P: 0 filled (2 left)
    ^Q: 0 filled (2 left)
    ^R: 0 filled (2 left)
    ^S: 1 filled (1 left)
    ^T: 0 filled (2 left)
    ^U: 0 filled (2 left)
    ^V: 0 filled (2 left)
    ^W: 0 filled (2 left)
    ^X: 1 filled (1 left)
    ^Y: 0 filled (2 left)
    ^Z: 1 filled (1 left)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment