Understanding Factorials in Go

The factorial of a number is the product of all positive integers less than or equal to that number. It is denoted as n! and calculated by multiplying all numbers from 1 to n. For example, 5! = 5 x 4 x 3 x 2 x 1 = 120.

Basic Factorial Calculation

Let's start with writing a basic factorial function in Go. Here we'll use a simple iterative approach.

package main

import "fmt"

func factorial(n int) int {
    result := 1
    for i := 2; i <= n; i++ {
        result *= i
    }
    return result
}

func main() {
    fmt.Println("5! =", factorial(5))
}

Recursive Approach

Factorials can also be calculated using recursion, which is calling the function within itself with a reduced argument until it reaches a base case.

package main

import "fmt"

func factorial(n int) int {
    if n == 0 {
        return 1
    }
    return n * factorial(n-1)
}

func main() {
    fmt.Println("5! =", factorial(5))
}

Fibonacci Sequence in Go

The Fibonacci sequence is a series of numbers where each number is the sum of the two preceding ones, typically starting with 0 and 1.

Basic Fibonacci Sequence Calculation

Let's write a function to calculate the Fibonacci sequence using an iterative approach.

package main

import "fmt"

func fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    prev2, prev1 := 0, 1
    var result int
    for i := 2; i <= n; i++ {
        result = prev1 + prev2
        prev2 = prev1
        prev1 = result
    }
    return result
}

func main() {
    fmt.Println("Fibonacci of 5 =", fibonacci(5))
}

Recursive Fibonacci

Now, let's look into a recursive approach which mimics the mathematical recursive definition of Fibonacci.

package main

import "fmt"

func fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    return fibonacci(n-1) + fibonacci(n-2)
}

func main() {
    fmt.Println("Fibonacci of 5 =", fibonacci(5))
}

Optimizing Fibonacci Calculation with Memoization

Using recursion for Fibonacci has a big drawback: performance issues for larger numbers. We can optimize this with Memoization to store previously calculated results.

package main

import "fmt"

var memo = make(map[int]int)

func fibonacci(n int) int {
    if n <= 1 {
        return n
    }
    if val, found := memo[n]; found {
        return val
    }
    memo[n] = fibonacci(n-1) + fibonacci(n-2)
    return memo[n]
}

func main() {
    fmt.Println("Fibonacci of 5 =", fibonacci(5))
}

By using memoization, each position in the Fibonacci sequence only has to be calculated once, which drastically improves the performance for larger numbers.