bitbucket.org/number571/tendermint@v0.8.14/test/e2e/generator/random.go (about) 1 package main 2 3 import ( 4 "math/rand" 5 "sort" 6 ) 7 8 // combinations takes input in the form of a map of item lists, and returns a 9 // list of all combinations of each item for each key. E.g.: 10 // 11 // {"foo": [1, 2, 3], "bar": [4, 5, 6]} 12 // 13 // Will return the following maps: 14 // 15 // {"foo": 1, "bar": 4} 16 // {"foo": 1, "bar": 5} 17 // {"foo": 1, "bar": 6} 18 // {"foo": 2, "bar": 4} 19 // {"foo": 2, "bar": 5} 20 // {"foo": 2, "bar": 6} 21 // {"foo": 3, "bar": 4} 22 // {"foo": 3, "bar": 5} 23 // {"foo": 3, "bar": 6} 24 func combinations(items map[string][]interface{}) []map[string]interface{} { 25 keys := []string{} 26 for key := range items { 27 keys = append(keys, key) 28 } 29 sort.Strings(keys) 30 return combiner(map[string]interface{}{}, keys, items) 31 } 32 33 // combiner is a utility function for combinations. 34 func combiner(head map[string]interface{}, pending []string, items map[string][]interface{}) []map[string]interface{} { 35 if len(pending) == 0 { 36 return []map[string]interface{}{head} 37 } 38 key, pending := pending[0], pending[1:] 39 40 result := []map[string]interface{}{} 41 for _, value := range items[key] { 42 path := map[string]interface{}{} 43 for k, v := range head { 44 path[k] = v 45 } 46 path[key] = value 47 result = append(result, combiner(path, pending, items)...) 48 } 49 return result 50 } 51 52 // uniformChoice chooses a single random item from the argument list, uniformly weighted. 53 type uniformChoice []interface{} 54 55 func (uc uniformChoice) Choose(r *rand.Rand) interface{} { 56 return uc[r.Intn(len(uc))] 57 } 58 59 // probSetChoice picks a set of strings based on each string's probability (0-1). 60 type probSetChoice map[string]float64 61 62 func (pc probSetChoice) Choose(r *rand.Rand) []string { 63 choices := []string{} 64 for item, prob := range pc { 65 if r.Float64() <= prob { 66 choices = append(choices, item) 67 } 68 } 69 return choices 70 } 71 72 // uniformSetChoice picks a set of strings with uniform probability, picking at least one. 73 type uniformSetChoice []string 74 75 func (usc uniformSetChoice) Choose(r *rand.Rand) []string { 76 choices := []string{} 77 indexes := r.Perm(len(usc)) 78 if len(indexes) > 1 { 79 indexes = indexes[:1+r.Intn(len(indexes)-1)] 80 } 81 for _, i := range indexes { 82 choices = append(choices, usc[i]) 83 } 84 return choices 85 }