diff --git a/recursion/README.md b/recursion/README.md index 66da4dc..8241926 100644 --- a/recursion/README.md +++ b/recursion/README.md @@ -3,11 +3,11 @@ Recursion is a computational technique that implements a [divide-and-conquer](../dnc) approach to problem-solving by breaking down a complex problem into smaller sub-problems. It consists of two components: * One or more base cases that provide output for simple inputs and terminate recursion -* A recursive case that combines the outputs obtained from recursive function calls to generate a solution for the original problem. +* A recursive case that combines the outputs obtained from recursive function calls to generate a solution for the original problem Although recursions enhance code readability, they are usually inefficient and challenging to debug. Consequently, unless they provide a more efficient solution to a problem, such as in the case of [quicksort](../dnc/quick_sort_test.go), they are generally not preferred. -During execution, a program typically stores function variables in a memory area known as the stack before executing recursion. The recursive function may assign different values to the same variables during each recursion. When the recursion ends, the stack pops and remembers the values. However, the stack will grow with each call if recursion continues indefinitely, causing the familiar stack overflow error. Since recursion employs the stack to execute, every recursive problem can be converted into an iterative one. This transformation, however, typically leads to more complex code and may require a [stack](../stack). +During execution, a program typically stores function variables in a memory area known as the stack before executing recursion. The recursive function may assign different values to the same variables that are stored separately for each call during each recursion. When the recursion ends, the stack pops and remembers the values. However, the stack will grow with each call if recursion continues indefinitely, causing the familiar stack overflow error. Since recursion employs the stack to execute, every recursive problem can be converted into an iterative one. This transformation, however, typically leads to more complex code and may require a [stack](../stack). ## Implementation @@ -16,9 +16,7 @@ The computation of the nth Fibonacci number can be achieved with recursion. For ```Go package main -import ( - "fmt" -) +import "fmt" func main() { for i := 1; i <= 10; i++ { @@ -37,8 +35,8 @@ func fibonacci(n int) int { When formulating recursive algorithms, it is essential to consider the following four rules of recursion: 1. It is imperative to establish a base case, or else the program will terminate abruptly -2. The algorithm should progress toward the base case at each recursive call. -3. Recursive calls are presumed effective; thus, traversing every recursive call and performing bookkeeping is unnecessary. +2. The algorithm should progress toward the base case at each recursive call +3. Recursive calls are presumed effective; thus, traversing every recursive call and performing bookkeeping is unnecessary 4. Use memoization, a technique that prevents redundant computation by caching previously computed results, can enhance the algorithm's efficiency. ## Complexity diff --git a/recursion/climbing_stairs_test.go b/recursion/climbing_stairs_test.go index b69ff40..a7f5048 100644 --- a/recursion/climbing_stairs_test.go +++ b/recursion/climbing_stairs_test.go @@ -9,6 +9,19 @@ TestClimbingStairs tests solution(s) with the following signature and problem de Given n the number of steps, return in how many ways you can climb these stairs if you are only able to climb 1 or 2 steps at a time. + +For example given 5 we can climb the stairs in the following ways: + + 1, 1, 1, 1, 1 + 1, 1, 1, 2 + 1, 1, 2, 1 + 1, 2, 1, 1 + 2, 1, 1, 1 + 2, 2, 1, + 1, 2, 2, + 2, 1, 2, + +So the algorithm should return 8. */ func TestClimbingStairs(t *testing.T) { tests := []struct { diff --git a/recursion/exponentiation_test.go b/recursion/exponentiation_test.go index 0d55a53..beee527 100644 --- a/recursion/exponentiation_test.go +++ b/recursion/exponentiation_test.go @@ -8,6 +8,8 @@ TestPowerOf tests solution(s) with the following signature and problem descripti func PowerOf(x, n int) int Given x and n, return x raised to the power of n in an efficient manner. + +For example given x=2 and n=3 the algorithm should return 8. */ func TestPowerOf(t *testing.T) { tests := []struct { diff --git a/recursion/expression_operators_test.go b/recursion/expression_operators_test.go index e76fbb7..4771cc4 100644 --- a/recursion/expression_operators_test.go +++ b/recursion/expression_operators_test.go @@ -7,12 +7,12 @@ TestExpressionOperators tests solution(s) with the following signature and probl func ExpressionOperators(list []int, target int) string -Given a list of numbers representing operands in an equation, and a target integer representing +Given a slice of numbers representing operands in an equation, and a target integer representing the result of the equation, return a string representing operators that can be inserted between the operands to form the equation and yield the target result. Only + and - operators are allowed and the are assumed to have the same priority -For example given {1,5,3} and 3, return +- because 1+5-3 = 3. +For example given {1,5,3} and 3 return {+,-} because 1+5-3 = 3. */ func TestExpressionOperators(t *testing.T) { tests := []struct { diff --git a/recursion/is_palindrome_test.go b/recursion/is_palindrome_test.go index 6704b2b..9d38a93 100644 --- a/recursion/is_palindrome_test.go +++ b/recursion/is_palindrome_test.go @@ -7,7 +7,9 @@ TestIsPalindrome tests solution(s) with the following signature and problem desc func IsPalindrome(s string) bool -Given a string like `abba` return true if it's a palindrome and false otherwise. +Given a string return true if it's a palindrome and false otherwise. + +For example given `abba` return true. Given `abca` return false. */ func TestIsPalindrome(t *testing.T) { tests := []struct { diff --git a/recursion/multiplication_test.go b/recursion/multiplication_test.go index c7b582c..1019974 100644 --- a/recursion/multiplication_test.go +++ b/recursion/multiplication_test.go @@ -9,6 +9,8 @@ TestMultiplication tests solution(s) with the following signature and problem de Given two integers, return their product using recursion and without using the multiplication operator. + +For example given 2 and 3 return 6. */ func TestMultiplication(t *testing.T) { tests := []struct { diff --git a/recursion/regular_expression_test.go b/recursion/regular_expression_test.go index 1f9f849..6abc087 100644 --- a/recursion/regular_expression_test.go +++ b/recursion/regular_expression_test.go @@ -13,6 +13,9 @@ Given an input and a regular expression pattern where `*` denotes to zero or more of the proceeding characters Write a recursive function to return true if the input matches the pattern and false otherwise. + +For example given input `aa` and pattern `a*` the algorithm should return true, but given the same +pattern and "ba" it should return false. */ func TestRegularExpressions(t *testing.T) { tests := []struct { @@ -27,6 +30,7 @@ func TestRegularExpressions(t *testing.T) { {"aa", "*", false}, {"aa", "*a", false}, {"aa", "a*", true}, + {"ba", "a*", false}, {"aa", ".", false}, {"ab", ".", false}, {"ad", "d", false}, diff --git a/recursion/reverse_number_test.go b/recursion/reverse_number_test.go index da092d3..1e0e503 100644 --- a/recursion/reverse_number_test.go +++ b/recursion/reverse_number_test.go @@ -7,8 +7,9 @@ TestReverseDigits tests solution(s) with the following signature and problem des func ReverseDigits(n int) int -Given an integer like 321 return a reversed number using recursion where the same digits -are repeated in the reverse order like 321. +Given an integer reverse the order of the digits. + +For example given 123 return 321. */ func TestReverseDigits(t *testing.T) { tests := []struct { @@ -19,6 +20,7 @@ func TestReverseDigits(t *testing.T) { {12, 21}, {112, 211}, {110, 11}, + {123, 321}, } for i, test := range tests {