func main() {
go spinner(100 * time.Millisecond)
const n = 45
fibN := fib(n) // slow
fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}
func spinner(delay time.Duration) {
for {
for _, r := range `-\|/` {
fmt.Printf("\r%c", r)
time.Sleep(delay)
}
}
}
func fib(x int) int {
if x < 2 {
return x
}
return fib(x-1) + fib(x-2)
}
can you explain above fib function ,how the results are obtained.
fib function return a fib calls ,how does the end results come?
The key is in this function:
func fib(x int) int {
if x < 2 {
return x
}
return fib(x-1) + fib(x-2)
}
If x<2 the function returns immediately, if not it retrieves the result from a call to fib with a smaller value of x
For recursive calls there are the 3 Laws of Recursion:
A recursive algorithm must have a base case.
A recursive algorithm
must change its state and move toward the base case.
A recursive
algorithm must call itself, recursively.
http://interactivepython.org/courselib/static/pythonds/Recursion/TheThreeLawsofRecursion.html
In your example, the base case is when x < 2. The state change is the reduction by 1 or 2 and your function calls itself recursively so the three laws are met.
Related
I want results of every fib execution to be stored in cache variable, but make cached decorator and fib function independent.
The thing is, decorated fib is executing not decorated fib inside itself.
I understand that decorated fib inside main is a local variable, but I can't redefine fib in global scope(or I don't know how)
Is this even possible?
package main
import (
"fmt"
)
func cached(f func(int) int) func(int) int {
cache := make(map[int]int)
return func(x int) int {
if _, ok := cache[x]; !ok {
cache[x] = f(x)
fmt.Println(len(cache))
}
value, _ := cache[x]
return value
}
}
func fib(x int) int {
if x < 0 {
return -1
}
if x == 0 || x == 1 {
return 1
}
return fib(x-1) + fib(x-2)
}
func main() {
fib := cached(fib)
fmt.Println(fib(40))
fmt.Println(fib(41))
fmt.Println(fib(42))
fmt.Println(fib(43))
}
This code output:
1
165580141
2
267914296
3
433494437
4
701408733
But 1, 2, 3 and 4 here should be 38, 39, 40, 41
I keep getting the error "cannot use a (type int) as type float64 in argument to math.Pow, cannot use x (type int) as type float64 in argument to math.Pow,
invalid operation: math.Pow(a, x) % n (mismatched types float64 and int)"
func pPrime(n int) bool {
var nm1 int = n - 1
var x int = nm1/2
a := 1;
for a < n {
if (math.Pow(a, x)) % n == nm1 {
return true
}
}
return false
}
func powInt(x, y int) int {
return int(math.Pow(float64(x), float64(y)))
}
In case you have to reuse it and keep it a little more clean.
If your inputs are int and the output is always expected to be int, then you're dealing with 32-bit numbers. It's more efficient to write your own function to handle this multiplication rather than using math.Pow. math.Pow, as mentioned in the other answers, expects 64-bit values.
Here's a Benchmark comparison for 15^15 (which approaches the upper limits for 32-bit representation):
// IntPow calculates n to the mth power. Since the result is an int, it is assumed that m is a positive power
func IntPow(n, m int) int {
if m == 0 {
return 1
}
result := n
for i := 2; i <= m; i++ {
result *= n
}
return result
}
// MathPow calculates n to the mth power with the math.Pow() function
func MathPow(n, m int) int {
return int(math.Pow(float64(n), float64(m)))
}
The result:
go test -cpu=1 -bench=.
goos: darwin
goarch: amd64
pkg: pow
BenchmarkIntPow15 195415786 6.06 ns/op
BenchmarkMathPow15 40776524 27.8 ns/op
I believe the best solution is that you should write your own function similar to IntPow(m, n int) shown above. My benchmarks show that it runs more than 4x faster on a single CPU core compared to using math.Pow.
Since nobody mentioned an efficient way (logarithmic) to do Pow(x, n) for integers x and n is as follows if you want to implement it yourself:
// Assumption: n >= 0
func PowInts(x, n int) int {
if n == 0 { return 1 }
if n == 1 { return x }
y := PowInts(x, n/2)
if n % 2 == 0 { return y*y }
return x*y*y
}
If you want the exact exponentiation of integers, use (*big.Int).Exp. You're likely to overflow int64 pretty quickly with powers larger than two.
I am so confused by goroutines.
Here is the code
func main() {
// runtime.GOMAXPROCS(1)
go spinner(100 * time.Millisecond)
const n = 45
fibN := fib(n) // slow
fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}
func spinner(delay time.Duration) {
for {
for _, r := range `-\|/` {
fmt.Printf("\r%c", r)
time.Sleep(delay)
}
}
}
func fib(x int) int {
if x < 2 {
return x
}
return fib(x-1) + fib(x-2)
}
That is a simple goroutine tutorial code which using goroutine to show an ASCII animation when calculating Fibonacci.
When I set GOMAXPROCS to 1, I think that there will be only one thread to execute goroutine and the Fibonacci function doesn't have any point to yield to animation goroutine. But this demo still works. It shows animation while doing calculating.
How does Go do this without goroutine switching?
Among others : the compiler inserts potential switch points at each function call, so each recursive call to fib(...) can yield to the "spinner" goroutine.
If you try to implement fib without any function call for example :
// note : this is a truly horrific way to compute the Fibonacci sequence,
// don't do this at home
// simulate the "compute Fibonacci recursively" algorithm,
// but without any function call
func fib(n int) int {
var res = 0
var stack []int
stack = append(stack, n)
for len(stack) > 0 {
// pop :
n = stack[len(stack)-1]
stack = stack[0 : len(stack)-1]
if n < 2 {
res += n
continue
}
// else : push 'n-1' and 'n-2' on the stack
stack = append(stack, n-1, n-2)
}
return res
}
https://play.golang.org/p/pdoAaBwyscr
you should see your spinner 'stuck'
Trying a simple recursive function that takes a number, splits it in a certain way, and is only supposed to return it if the split numbers are equal to each other.
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
if y == x || sum > 200 {
return
} else {
split(sum+1)
return
}
}
func main() {
fmt.Println(split(10))
}
The output for fmt.Println(split(10)) is 4 and 6, which is incorrect since they're not equal to each other. Is this due to the return statement t the end of my ELSE statement? I have a JAVA background so I figured that line would never get hit.
As you are declaring the variables in the function definition with (x, y int) performing a return will return the values of x and y at that point. When you call the split function recursively it will assign a new x and y for that function call, so changing the values there will not effect the outer scope.
You can fix this by returning the return value of the recursive split call, as currently you are ignoring the results by calling it on the line before the return.
However I would note that any input value > 0 will never be equal in this implementation and will return the same value for any input as the sum > 200 clause triggers.
https://play.golang.org/p/fzuPtqPCxpE
package main
import "fmt"
func split(sum int) (int, int) {
x := sum * 4 / 9
y := sum - x
if y == x || sum > 200 {
return
} else {
return split(sum + 1)
}
}
func main() {
fmt.Println(split(10))
}
I have a recursive function and I want one execute some statement only for the outermost call to the function. How do I achieve this functionality?
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most{
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
This should print only 4
To answer the question itself: if for some reason you really want to run something that is only for outermost func call and don't want to change api, Golang has a runtime lib for that.
You may do it as:
package main
import (
"fmt"
"runtime"
"strconv"
)
func outer_most() bool {
pc:=make([]uintptr,2)
runtime.Callers(2,pc) //skip: 1 - runtime.Caller, 2 - outer_most itself
return runtime.FuncForPC(pc[0])!=runtime.FuncForPC(pc[1]) // test if the caller of the caller is the same func, otherwise it is the outermost
}
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most() {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
playground: https://play.golang.org/p/ro1ZOn6yIR7
It is no good practice, but solve the question most straightfowardly.
Note:
Use a global variable is very likely to cause glitches. You need to set it every time you call the func, and if there is concurency, data race would be involved.
And if you are unconfortable with the fact that the extra bool argument get allocated every recursive call (which could be countless time), you may look at #Adrian 's answer or wrap it as a method of a bool.
You could pass something like a depth that gets incremented at each call. Eg:
func fact(depth int, n int) int {
if n == 0 {
return 1
}
fact := n * fact(depth + 1, n-1)
if depth == 0 {
fmt.Println(fact) // I assume you meant to print fact here.
}
return fact
}
func main() {
fact(0, 4)
}
If this is really your use case, you're much better off doing:
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(4))
}
Answer to edited question:
You can use he second pattern below again:
func fact(n int, outerMost bool) int {
if n == 0 {
return 1
}
fact := n * fact(n-1, false)
if outerMost {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4, true)
}
Again, you can use closures or helper functions to clean this up.
Original answer:
Try using a global variable:
var outerMost bool = true
func fact(n int) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fact(4)
}
There are other ways to achieve this. For example, you can use similar technique with closures as well. Or add another parameter to fact:
func fact(n int, outerMost bool) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1, outerMost)
}
func main() {
fact(4, true)
}
A simple anonymous function is probably the cleanest, as it does not add a parameter, complicating the API for external callers just to implement internal logic.
func fact(n int) int {
var facto func(n int) int
facto = func(n int) int {
if n == 0 {
return 1
}
fact := n * facto(n-1)
return fact
}
n = facto(n)
fmt.Printf("%d", n)
return n
}
This achieves the same functionality, but the caller doesn't have to know to pass an additional bool or int value that's irrelevant to it. Full example here: https://play.golang.org/p/7vHwPDN2_FL