diff --git a/Algorithms.Tests/Numeric/PrimeNumberTest.cs b/Algorithms.Tests/Numeric/PrimeNumberTest.cs new file mode 100644 index 00000000..7b5b018b --- /dev/null +++ b/Algorithms.Tests/Numeric/PrimeNumberTest.cs @@ -0,0 +1,37 @@ +using Algorithms.Numeric; + +namespace Algorithms.Tests.Numeric; + +public static class PrimeNumberTests +{ + /// + /// Tests the PrimeChecker.IsPrime method with various inputs (primes, composites, edge cases) + /// to ensure the result is correct. + /// + [TestCase(-5, ExpectedResult = false)] // Negative number + [TestCase(0, ExpectedResult = false)] // Zero + [TestCase(1, ExpectedResult = false)] // One + [TestCase(2, ExpectedResult = true)] // Smallest prime + [TestCase(3, ExpectedResult = true)] // Prime + [TestCase(4, ExpectedResult = false)] // Composite (2*2) + [TestCase(7, ExpectedResult = true)] // Prime + [TestCase(9, ExpectedResult = false)] // Composite (3*3) + [TestCase(13, ExpectedResult = true)] // Prime + [TestCase(15, ExpectedResult = false)] // Composite (3*5) + [TestCase(25, ExpectedResult = false)] // Composite (5*5) + [TestCase(29, ExpectedResult = true)] // Prime + [TestCase(35, ExpectedResult = false)] // Composite (5*7) + [TestCase(49, ExpectedResult = false)] // Composite (7*7) + [TestCase(97, ExpectedResult = true)] // Larger prime + [TestCase(100, ExpectedResult = false)] // Larger composite + public static bool IsPrime_ResultIsCorrect(int number) + { + // Arrange is implicit here + + // Act + var result = PrimeChecker.IsPrime(number); + + // Assert + return result; + } +} \ No newline at end of file diff --git a/Algorithms/Numeric/PrimeChecker.cs b/Algorithms/Numeric/PrimeChecker.cs new file mode 100644 index 00000000..91f64e18 --- /dev/null +++ b/Algorithms/Numeric/PrimeChecker.cs @@ -0,0 +1,55 @@ +namespace Algorithms.Numeric; + +/// +/// A prime number (or a prime) is a natural number greater than 1 that is not a product of two smaller natural numbers. +/// +public static class PrimeChecker +{ + /// + /// Checks if a number is a prime number or not using optimized trial division. + /// This method avoids checking multiples of 2 and 3, optimizing the loop by checking + /// divisors of the form 6k ± 1 up to the square root of the number. + /// + /// The integer number to check. + /// True if the number is prime; False otherwise. + public static bool IsPrime(int number) + { + // Numbers less than or equal to 1 are not prime. + if (number <= 1) + { + return false; + } + + // 2 and 3 are the first two prime numbers. + if (number <= 3) + { + return true; + } + + // Check for divisibility by 2 and 3. + if (number % 2 == 0 || number % 3 == 0) + { + return false; + } + + // Check for divisibility by numbers of the form 6k ± 1 up to sqrt(number). + // The loop increments by 6 to skip known non-prime divisors. + for (int i = 5; i <= number / i; i = i + 6) + { + // Check 6k - 1 + if (number % i == 0) + { + return false; + } + + // Check 6k + 1 + if (number % (i + 2) == 0) + { + return false; + } + } + + // If no divisors are found, the number is prime. + return true; + } +}