Created
September 24, 2015 19:09
-
-
Save sheki/a4a4713204e083cc21c3 to your computer and use it in GitHub Desktop.
try.go
This file contains hidden or 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" | |
| "strconv" | |
| ) | |
| type Tracker struct { | |
| store map[string][]int | |
| } | |
| func (t *Tracker) Alloc(name string) string { | |
| if t.store == nil { | |
| t.store = make(map[string][]int) | |
| } | |
| r, ok := t.store[name] | |
| if !ok { | |
| t.store[name] = make([]int, 0) | |
| r = t.store[name] // avoid double lookup | |
| } | |
| next := nextServerNum(r) | |
| r = append(r, next) | |
| t.store[name] = r | |
| return fmt.Sprintf("%s%d", name, next) | |
| } | |
| var reg = regexp.MustCompile(`([a-z]+)(\d+)`) | |
| func (t *Tracker) Dealloc(name string) { | |
| if t.store == nil { | |
| return | |
| } | |
| arr := reg.FindStringSubmatch(name) | |
| name = arr[1] | |
| num, err := strconv.Atoi(arr[2]) | |
| if err != nil { | |
| // TODO return | |
| panic(err) | |
| } | |
| res, ok := t.store[name] | |
| if !ok { | |
| return | |
| } | |
| res = removeElem(res, num) | |
| t.store[name] = res | |
| } | |
| //TODO do inplace | |
| func removeElem(arr []int, i int) []int { | |
| var res []int | |
| for _, j := range arr { | |
| if j == i { | |
| continue | |
| } | |
| res = append(res, j) | |
| } | |
| return res | |
| } | |
| func nextServerNum(input []int) int { | |
| sort.Ints(input) | |
| if len(input) == 0 { | |
| return 1 | |
| } | |
| if input[0] != 1 { | |
| return 1 | |
| } | |
| for index, val := range input { | |
| next := -1 | |
| if index < len(input)-1 { | |
| next = input[index+1] | |
| } | |
| if next == val+1 { | |
| continue | |
| } | |
| if next != -1 { | |
| return val + 1 | |
| } | |
| } | |
| return input[len(input)-1] + 1 | |
| } | |
| func assert(input []int, output int) { | |
| if nextServerNum(input) != output { | |
| fmt.Println(input) | |
| panic(input) | |
| } | |
| } | |
| func main() { | |
| assert([]int{1, 2, 3}, 4) | |
| assert([]int{1, 3}, 2) | |
| assert([]int{1, 2, 4, 5}, 3) | |
| assert([]int{2, 4, 5}, 1) | |
| assert([]int{1, 4, 5}, 2) | |
| assert([]int{}, 1) | |
| fmt.Println("all is well") | |
| t := &Tracker{} | |
| for i := 0; i < 10; i++ { | |
| fmt.Println(t.Alloc("api")) | |
| } | |
| t.Dealloc("api5") | |
| fmt.Println(t.Alloc("api")) | |
| // for i := 0; i < 10; i++ { | |
| // fmt.Println(t.Alloc("site")) | |
| // } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment