Skip to content

Commit 8a5db71

Browse files
authored
Fix Sieve of Eratosthenes (TheAlgorithms#377)
1 parent 59c7a7b commit 8a5db71

File tree

2 files changed

+66
-15
lines changed

2 files changed

+66
-15
lines changed

Algorithms.Tests/Other/SieveOfEratosthenesTests.cs

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
using System.Numerics;
1+
using System.Numerics;
22
using Algorithms.Other;
3+
using FluentAssertions;
34
using NUnit.Framework;
45

56
namespace Algorithms.Tests.Other
67
{
78
public static class SieveOfEratosthenesTests
89
{
9-
private static readonly BigInteger[] First10000PrimeNumbers =
10+
private static readonly long[] First10000PrimeNumbers =
1011
{
1112
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, 101, 103,
1213
107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
@@ -667,7 +668,17 @@ public static class SieveOfEratosthenesTests
667668
};
668669

669670
[Test]
670-
public static void First10_000PrimesCorrect() =>
671-
Assert.AreEqual(First10000PrimeNumbers, SieveOfEratosthenes.GetPrimeNumbers(10_000));
671+
public static void First10_000PrimesCorrect() =>
672+
Assert.AreEqual(First10000PrimeNumbers, new SieveOfEratosthenes(104729).GetPrimes());
673+
674+
[Test]
675+
public static void TestMaxNumber() => Assert.AreEqual(new SieveOfEratosthenes(69).MaximumNumber, 69);
676+
677+
[TestCase(13, true)]
678+
[TestCase(10, false)]
679+
public static void TestIsPrime(int input, bool expected)
680+
{
681+
Assert.AreEqual(new SieveOfEratosthenes(100).IsPrime(input), expected);
682+
}
672683
}
673684
}
+51-11
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,71 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Linq;
34
using System.Numerics;
5+
using System.Runtime.CompilerServices;
46

57
namespace Algorithms.Other
68
{
79
/// <summary>
8-
/// TODO.
10+
/// Implements the Sieve of Eratosthenes.
911
/// </summary>
10-
public static class SieveOfEratosthenes
12+
public class SieveOfEratosthenes
1113
{
14+
private readonly bool[] primes;
15+
1216
/// <summary>
13-
/// TODO.
17+
/// Initializes a new instance of the <see cref="SieveOfEratosthenes"/> class.
18+
/// Uses the Sieve of Eratosthenes to precalculate the primes from 0 up to maximumNumberToCheck.
19+
/// Requires enough memory to allocate maximumNumberToCheck bytes.
20+
/// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes .
1421
/// </summary>
15-
/// <param name="count">TODO. 2.</param>
16-
/// <returns>TODO. 3.</returns>
17-
public static List<BigInteger> GetPrimeNumbers(int count)
22+
/// <param name="maximumNumberToCheck">long which specifies the largest number you wish to know if it is prime.</param>
23+
public SieveOfEratosthenes(long maximumNumberToCheck)
1824
{
19-
var output = new List<BigInteger>();
20-
for (BigInteger n = 2; output.Count < count; n++)
25+
primes = new bool[maximumNumberToCheck + 1];
26+
27+
// initialize primes array
28+
Array.Fill(this.primes, true, 2, primes.Length - 2);
29+
30+
for(long i = 2; i * i <= maximumNumberToCheck; i++)
2131
{
22-
if (output.All(x => n % x != 0))
32+
if (!primes[i])
33+
{
34+
continue;
35+
}
36+
37+
for(long composite = i * i; composite <= maximumNumberToCheck; composite += i)
2338
{
24-
output.Add(n);
39+
primes[composite] = false;
2540
}
2641
}
42+
}
43+
44+
/// <summary>
45+
/// Gets the maximumNumberToCheck the class was instantiated with.
46+
/// </summary>
47+
public long MaximumNumber => primes.Length - 1;
2748

28-
return output;
49+
/// <summary>
50+
/// Returns a boolean indicating whether the number is prime.
51+
/// </summary>
52+
/// <param name="numberToCheck">The number you desire to know if it is prime or not.</param>
53+
/// <returns>A boolean indicating whether the number is prime or not.</returns>
54+
public bool IsPrime(long numberToCheck) => primes[numberToCheck];
55+
56+
/// <summary>
57+
/// Returns an IEnumerable of long primes in asending order.
58+
/// </summary>
59+
/// <returns>Primes in ascending order.</returns>
60+
public IEnumerable<long> GetPrimes()
61+
{
62+
for(long i = 2; i < primes.Length; i++)
63+
{
64+
if (primes[i])
65+
{
66+
yield return i;
67+
}
68+
}
2969
}
3070
}
3171
}

0 commit comments

Comments
 (0)