type (
Keyfunc func(...interface{}) string
Memfunc func(...interface{}) interface{}
Algofunc func(int, []int) []int
)
memoize is exactly the same as before:
func memoize(f Memfunc, kf Keyfunc) Memfunc { if kf == nil { kf = func(v ...interface{}) string { // Very naive keygen func, simply use string representation // of every param var buffer bytes.Buffer for i := 0; i < len(v); i++ { buffer.WriteString(fmt.Sprint(v[0])) buffer.WriteString(",") } return buffer.String() } } cache := make(map[string]interface{}) return func(v ...interface{}) interface{} { cachekey := kf(v) if r, ok := cache[cachekey]; ok { // Hit, return previous result return r } // Miss, call calculator r := f(v...) cache[cachekey] = r return r } }
func findshare(mf Memfunc) Algofunc { f := func(target int, treasures []int) []int { if target == 0 { return make([]int, 0) } if target < 0 || len(treasures) == 0 { return nil } first, rest := treasures[0:1], treasures[1:] solution := toIntSlice(mf(target-first[0], rest)) if solution != nil { return append(first, solution...) } return toIntSlice(mf(target, rest)) } if mf == nil { mf = func(v ...interface{}) interface{} { return f(toInt(v[0]), toIntSlice(v[1])) } } return f }
func main() { treasure := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} target := 209 rawfindshare := findshare(nil) duration, res := timeThis(rawfindshare, target, treasure) fmt.Printf("Raw partition %v into %d: %d at %s\n", treasure, target, res, duration)
mfindshare := func() Algofunc { // Forward decleration of calculator var calcshare Algofunc // Memoizer memfindshare := memoize(func(values ...interface{}) interface{} { return calcshare(toInt(values[0]), toIntSlice(values[1])) }, nil) // Construct the calculator, use the memonizer defined above calcshare = findshare(memfindshare) // Return a function that will do the neccessary typecasting return func(target int, treasures []int) []int { return toIntSlice(memfindshare(target, treasures)) } }() duration, res = timeThis(mfindshare, target, treasure) fmt.Printf("Memoized partition %v into %d: %d at %s\n", treasure, target, res, duration) }
Raw partition [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] into 209: [2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] at 558.018056ms
Memoized partition [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] into 209: [2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] at 18.783834ms
Get the source at GitHub.
No comments:
Post a Comment