The challenge
The purpose of this challenge is to write a higher-order function returning a new function that iterates on a specified function a given number of times. This new function takes in an argument as a seed to start the computation.
For instance, consider the function getDouble
. When run twice on value 3
, yields 12
as shown below.
getDouble(3) => 6
getDouble(6) => 12
Let us name the new function createIterator
and we should be able to obtain the same result using createIterator
as shown below:
var doubleIterator = createIterator(getDouble, 2); // Runs *getDouble* twice
doubleIterator(3) => 12
For the sake of simplicity, all function inputs to createIterator
would function returning a small number and the number of iterations would always be integers.
The solution in Golang
Option 1:
package solution
func CreateIterator(fn func(int) int,n int) func(int) int {
return func (i int) int {
for j := 0; j < n; j++ { i = fn(i) }
return i
}
}
Option 2:
package solution
func CreateIterator(fn func(int) int,n int) func(int) int {
if n == 0 {
return func(x int) int { return x } // id
} else {
return func(x int) int { return CreateIterator(fn, n-1)(fn(x)) }
}
}
Option 3:
package solution
func CreateIterator(fn func(int) int,n int) func(int) int {
if n < 1 {
return nil
}
var retFunc = func(r int) int {
for i := n ; i>0 ; i-- {
r = fn(r)
}
return r
}
return retFunc
}
Test cases to validate our solution
package solution_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Iterator for 'getDouble' function",func() {
var getDouble = func(n int) int {return 2*n}
It("Running the iterator once",func() {
doubleIterator := CreateIterator(getDouble,1)
Expect(doubleIterator(3)).To(Equal(6))
Expect(doubleIterator(5)).To(Equal(10))
})
It("Running the iterator twice",func() {
getQuadruple := CreateIterator(getDouble,2)
Expect(getQuadruple(2)).To(Equal(8))
Expect(getQuadruple(5)).To(Equal(20))
})
})