Skip to content

Commit

Permalink
merge: algorithm: Bitwise log base 2 (TheAlgorithms#503)
Browse files Browse the repository at this point in the history
* feat: bitwise min

* fix: bitwise min, change for vararg

* fix: change min tests

* fix: benchmark for bitwise

* fix: rename tests

* fix: add value param

* fix: change condition

* feat: added description to some functions

* Updated Documentation in README.md

* fix: change descriptions

* Updated Documentation in README.md

* Updated Documentation in README.md

* Updated Documentation in README.md

* feat: abs algo

* Updated Documentation in README.md

* fix: add comment

* Updated Documentation in README.md

* fix: new comment

* Updated Documentation in README.md

* fix: rename func and remove package

* Updated Documentation in README.md

* Update math/abs.go

Co-authored-by: Taj <[email protected]>

* Updated Documentation in README.md

* Update math/binary/abs.go

Co-authored-by: Taj <[email protected]>

* Updated Documentation in README.md

* fix: rename func and move binary test

* add package description and add function name to comment

* Updated Documentation in README.md

* rename Intercept method to YIntercept

* Updated Documentation in README.md

* fix strings

* Updated Documentation in README.md

* fix commit

* fix name cos tests and rename epsilon to epsilonCos

* feat: sin

* Updated Documentation in README.md

* fix test for sin

* fix epsilon

* rename package to test

* fix afte review

* Updated Documentation in README.md

* Updated Documentation in README.md

* Updated Documentation in README.md

* @feat bitwise logarithm

* @fix: rename function name to LogBase2

Co-authored-by: Rak Laptudirm <[email protected]>
Co-authored-by: github-action <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Taj <[email protected]>
  • Loading branch information
4 people authored Apr 28, 2022
1 parent ff22113 commit 603f2fd
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 22 deletions.
58 changes: 36 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,22 +257,23 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
##### Functions:

1. [`Bin2`](./dynamic/binomialcoefficient.go#L21): Bin2 function
2. [`CutRodDp`](./dynamic/rodcutting.go#L21): CutRodDp solve the same problem using dynamic programming
3. [`CutRodRec`](./dynamic/rodcutting.go#L8): CutRodRec solve the problem recursively: initial approach
4. [`EditDistanceDP`](./dynamic/editdistance.go#L35): EditDistanceDP is an optimised implementation which builds on the ideas of the recursive implementation. We use dynamic programming to compute the DP table where dp[i][j] denotes the edit distance value of first[0..i-1] and second[0..j-1]. Time complexity is O(m * n) where m and n are lengths of the strings, first and second respectively.
5. [`EditDistanceRecursive`](./dynamic/editdistance.go#L10): EditDistanceRecursive is a naive implementation with exponential time complexity.
6. [`IsSubsetSum`](./dynamic/subsetsum.go#L14): No description provided.
7. [`Knapsack`](./dynamic/knapsack.go#L17): Knapsack solves knapsack problem return maxProfit
8. [`LongestCommonSubsequence`](./dynamic/longestcommonsubsequence.go#L8): LongestCommonSubsequence function
9. [`LongestIncreasingSubsequence`](./dynamic/longestincreasingsubsequence.go#L9): LongestIncreasingSubsequence returns the longest increasing subsequence where all elements of the subsequence are sorted in increasing order
10. [`LongestIncreasingSubsequenceGreedy`](./dynamic/longestincreasingsubsequencegreedy.go#L9): LongestIncreasingSubsequenceGreedy is a function to find the longest increasing subsequence in a given array using a greedy approach. The dynamic programming approach is implemented alongside this one. Worst Case Time Complexity: O(nlogn) Auxiliary Space: O(n), where n is the length of the array(slice). Reference: https://www.geeksforgeeks.org/construction-of-longest-monotonically-increasing-subsequence-n-log-n/
11. [`LpsDp`](./dynamic/longestpalindromicsubsequence.go#L21): LpsDp function
12. [`LpsRec`](./dynamic/longestpalindromicsubsequence.go#L7): LpsRec function
13. [`MatrixChainDp`](./dynamic/matrixmultiplication.go#L24): MatrixChainDp function
14. [`MatrixChainRec`](./dynamic/matrixmultiplication.go#L10): MatrixChainRec function
15. [`Max`](./dynamic/knapsack.go#L11): Max function - possible duplicate
16. [`NthCatalanNumber`](./dynamic/catalan.go#L13): NthCatalan returns the n-th Catalan Number Complexity: O(n²)
17. [`NthFibonacci`](./dynamic/fibonacci.go#L6): NthFibonacci returns the nth Fibonacci Number
2. [`CoinChange`](./dynamic/coinchange.go#L5): CoinChange finds the number of possible combinations of coins of different values which can get to the target amount.
3. [`CutRodDp`](./dynamic/rodcutting.go#L21): CutRodDp solve the same problem using dynamic programming
4. [`CutRodRec`](./dynamic/rodcutting.go#L8): CutRodRec solve the problem recursively: initial approach
5. [`EditDistanceDP`](./dynamic/editdistance.go#L35): EditDistanceDP is an optimised implementation which builds on the ideas of the recursive implementation. We use dynamic programming to compute the DP table where dp[i][j] denotes the edit distance value of first[0..i-1] and second[0..j-1]. Time complexity is O(m * n) where m and n are lengths of the strings, first and second respectively.
6. [`EditDistanceRecursive`](./dynamic/editdistance.go#L10): EditDistanceRecursive is a naive implementation with exponential time complexity.
7. [`IsSubsetSum`](./dynamic/subsetsum.go#L14): No description provided.
8. [`Knapsack`](./dynamic/knapsack.go#L17): Knapsack solves knapsack problem return maxProfit
9. [`LongestCommonSubsequence`](./dynamic/longestcommonsubsequence.go#L8): LongestCommonSubsequence function
10. [`LongestIncreasingSubsequence`](./dynamic/longestincreasingsubsequence.go#L9): LongestIncreasingSubsequence returns the longest increasing subsequence where all elements of the subsequence are sorted in increasing order
11. [`LongestIncreasingSubsequenceGreedy`](./dynamic/longestincreasingsubsequencegreedy.go#L9): LongestIncreasingSubsequenceGreedy is a function to find the longest increasing subsequence in a given array using a greedy approach. The dynamic programming approach is implemented alongside this one. Worst Case Time Complexity: O(nlogn) Auxiliary Space: O(n), where n is the length of the array(slice). Reference: https://www.geeksforgeeks.org/construction-of-longest-monotonically-increasing-subsequence-n-log-n/
12. [`LpsDp`](./dynamic/longestpalindromicsubsequence.go#L21): LpsDp function
13. [`LpsRec`](./dynamic/longestpalindromicsubsequence.go#L7): LpsRec function
14. [`MatrixChainDp`](./dynamic/matrixmultiplication.go#L24): MatrixChainDp function
15. [`MatrixChainRec`](./dynamic/matrixmultiplication.go#L10): MatrixChainRec function
16. [`Max`](./dynamic/knapsack.go#L11): Max function - possible duplicate
17. [`NthCatalanNumber`](./dynamic/catalan.go#L13): NthCatalan returns the n-th Catalan Number Complexity: O(n²)
18. [`NthFibonacci`](./dynamic/fibonacci.go#L6): NthFibonacci returns the nth Fibonacci Number

---
</details><details>
Expand Down Expand Up @@ -635,6 +636,16 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.

1. [`IsPangram`](./strings/pangram/ispangram.go#L21): No description provided.

---
</details><details>
<summary> <strong> parenthesis </strong> </summary>

---

##### Functions:

1. [`Parenthesis`](./strings/parenthesis/parenthesis.go#L12): parcounter will be 0 if all open parenthesis are closed correctly

---
</details><details>
<summary> <strong> pascal </strong> </summary>
Expand Down Expand Up @@ -727,11 +738,14 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.
1. [`Factorize`](./math/prime/primefactorization.go#L5): Factorize is a function that computes the exponents of each prime in the prime factorization of n
2. [`Generate`](./math/prime/sieve.go#L26): Generate returns a int slice of prime numbers up to the limit
3. [`GenerateChannel`](./math/prime/sieve.go#L9): Generate generates the sequence of integers starting at 2 and sends it to the channel `ch`
4. [`MillerRabinTest`](./math/prime/millerrabinprimalitytest.go#L59): MillerRabinTest Probabilistic test for primality of an integer based of the algorithm devised by Miller and Rabin.
5. [`MillerTest`](./math/prime/millerrabinprimalitytest.go#L32): MillerTest This is the intermediate step that repeats within the miller rabin primality test for better probabilitic chances of receiving the correct result.
6. [`NaiveApproach`](./math/prime/primecheck.go#L8): NaiveApproach checks if an integer is prime or not. Returns a bool.
7. [`PairApproach`](./math/prime/primecheck.go#L22): PairApproach checks primality of an integer and returns a bool. More efficient than the naive approach as number of iterations are less.
8. [`Sieve`](./math/prime/sieve.go#L16): Sieve Sieving the numbers that are not prime from the channel - basically removing them from the channels
4. [`MillerRabinDeterministic`](./math/prime/millerrabinprimalitytest.go#L121): MillerRabinDeterministic is a Deterministic version of the Miller-Rabin test, which returns correct results for all valid int64 numbers.
5. [`MillerRabinProbabilistic`](./math/prime/millerrabinprimalitytest.go#L101): MillerRabinProbabilistic is a probabilistic test for primality of an integer based of the algorithm devised by Miller and Rabin.
6. [`MillerRandomTest`](./math/prime/millerrabinprimalitytest.go#L77): MillerRandomTest This is the intermediate step that repeats within the miller rabin primality test for better probabilitic chances of receiving the correct result with random witnesses.
7. [`MillerTest`](./math/prime/millerrabinprimalitytest.go#L49): MillerTest tests whether num is a strong probable prime to a witness. Formally: a^d ≡ 1 (mod n) or a^(2^r * d) ≡ -1 (mod n), 0 <= r <= s
8. [`MillerTestMultiple`](./math/prime/millerrabinprimalitytest.go#L84): MillerTestMultiple is like MillerTest but runs the test for multiple witnesses.
9. [`NaiveApproach`](./math/prime/primecheck.go#L8): NaiveApproach checks if an integer is prime or not. Returns a bool.
10. [`PairApproach`](./math/prime/primecheck.go#L22): PairApproach checks primality of an integer and returns a bool. More efficient than the naive approach as number of iterations are less.
11. [`Sieve`](./math/prime/sieve.go#L16): Sieve Sieving the numbers that are not prime from the channel - basically removing them from the channels

---
</details><details>
Expand Down Expand Up @@ -807,7 +821,7 @@ Read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute.

##### Functions:

1. [`NewSegmentTree`](./structure/segmenttree/segmenttree.go#L114): No description provided.
1. [`NewSegmentTree`](./structure/segmenttree/segmenttree.go#L116): No description provided.

---
##### Types
Expand Down
18 changes: 18 additions & 0 deletions math/binary/logarithm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// author(s) [red_byte](https://github.com/i-redbyte)
// see logarithm_test.go

package binary

// LogBase2 Finding the exponent of n = 2**x using bitwise operations (logarithm in base 2 of n) [See more](https://en.wikipedia.org/wiki/Logarithm)
func LogBase2(n uint32) uint32 {
base := [5]uint32{0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}
exponents := [5]uint32{1, 2, 4, 8, 16}
var result uint32
for i := 4; i >= 0; i-- {
if n&base[i] != 0 {
n >>= exponents[i]
result |= exponents[i]
}
}
return result
}
48 changes: 48 additions & 0 deletions math/binary/logarithm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// logarithm_test.go
// description: Test for finding the exponent of n = 2**x using bitwise operations (logarithm in base 2 of n)
// author(s) [red_byte](https://github.com/i-redbyte)
// see logarithm.go

package binary

import (
"math"
"testing"
)

func TestLogBase2(t *testing.T) {
tests := []struct {
name string
n uint32
want uint32
}{
{"log2(1) = 0", 1, 0},
{"log2(2) = 1", 2, 1},
{"log2(4) = 2", 4, 2},
{"log2(8) = 3", 8, 3},
{"log2(16) = 4", 16, 4},
{"log2(32) = 5", 32, 5},
{"log2(64) = 6", 64, 6},
{"log2(128) = 7", 128, 7},
{"log2(256) = 8", 256, 8},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := LogBase2(test.n); got != test.want {
t.Errorf("LogBase2() = %v, want %v", got, test.want)
}
})
}
}

func BenchmarkBitwiseLogBase2(b *testing.B) {
for i := 0; i < b.N; i++ {
LogBase2(1024)
}
}

func BenchmarkMathPAckageLogBase2(b *testing.B) {
for i := 0; i < b.N; i++ {
math.Log2(1024)
}
}

0 comments on commit 603f2fd

Please sign in to comment.