Prime engine: generation, primality, factorization
up vote
0
down vote
favorite
I've just written my first C# class, so I'm looking for some feedback before I go and write more code. The goal of the code is to provide a Singleton-like class to deal with common operations on the set of prime numbers that I will need to complete projecteuler.net problems.
I'm interested in feedback for all aspects of the implementation (short of the actual prime generation algorithms, the 6*i +/- 1
method was used solely for its simplicity).
I'm also interested in feedback about how the interfaces are split up. I split these up into slices of functionality in an attempt to allow future implementation changes. I am planning to use DI (e.g. SimpleInjector) to bind the singleton instance to each of the interfaces, but I'm seriously starting to doubt this pattern.
I'm less interested in feedback about the selections of methods, I just chose a relatively minimal subset of methods that I know that I will need at some point - more methods will probably be added as needed.
Interfaces
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeFactorizer
{
IEnumerable<long> PrimeFactors(long value);
IEnumerable<long> UniquePrimeFactors(long value);
}
Implementation
public class PrimeEngine: IPrimeGenerator, IPrimeChecker, IPrimeFactorizer
{
private readonly ICollection<long> _primeCollection;
private long _indexFactor;
private long _maxChecked;
public PrimeEngine()
{
_primeCollection = new Collection<long> {2, 3};
_indexFactor = 1;
_maxChecked = 3;
}
private void CheckNextPossiblePrimeDoublet()
{
var low = 6 * _indexFactor - 1;
var high = low + 2;
if (IsPrime(low))
{
_primeCollection.Add(low);
}
if (IsPrime(high))
{
_primeCollection.Add(high);
}
_indexFactor += 1;
_maxChecked = high;
}
private IEnumerable<long> GetPossibleSmallerPrimeFactors(long value)
{
FillPrimesUntilRoot(value);
return PrimesUntilRoot(value);
}
public bool IsPrime(long value)
{
var primePool = GetPossibleSmallerPrimeFactors(value);
return primePool.All(prime => value % prime != 0);
}
private void FillPrimesUntilValue(long value)
{
while (_maxChecked < value)
{
CheckNextPossiblePrimeDoublet();
}
}
private void FillPrimesUntilCount(int count)
{
while (_primeCollection.Count < count)
{
CheckNextPossiblePrimeDoublet();
}
}
private static long FloorOfRoot(long value)
{
return (long) Math.Floor(Math.Sqrt(value));
}
private void FillPrimesUntilRoot(long value)
{
FillPrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimesUntilValue(long value)
{
FillPrimesUntilValue(value);
return _primeCollection.TakeWhile(prime => prime <= value);
}
public IEnumerable<long> PrimesUntilCount(int count)
{
FillPrimesUntilCount(count);
return _primeCollection.Take(count);
}
public IEnumerable<long> PrimesUntilRoot(long value)
{
return PrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimeFactors(long value)
{
FillPrimesUntilRoot(value);
foreach (var prime in PrimesUntilRoot(value))
{
if (prime > value) break;
while (value % prime == 0)
{
yield return prime;
value /= prime;
}
}
if (value != 1)
{
yield return value;
}
}
public IEnumerable<long> UniquePrimeFactors(long value)
{
return PrimeFactors(value).Distinct();
}
}
c# beginner primes
add a comment |
up vote
0
down vote
favorite
I've just written my first C# class, so I'm looking for some feedback before I go and write more code. The goal of the code is to provide a Singleton-like class to deal with common operations on the set of prime numbers that I will need to complete projecteuler.net problems.
I'm interested in feedback for all aspects of the implementation (short of the actual prime generation algorithms, the 6*i +/- 1
method was used solely for its simplicity).
I'm also interested in feedback about how the interfaces are split up. I split these up into slices of functionality in an attempt to allow future implementation changes. I am planning to use DI (e.g. SimpleInjector) to bind the singleton instance to each of the interfaces, but I'm seriously starting to doubt this pattern.
I'm less interested in feedback about the selections of methods, I just chose a relatively minimal subset of methods that I know that I will need at some point - more methods will probably be added as needed.
Interfaces
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeFactorizer
{
IEnumerable<long> PrimeFactors(long value);
IEnumerable<long> UniquePrimeFactors(long value);
}
Implementation
public class PrimeEngine: IPrimeGenerator, IPrimeChecker, IPrimeFactorizer
{
private readonly ICollection<long> _primeCollection;
private long _indexFactor;
private long _maxChecked;
public PrimeEngine()
{
_primeCollection = new Collection<long> {2, 3};
_indexFactor = 1;
_maxChecked = 3;
}
private void CheckNextPossiblePrimeDoublet()
{
var low = 6 * _indexFactor - 1;
var high = low + 2;
if (IsPrime(low))
{
_primeCollection.Add(low);
}
if (IsPrime(high))
{
_primeCollection.Add(high);
}
_indexFactor += 1;
_maxChecked = high;
}
private IEnumerable<long> GetPossibleSmallerPrimeFactors(long value)
{
FillPrimesUntilRoot(value);
return PrimesUntilRoot(value);
}
public bool IsPrime(long value)
{
var primePool = GetPossibleSmallerPrimeFactors(value);
return primePool.All(prime => value % prime != 0);
}
private void FillPrimesUntilValue(long value)
{
while (_maxChecked < value)
{
CheckNextPossiblePrimeDoublet();
}
}
private void FillPrimesUntilCount(int count)
{
while (_primeCollection.Count < count)
{
CheckNextPossiblePrimeDoublet();
}
}
private static long FloorOfRoot(long value)
{
return (long) Math.Floor(Math.Sqrt(value));
}
private void FillPrimesUntilRoot(long value)
{
FillPrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimesUntilValue(long value)
{
FillPrimesUntilValue(value);
return _primeCollection.TakeWhile(prime => prime <= value);
}
public IEnumerable<long> PrimesUntilCount(int count)
{
FillPrimesUntilCount(count);
return _primeCollection.Take(count);
}
public IEnumerable<long> PrimesUntilRoot(long value)
{
return PrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimeFactors(long value)
{
FillPrimesUntilRoot(value);
foreach (var prime in PrimesUntilRoot(value))
{
if (prime > value) break;
while (value % prime == 0)
{
yield return prime;
value /= prime;
}
}
if (value != 1)
{
yield return value;
}
}
public IEnumerable<long> UniquePrimeFactors(long value)
{
return PrimeFactors(value).Distinct();
}
}
c# beginner primes
The two first interfaces are identical - a copy/paste mistake?
– t3chb0t
3 mins ago
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I've just written my first C# class, so I'm looking for some feedback before I go and write more code. The goal of the code is to provide a Singleton-like class to deal with common operations on the set of prime numbers that I will need to complete projecteuler.net problems.
I'm interested in feedback for all aspects of the implementation (short of the actual prime generation algorithms, the 6*i +/- 1
method was used solely for its simplicity).
I'm also interested in feedback about how the interfaces are split up. I split these up into slices of functionality in an attempt to allow future implementation changes. I am planning to use DI (e.g. SimpleInjector) to bind the singleton instance to each of the interfaces, but I'm seriously starting to doubt this pattern.
I'm less interested in feedback about the selections of methods, I just chose a relatively minimal subset of methods that I know that I will need at some point - more methods will probably be added as needed.
Interfaces
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeFactorizer
{
IEnumerable<long> PrimeFactors(long value);
IEnumerable<long> UniquePrimeFactors(long value);
}
Implementation
public class PrimeEngine: IPrimeGenerator, IPrimeChecker, IPrimeFactorizer
{
private readonly ICollection<long> _primeCollection;
private long _indexFactor;
private long _maxChecked;
public PrimeEngine()
{
_primeCollection = new Collection<long> {2, 3};
_indexFactor = 1;
_maxChecked = 3;
}
private void CheckNextPossiblePrimeDoublet()
{
var low = 6 * _indexFactor - 1;
var high = low + 2;
if (IsPrime(low))
{
_primeCollection.Add(low);
}
if (IsPrime(high))
{
_primeCollection.Add(high);
}
_indexFactor += 1;
_maxChecked = high;
}
private IEnumerable<long> GetPossibleSmallerPrimeFactors(long value)
{
FillPrimesUntilRoot(value);
return PrimesUntilRoot(value);
}
public bool IsPrime(long value)
{
var primePool = GetPossibleSmallerPrimeFactors(value);
return primePool.All(prime => value % prime != 0);
}
private void FillPrimesUntilValue(long value)
{
while (_maxChecked < value)
{
CheckNextPossiblePrimeDoublet();
}
}
private void FillPrimesUntilCount(int count)
{
while (_primeCollection.Count < count)
{
CheckNextPossiblePrimeDoublet();
}
}
private static long FloorOfRoot(long value)
{
return (long) Math.Floor(Math.Sqrt(value));
}
private void FillPrimesUntilRoot(long value)
{
FillPrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimesUntilValue(long value)
{
FillPrimesUntilValue(value);
return _primeCollection.TakeWhile(prime => prime <= value);
}
public IEnumerable<long> PrimesUntilCount(int count)
{
FillPrimesUntilCount(count);
return _primeCollection.Take(count);
}
public IEnumerable<long> PrimesUntilRoot(long value)
{
return PrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimeFactors(long value)
{
FillPrimesUntilRoot(value);
foreach (var prime in PrimesUntilRoot(value))
{
if (prime > value) break;
while (value % prime == 0)
{
yield return prime;
value /= prime;
}
}
if (value != 1)
{
yield return value;
}
}
public IEnumerable<long> UniquePrimeFactors(long value)
{
return PrimeFactors(value).Distinct();
}
}
c# beginner primes
I've just written my first C# class, so I'm looking for some feedback before I go and write more code. The goal of the code is to provide a Singleton-like class to deal with common operations on the set of prime numbers that I will need to complete projecteuler.net problems.
I'm interested in feedback for all aspects of the implementation (short of the actual prime generation algorithms, the 6*i +/- 1
method was used solely for its simplicity).
I'm also interested in feedback about how the interfaces are split up. I split these up into slices of functionality in an attempt to allow future implementation changes. I am planning to use DI (e.g. SimpleInjector) to bind the singleton instance to each of the interfaces, but I'm seriously starting to doubt this pattern.
I'm less interested in feedback about the selections of methods, I just chose a relatively minimal subset of methods that I know that I will need at some point - more methods will probably be added as needed.
Interfaces
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeGenerator
{
IEnumerable<long> PrimesUntilValue(long value);
IEnumerable<long> PrimesUntilCount(int count);
}
public interface IPrimeFactorizer
{
IEnumerable<long> PrimeFactors(long value);
IEnumerable<long> UniquePrimeFactors(long value);
}
Implementation
public class PrimeEngine: IPrimeGenerator, IPrimeChecker, IPrimeFactorizer
{
private readonly ICollection<long> _primeCollection;
private long _indexFactor;
private long _maxChecked;
public PrimeEngine()
{
_primeCollection = new Collection<long> {2, 3};
_indexFactor = 1;
_maxChecked = 3;
}
private void CheckNextPossiblePrimeDoublet()
{
var low = 6 * _indexFactor - 1;
var high = low + 2;
if (IsPrime(low))
{
_primeCollection.Add(low);
}
if (IsPrime(high))
{
_primeCollection.Add(high);
}
_indexFactor += 1;
_maxChecked = high;
}
private IEnumerable<long> GetPossibleSmallerPrimeFactors(long value)
{
FillPrimesUntilRoot(value);
return PrimesUntilRoot(value);
}
public bool IsPrime(long value)
{
var primePool = GetPossibleSmallerPrimeFactors(value);
return primePool.All(prime => value % prime != 0);
}
private void FillPrimesUntilValue(long value)
{
while (_maxChecked < value)
{
CheckNextPossiblePrimeDoublet();
}
}
private void FillPrimesUntilCount(int count)
{
while (_primeCollection.Count < count)
{
CheckNextPossiblePrimeDoublet();
}
}
private static long FloorOfRoot(long value)
{
return (long) Math.Floor(Math.Sqrt(value));
}
private void FillPrimesUntilRoot(long value)
{
FillPrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimesUntilValue(long value)
{
FillPrimesUntilValue(value);
return _primeCollection.TakeWhile(prime => prime <= value);
}
public IEnumerable<long> PrimesUntilCount(int count)
{
FillPrimesUntilCount(count);
return _primeCollection.Take(count);
}
public IEnumerable<long> PrimesUntilRoot(long value)
{
return PrimesUntilValue(FloorOfRoot(value));
}
public IEnumerable<long> PrimeFactors(long value)
{
FillPrimesUntilRoot(value);
foreach (var prime in PrimesUntilRoot(value))
{
if (prime > value) break;
while (value % prime == 0)
{
yield return prime;
value /= prime;
}
}
if (value != 1)
{
yield return value;
}
}
public IEnumerable<long> UniquePrimeFactors(long value)
{
return PrimeFactors(value).Distinct();
}
}
c# beginner primes
c# beginner primes
edited 3 mins ago
t3chb0t
33.7k744108
33.7k744108
asked 4 hours ago
Jared Goguen
777312
777312
The two first interfaces are identical - a copy/paste mistake?
– t3chb0t
3 mins ago
add a comment |
The two first interfaces are identical - a copy/paste mistake?
– t3chb0t
3 mins ago
The two first interfaces are identical - a copy/paste mistake?
– t3chb0t
3 mins ago
The two first interfaces are identical - a copy/paste mistake?
– t3chb0t
3 mins ago
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208424%2fprime-engine-generation-primality-factorization%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The two first interfaces are identical - a copy/paste mistake?
– t3chb0t
3 mins ago