diff --git a/.gitignore b/.gitignore index 74b926f..1ea206a 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ docs/ # Code coverage *.lst +.aider* diff --git a/src/math/ceil.d b/src/math/ceil.d index 77c796b..fbe1c93 100644 --- a/src/math/ceil.d +++ b/src/math/ceil.d @@ -1,20 +1,30 @@ + import std; /** - * Returns the smallest (closest to negative infinity) - * - * @param number the number - * @return the smallest (closest to negative infinity) of given - * {@code number} -*/ + * Computes the smallest integer value that is greater than or equal to a given floating-point number. + * + * ### Step-by-Step: + * 1. `rem` = for get remainder of number when divided by 1. + * 2. In first if = if number is Positive and `rem != 0` (it has remainder) then `number - rem + 1`. + * 3. In second if = if number is Negative and `rem != 0` (it has remainder) then `number - rem`. + * 4. If number is already an integer then return the number as is. + * + * Params: + * number = The floating-point value to evaluate. + * + * Returns: + * If input has no remainder, it returns `number`. Otherwise it removes remaining part, adds one to `number` and returns it. + */ -double ceil(double number) { - if (number - cast(int) number == 0) { - return number; - } else if (number - cast(int) number > 0) { - return cast(int)(number + 1); - } else { - return cast(int) number; +double ceil(double number){ + double rem = number % 1; + if( number > 0 && rem != 0) { + return number - rem + 1; + } else if (number < 0 && rem != 0) { + return number - rem; + } else { + return number; } } @@ -23,6 +33,10 @@ unittest { assert(ceil(10.2) == 11); assert(ceil(9) == 9); assert(ceil(12.6) == 13); + + assert(ceil(-10.2) == -10); + assert(ceil(-12.6) == -12); + assert(ceil(-5.0) == -5); } diff --git a/src/math/floor.d b/src/math/floor.d new file mode 100644 index 0000000..532366b --- /dev/null +++ b/src/math/floor.d @@ -0,0 +1,39 @@ + +/** + * Computes the largest integer value that is less than or equal to a given floating-point number. + * + * ### Step-by-Step: + * 1. `rem` = for get remainder of number when divided by 1. + * 2. In first if = if number is Positive and `rem != 0` (it has remainder) then `x - rem`. + * 3. In second if = if number is Negative and `rem != 0` (it has remainder) then `x - rem - 1`. + * 4. If number is already an integer then return the number as is. + * + * Params: + * x = The floating-point value to evaluate. + * + * Returns: + * If input has no remainder, return `x`. Otherwise if number positive remove remaining and returns it, if negative, subtract one and return it. + */ + +double floor(double x) { + double rem = x % 1; + if( x > 0 && rem != 0) { + return x - rem; + } else if (x < 0 && rem != 0) { + return x - rem - 1; + } else { + return x; + } +} + + + + +unittest { + assert(floor(3.5) == 3); + assert(floor(-3.5) == -4); + assert(floor(3.0) == 3); + assert(floor(-3.0) == -3); +} + +void main() {} diff --git a/src/math/gcd.d b/src/math/gcd.d new file mode 100644 index 0000000..d5b1811 --- /dev/null +++ b/src/math/gcd.d @@ -0,0 +1,40 @@ +import std; + +/** + * Greatest Common Divisor (GCD) Calculation - Computes the largest positive integer that divides two integers without leaving a remainder. + * + * ### Step-by-Step: + * 1. If either input `a` or `b` is 0, return 0. + * 2. Loop continues until `b` is zero. + * 3. `temp` = store the value of `b` temporarily before update `b` to `a % b`. + * 4. `b = a % b` = update `b` to remainder of `a` divided by `b`. + * 5. `a = temp` = update `a` to previous value of `b`. + * + * Params: + * a = The first integer. + * b = The second integer. + * + * Returns: + * In the end return `a` which is the GCD of the original pair of integers. + */ + +long gcd(long a, long b) { + if (a == 0 || b == 0) { + return 0; + } + while (b != 0) { + long temp = b; + b = a % b; + a = temp; + } + return a; +} + +unittest { + assert(gcd(48, 18) == 6); + assert(gcd(56, 98) == 14); + assert(gcd(101, 10) == 1); + assert(gcd(54, 24) == 6); +} + +void main(){} diff --git a/src/math/is_prime.d b/src/math/is_prime.d new file mode 100644 index 0000000..972985b --- /dev/null +++ b/src/math/is_prime.d @@ -0,0 +1,39 @@ +import std; + +/** + * Prime Check - An algorithm to determine if an integer is a prime number. + * + * ### Step-by-Step: + * 1. First if input `n <= 1` return false because it is not prime number. + * 2. Second if input `n == 2` return true because 2 is a prime number. + * 3. Third if input `n` is even return false because even numbers greater than 2 are not prime. + * 4. Start a loop from 3 to square root of `n`, increment by 2. If `n` is divisible by any of these, return false. + * + * Params: + * n = The integer to check. + * + * Returns: + * In the end return true if `n` is not divisible by any number from 2 to square root of `n`. + */ + +bool is_prime(int n){ + if(n <= 1) return false; + if(n == 2) return true; + if(n % 2 == 0) return false; + for(int i = 3; i * i <= n; i += 2){ + if(n % i == 0) return false; + } + return true; +} +unittest { + assert(is_prime(2) == true); + assert(is_prime(3) == true); + assert(is_prime(4) == false); + assert(is_prime(5) == true); + assert(is_prime(10) == false); + assert(is_prime(13) == true); + assert(is_prime(17) == true); + assert(is_prime(20) == false); +} + +void main() {} diff --git a/src/math/lcm.d b/src/math/lcm.d new file mode 100644 index 0000000..dc9b260 --- /dev/null +++ b/src/math/lcm.d @@ -0,0 +1,45 @@ + +import std; + +/** + * Least Common Multiple (LCM) Calculation - Computes the smallest positive integer that is divisible by both of two given integers. + * + * ### Step-by-Step: + * 1. If any of inputs `a` or `b` are zero, return 0. + * 2. If any of inputs are negative number, we take absolute value of that. + * 3. `result` = store output and multiply two inputs. + * 4. In while loop, we take GCD of the two inputs. + * + * Params: + * a = The first integer. + * b = The second integer. + * + * Returns: + * In the end, multiply two inputs, divide by their GCD, and return this result. + */ + + +long lcm(long a , long b){ + if (a == 0 || b == 0) { + return 0; + } + if(a < 0) a = -a; + if(b < 0) b = -b; + + long result = a * b; + while (b != 0) { + long temp = b; + b = a % b; + a = temp; + } + return result / a; +} + +unittest { + assert(lcm(4, 6) == 12); + assert(lcm(21, 6) == 42); + assert(lcm(8, 9) == 72); + assert(lcm(15, 20) == 60); +} + +void main() {} diff --git a/src/math/prime_sieve.d b/src/math/prime_sieve.d new file mode 100644 index 0000000..0267e22 --- /dev/null +++ b/src/math/prime_sieve.d @@ -0,0 +1,51 @@ +import std; + +/** + * Prime Sieve - Generates all prime numbers up to a specified limit N using the Sieve of Eratosthenes algorithm. + * + * ### Step-by-Step: + * 1. In the first, we check that the input cannot be less than 2 because it is not a prime number. + * 2. We create a boolean array `is_prime` (size `n + 1`) to save valid outputs. + * 3. First we set the entire array to true. + * 4. We set members 0 and 1 to false because 0 and 1 are not prime. + * 5. In the loop, we check whether the current number is prime or not, and if not, saved in `is_prime` array. + * + * Params: + * n = The upper bound limit. + * + * Returns: + * In the end, checking values inside our validator array and added in `primes` array, return `primes`. + */ + + +int[] prime_sieve(int n){ + if(n < 2) return []; + bool[] is_prime = new bool[n + 1]; + is_prime[] = true; + is_prime[0] = false; + is_prime[1] = false; + for(int i = 2; i * i <= n; i++){ + if(is_prime[i]){ + for(int j = i * i; j <= n; j += i){ + is_prime[j] = false; + } + } + } + int[] primes = []; + for(int i = 2; i <= n; i++){ + if(is_prime[i]){ + primes ~= i; + } + } + return primes; +} + +unittest { + assert(prime_sieve(10) == [2, 3, 5, 7]); + assert(prime_sieve(20) == [2, 3, 5, 7, 11, 13, 17, 19]); + assert(prime_sieve(1) == []); + assert(prime_sieve(2) == [2]); +} + +void main() {} + diff --git a/src/math/round.d b/src/math/round.d new file mode 100644 index 0000000..aa4cfab --- /dev/null +++ b/src/math/round.d @@ -0,0 +1,48 @@ +import std; + +/** + * Rounding Function - Rounds a floating-point number to the nearest integer. Numbers exactly halfway between two integers are rounded away from zero. + * + * ### Step-by-Step: + * 1. `rem` = for get remainder of number when divided by 1. + * 2. In first if = if number is positive and fractional part `>= 0.5`, round up by subtracting `rem` and adding 1. + * 3. In second if = if number is positive and fractional part `< 0.5`, round down by subtracting `rem`. + * 4. In third if = if number is negative and fractional part `> -0.5`, round towards zero by subtracting `rem`. + * 5. In fourth if = if number is negative and fractional part `<= -0.5`, round away from zero by subtracting `rem` and 1. + * 6. Else = if number is already an integer, return the number as is. + * + * Params: + * x = The floating-point value to round. + * + * Returns: + * The rounded integer value according to the step conditions. + */ + + +double round(double x){ + double rem = x % 1; + if (rem >= 0.5 && x > 0){ + return x - rem + 1; + }else if (rem < 0.5 && x > 0){ + return x - rem; + }else if (rem > -0.5 && x < 0){ + return x - rem; + }else if (rem <= -0.5 && x < 0){ + return x - rem - 1; + } else { + return x; + } +} + + +unittest{ + assert(round(10.2) == 10); + assert(round(9) == 9); + assert(round(12.6) == 13); + + assert(round(-10.2) == -10); + assert(round(-12.6) == -13); + assert(round(-5.0) == -5); +} + +void main(){}