diff --git a/algorithms/CSharp/README.md b/algorithms/CSharp/README.md index ef07a000..af05ac0c 100644 --- a/algorithms/CSharp/README.md +++ b/algorithms/CSharp/README.md @@ -7,6 +7,8 @@ For running the `.cs` file please using [.Net Finddle](https://dotnetfiddle.net/ ## Number Theory 1. [Big Mod Algorithm](src/Number-Theory/big-mod.cs) 2. [Sieve of Eratosthenes](src/Number-Theory/sieve-of-eratosthenes.cs) +3. [Bitwise Sieve of Eratosthenes](src/Number-Theory/bitwise-sieve-of-eratosthenes.cs) + ## Sorts diff --git a/algorithms/CSharp/src/Number-Theory/bitwise-sieve-of-eratosthenes.cs b/algorithms/CSharp/src/Number-Theory/bitwise-sieve-of-eratosthenes.cs new file mode 100644 index 00000000..2d0110d0 --- /dev/null +++ b/algorithms/CSharp/src/Number-Theory/bitwise-sieve-of-eratosthenes.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Algorithms.NumberTheory +{ + public class BitwiseSieveOfEratosthenes + { + public static bool CheckBit(int number, int position) => + (number & (1 << position)) != 0; + + public static int SetBit(int number, int position) => + number | (1 << position); + + public static List GeneratePrimeNumbers(int max) + { + int[] status = Enumerable.Repeat(0, max / 32 + 1).ToArray(); + int squareRoot = (int)Math.Sqrt(max * 1.0); + + for(int i = 3; i <= squareRoot; i += 2) + { + if(!CheckBit(status[i / 32], i % 32)) + { + for(int j = 2 * i; j <= max; j += i) + { + status[j / 32] = SetBit(status[j / 32], j % 32); + } + } + } + + List primeNumbers = new List(); + primeNumbers.Add(2); + + for(int i = 3; i <= max; i += 2) + { + if(!CheckBit(status[i / 32], i % 32)) + { + primeNumbers.Add(i); + } + } + + return primeNumbers; + } + + public static void Main() + { + List primeNumbers = GeneratePrimeNumbers(100); + Console.WriteLine(string.Join(", ", primeNumbers)); + } + } +} + +/* + * Bitwise Sieve is an optimized version of the Sieve of Eratosthenes + * Instead of keeping the status of a number in a single number, we use a bit + * We use 32 bit integers + * e.g: 0 has the status of 0-31, 1 has the status of 32-63, etc. + */ \ No newline at end of file diff --git a/algorithms/CSharp/test/Number-Theory/bitwise-sieve-of-eratosthenes.cs b/algorithms/CSharp/test/Number-Theory/bitwise-sieve-of-eratosthenes.cs new file mode 100644 index 00000000..4befb1d9 --- /dev/null +++ b/algorithms/CSharp/test/Number-Theory/bitwise-sieve-of-eratosthenes.cs @@ -0,0 +1,18 @@ +using NUnit.Framework; +using System.Collections.Generic; + +namespace Algorithms.Tests.Number_Theory +{ + [TestFixture] + public class BitwiseSieveOfEratosthenes + { + [TestCase(10, "2, 3, 5, 7")] + [TestCase(25, "2, 3, 5, 7, 11, 13, 17, 19, 23")] + [TestCase(100, "2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97")] + public void BitwiseSieveOfEratosthenes_ShouldReturnExpected(int max, string expected) + { + List primeNumbers = Algorithms.NumberTheory.BitwiseSieveOfEratosthenes.GeneratePrimeNumbers(max); + Assert.AreEqual(expected, string.Join(", ", primeNumbers)); + } + } +}