From 713bd1db0a9bfc5c419022e704a6eabdcda9359f Mon Sep 17 00:00:00 2001 From: Gyan Date: Sun, 8 Oct 2023 03:04:25 +0530 Subject: [PATCH 1/2] Implemented nth Fibonacci number using different methods --- src/math/fibonacci.lua | 107 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/math/fibonacci.lua diff --git a/src/math/fibonacci.lua b/src/math/fibonacci.lua new file mode 100644 index 0000000..32f59b2 --- /dev/null +++ b/src/math/fibonacci.lua @@ -0,0 +1,107 @@ +-- Fibonacci.lua + +-- Fibonacci Sequence: +-- The Fibonacci sequence is a series of numbers where each number (after the first two) is the sum of the two preceding ones. +-- More information: https://en.wikipedia.org/wiki/Fibonacci_number + +-- Author: Gyandeep + +-- Implemented nth Fibonacci number using different approaches in O(2^N) , O(N) , O(logN) , O(1) . + + +-- Function to calculate Fibonacci numbers using recursion +-- Time Complexity: O(2^n) +function fibonacci_recursive(n) + if n <= 0 then + return 0 + elseif n == 1 then + return 1 + else + return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2) + end +end + +-- Function to calculate Fibonacci numbers using dynamic programming (DP) +-- Time Complexity: O(n) +function fibonacci_dp(n) + local fib = {} + fib[0] = 0 + fib[1] = 1 + for i = 2, n do + fib[i] = fib[i - 1] + fib[i - 2] + end + return fib[n] +end + +-- Function to calculate Fibonacci numbers using Binet's formula +-- Time Complexity: O(1) +-- Limitation: Accurate results up to n = 70 due to limitations of floating-point precision. +function fibonacci_binet(n) + local phi = (1 + math.sqrt(5)) / 2 + local psi = (1 - math.sqrt(5)) / 2 + return math.floor((math.pow(phi, n) - math.pow(psi, n)) / math.sqrt(5)) +end + +-- Function to multiply two 2x2 matrices +-- Time Complexity: O(1) +function matrix_multiply(a, b) + local c = {} + c[1] = a[1] * b[1] + a[2] * b[3] + c[2] = a[1] * b[2] + a[2] * b[4] + c[3] = a[3] * b[1] + a[4] * b[3] + c[4] = a[3] * b[2] + a[4] * b[4] + return c +end + +-- Function to raise a 2x2 matrix to a power n using divide and conquer +-- Time Complexity: O(log(n)) +function matrix_power(matrix, n) + if n == 0 then + return {1, 0, 0, 1} -- Identity matrix + elseif n % 2 == 0 then + local half_pow = matrix_power(matrix, n / 2) + return matrix_multiply(half_pow, half_pow) + else + local half_pow = matrix_power(matrix, (n - 1) / 2) + return matrix_multiply(matrix, matrix_multiply(half_pow, half_pow)) + end +end + +-- Function to calculate Fibonacci numbers using matrix exponentiation +-- Time Complexity: O(log(n)) +function fibonacci_matrix(n) + if n <= 0 then + return 0 + else + local matrix = {1, 1, 1, 0} + local result_matrix = matrix_power(matrix, n - 1) + return result_matrix[1] + end +end + +-- Assert tests for all four functions +assert(fibonacci_recursive(0) == 0) +assert(fibonacci_recursive(1) == 1) +assert(fibonacci_recursive(5) == 5) +assert(fibonacci_recursive(10) == 55) + +assert(fibonacci_dp(0) == 0) +assert(fibonacci_dp(1) == 1) +assert(fibonacci_dp(5) == 5) +assert(fibonacci_dp(10) == 55) + +-- Test Binet's formula with known limitation +assert(fibonacci_binet(0) == 0) +assert(fibonacci_binet(1) == 1) +assert(fibonacci_binet(5) == 5) +assert(fibonacci_binet(10) == 55) + +-- Limitation test after n=70 value will start diverting +assert(fibonacci_binet(70) == 190392490709135) + +assert(fibonacci_matrix(0) == 0) +assert(fibonacci_matrix(1) == 1) +assert(fibonacci_matrix(5) == 5) +assert(fibonacci_matrix(10) == 55) + +print("All tests passed!") From f4ad2116c20a288871a0f8eb73e1ce20f714290f Mon Sep 17 00:00:00 2001 From: Gyan Date: Mon, 9 Oct 2023 02:04:29 +0530 Subject: [PATCH 2/2] seperated test suite into different file --- .spec/math/fibonacci_spec.lua | 34 ++++++++++++++++++++++++ package-lock.json | 6 +++++ src/math/fibonacci.lua | 29 +------------------- src/math/sieve_eratosthenes.lua | 47 +++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 28 deletions(-) create mode 100644 .spec/math/fibonacci_spec.lua create mode 100644 package-lock.json create mode 100644 src/math/sieve_eratosthenes.lua diff --git a/.spec/math/fibonacci_spec.lua b/.spec/math/fibonacci_spec.lua new file mode 100644 index 0000000..17daa3a --- /dev/null +++ b/.spec/math/fibonacci_spec.lua @@ -0,0 +1,34 @@ +-- Define the test suite for the Fibonacci module +describe("Fibonacci", function() + -- Test the recursive Fibonacci function + it("works with fibonacci_recursive", function() + assert.is_equal(0, fibonacci.fibonacci_recursive(0)) + assert.is_equal(1, fibonacci.fibonacci_recursive(1)) + assert.is_equal(5, fibonacci.fibonacci_recursive(5)) + assert.is_equal(55, fibonacci.fibonacci_recursive(10)) + end) + + -- Test the dynamic programming Fibonacci function + it("works with fibonacci_dp", function() + assert.is_equal(0, fibonacci.fibonacci_dp(0)) + assert.is_equal(1, fibonacci.fibonacci_dp(1)) + assert.is_equal(5, fibonacci.fibonacci_dp(5)) + assert.is_equal(55, fibonacci.fibonacci_dp(10)) + end) + + -- Test Binet's formula Fibonacci function + it("works with fibonacci_binet", function() + assert.is_equal(0, fibonacci.fibonacci_binet(0)) + assert.is_equal(1, fibonacci.fibonacci_binet(1)) + assert.is_equal(5, fibonacci.fibonacci_binet(5)) + assert.is_equal(55, fibonacci.fibonacci_binet(10)) + end) + + -- Test matrix exponentiation Fibonacci function + it("works with fibonacci_matrix", function() + assert.is_equal(0, fibonacci.fibonacci_matrix(0)) + assert.is_equal(1, fibonacci.fibonacci_matrix(1)) + assert.is_equal(5, fibonacci.fibonacci_matrix(5)) + assert.is_equal(55, fibonacci.fibonacci_matrix(10)) + end) +end) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7adf8bf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "Lua", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/src/math/fibonacci.lua b/src/math/fibonacci.lua index 32f59b2..c5d107e 100644 --- a/src/math/fibonacci.lua +++ b/src/math/fibonacci.lua @@ -77,31 +77,4 @@ function fibonacci_matrix(n) local result_matrix = matrix_power(matrix, n - 1) return result_matrix[1] end -end - --- Assert tests for all four functions -assert(fibonacci_recursive(0) == 0) -assert(fibonacci_recursive(1) == 1) -assert(fibonacci_recursive(5) == 5) -assert(fibonacci_recursive(10) == 55) - -assert(fibonacci_dp(0) == 0) -assert(fibonacci_dp(1) == 1) -assert(fibonacci_dp(5) == 5) -assert(fibonacci_dp(10) == 55) - --- Test Binet's formula with known limitation -assert(fibonacci_binet(0) == 0) -assert(fibonacci_binet(1) == 1) -assert(fibonacci_binet(5) == 5) -assert(fibonacci_binet(10) == 55) - --- Limitation test after n=70 value will start diverting -assert(fibonacci_binet(70) == 190392490709135) - -assert(fibonacci_matrix(0) == 0) -assert(fibonacci_matrix(1) == 1) -assert(fibonacci_matrix(5) == 5) -assert(fibonacci_matrix(10) == 55) - -print("All tests passed!") +end \ No newline at end of file diff --git a/src/math/sieve_eratosthenes.lua b/src/math/sieve_eratosthenes.lua new file mode 100644 index 0000000..f42fe6e --- /dev/null +++ b/src/math/sieve_eratosthenes.lua @@ -0,0 +1,47 @@ +-- Sieve.lua + +-- Sieve of Eratosthenes: +-- The Sieve of Eratosthenes is an efficient algorithm for finding all prime numbers up to a given limit. +-- More information: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes + +-- Author: Gyandeep (https://www.linkedin.com/in/gyandeep-katiyar-790ba6256/) + +-- Function to find all prime numbers up to a given limit using the Sieve of Eratosthenes +-- Time Complexity: O(n log log n) +function sieve_eratosthenes(limit) + -- Create a boolean array "is_prime" and initialize all entries as true + local is_prime = {} + for i = 2, limit do + is_prime[i] = true + end + + -- Start with the first prime number, 2 + local p = 2 + while p * p <= limit do + -- If is_prime[p] is still true, then it is a prime number + if is_prime[p] == true then + -- Mark all multiples of p as non-prime + for i = p * p, limit, p do + is_prime[i] = false + end + end + p = p + 1 + end + + -- Collect the prime numbers into a table + local primes = {} + for i = 2, limit do + if is_prime[i] == true then + table.insert(primes, i) + end + end + + return primes +end + +-- Assert tests for the Sieve of Eratosthenes function +assert(#sieve_eratosthenes(10) == 4) -- There are 4 prime numbers up to 10 (2, 3, 5, 7) +assert(#sieve_eratosthenes(20) == 8) -- There are 8 prime numbers up to 20 (2, 3, 5, 7, 11, 13, 17, 19) +assert(#sieve_eratosthenes(50) == 15) -- There are 15 prime numbers up to 50 + +print("All tests passed!")