Merge pull request #172 from mlemanczyk/codex/add-max-prime-parameter-to-evenperfectbitscanner
Add max prime filter option
This commit is contained in:
1 file changed
+68
-4
@@ -81,6 +81,8 @@ internal static class Program
|
|||||||
int scanBatchSize = 2_097_152, sliceSize = 32;
|
int scanBatchSize = 2_097_152, sliceSize = 32;
|
||||||
ulong residueKMax = 5_000_000UL;
|
ulong residueKMax = 5_000_000UL;
|
||||||
string filterFile = string.Empty;
|
string filterFile = string.Empty;
|
||||||
|
UInt128 maxPrimeLimit = UInt128.MaxValue;
|
||||||
|
bool maxPrimeConfigured = false;
|
||||||
string cyclesPath = DefaultCyclesPath;
|
string cyclesPath = DefaultCyclesPath;
|
||||||
int cyclesBatchSize = 512;
|
int cyclesBatchSize = 512;
|
||||||
bool continueCyclesGeneration = false;
|
bool continueCyclesGeneration = false;
|
||||||
@@ -109,6 +111,20 @@ internal static class Program
|
|||||||
currentP = ulong.Parse(arg.AsSpan(arg.IndexOf('=') + 1));
|
currentP = ulong.Parse(arg.AsSpan(arg.IndexOf('=') + 1));
|
||||||
startPrimeProvided = true;
|
startPrimeProvided = true;
|
||||||
}
|
}
|
||||||
|
else if (arg.StartsWith("--max-prime=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
ReadOnlySpan<char> value = arg.AsSpan(arg.IndexOf('=') + 1);
|
||||||
|
if (UInt128.TryParse(value, NumberStyles.None, CultureInfo.InvariantCulture, out UInt128 parsedMaxPrime))
|
||||||
|
{
|
||||||
|
maxPrimeLimit = parsedMaxPrime;
|
||||||
|
maxPrimeConfigured = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid value for --max-prime.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (arg.Equals("--increment=bit", StringComparison.OrdinalIgnoreCase))
|
else if (arg.Equals("--increment=bit", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
useBitTransform = true;
|
useBitTransform = true;
|
||||||
@@ -615,7 +631,21 @@ internal static class Program
|
|||||||
Console.WriteLine("Loading filter...");
|
Console.WriteLine("Loading filter...");
|
||||||
if (_useByDivisorMode)
|
if (_useByDivisorMode)
|
||||||
{
|
{
|
||||||
byDivisorCandidates = LoadByDivisorCandidates(filterFile);
|
int skippedByLimit = 0;
|
||||||
|
byDivisorCandidates = LoadByDivisorCandidates(filterFile, maxPrimeLimit, maxPrimeConfigured, out skippedByLimit);
|
||||||
|
if (maxPrimeConfigured)
|
||||||
|
{
|
||||||
|
if (skippedByLimit > 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Skipped {skippedByLimit} by-divisor candidate(s) above --max-prime limit.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (byDivisorCandidates.Count == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("No by-divisor candidates fall within the --max-prime limit.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -623,11 +653,23 @@ internal static class Program
|
|||||||
// we do not allocate fresh arrays while replaying large result filters.
|
// we do not allocate fresh arrays while replaying large result filters.
|
||||||
localFilter = new ulong[1024];
|
localFilter = new ulong[1024];
|
||||||
filterCount = 0;
|
filterCount = 0;
|
||||||
|
bool addedWithinLimit = false;
|
||||||
|
int skippedByLimit = 0;
|
||||||
LoadResultsFile(filterFile, (p, detailedCheck, passedAllTests) =>
|
LoadResultsFile(filterFile, (p, detailedCheck, passedAllTests) =>
|
||||||
{
|
{
|
||||||
if (passedAllTests)
|
if (!passedAllTests)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxPrimeConfigured && (UInt128)p > maxPrimeLimit)
|
||||||
|
{
|
||||||
|
skippedByLimit++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
localFilter[filterCount++] = p;
|
localFilter[filterCount++] = p;
|
||||||
|
addedWithinLimit = true;
|
||||||
if (p > maxP)
|
if (p > maxP)
|
||||||
{
|
{
|
||||||
maxP = p;
|
maxP = p;
|
||||||
@@ -639,13 +681,26 @@ internal static class Program
|
|||||||
filterCount = 0;
|
filterCount = 0;
|
||||||
Console.WriteLine($"Added {p}");
|
Console.WriteLine($"Added {p}");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (filterCount > 0)
|
if (filterCount > 0)
|
||||||
{
|
{
|
||||||
filter.AddRange(localFilter[..filterCount]);
|
filter.AddRange(localFilter[..filterCount]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxPrimeConfigured)
|
||||||
|
{
|
||||||
|
if (!addedWithinLimit)
|
||||||
|
{
|
||||||
|
Console.WriteLine("No filter candidates fall within the --max-prime limit.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skippedByLimit > 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Skipped {skippedByLimit} filter candidate(s) above --max-prime limit.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,9 +811,10 @@ internal static class Program
|
|||||||
StringBuilderPool.Return(_outputBuilder!);
|
StringBuilderPool.Return(_outputBuilder!);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<ulong> LoadByDivisorCandidates(string candidateFile)
|
private static List<ulong> LoadByDivisorCandidates(string candidateFile, UInt128 maxPrimeLimit, bool maxPrimeConfigured, out int skippedByLimit)
|
||||||
{
|
{
|
||||||
List<ulong> candidates = [];
|
List<ulong> candidates = [];
|
||||||
|
skippedByLimit = 0;
|
||||||
using FileStream readStream = new(candidateFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
using FileStream readStream = new(candidateFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
using StreamReader reader = new(readStream);
|
using StreamReader reader = new(readStream);
|
||||||
string? line;
|
string? line;
|
||||||
@@ -797,9 +853,16 @@ internal static class Program
|
|||||||
// TODO: Swap ulong.TryParse for the Utf8Parser-based fast path once the shared span helpers
|
// TODO: Swap ulong.TryParse for the Utf8Parser-based fast path once the shared span helpers
|
||||||
// arrive so by-divisor candidate loading avoids per-value string allocations.
|
// arrive so by-divisor candidate loading avoids per-value string allocations.
|
||||||
if (ulong.TryParse(span[start..index], NumberStyles.None, CultureInfo.InvariantCulture, out ulong parsed))
|
if (ulong.TryParse(span[start..index], NumberStyles.None, CultureInfo.InvariantCulture, out ulong parsed))
|
||||||
|
{
|
||||||
|
if (!maxPrimeConfigured || (UInt128)parsed <= maxPrimeLimit)
|
||||||
{
|
{
|
||||||
candidates.Add(parsed);
|
candidates.Add(parsed);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skippedByLimit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,6 +959,7 @@ internal static class Program
|
|||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine("Options:");
|
Console.WriteLine("Options:");
|
||||||
Console.WriteLine(" --prime=<value> starting exponent (p)");
|
Console.WriteLine(" --prime=<value> starting exponent (p)");
|
||||||
|
Console.WriteLine(" --max-prime=<value> inclusive upper bound for primes from filter files");
|
||||||
Console.WriteLine(" --increment=bit|add exponent increment method");
|
Console.WriteLine(" --increment=bit|add exponent increment method");
|
||||||
Console.WriteLine(" --threads=<value> number of worker threads");
|
Console.WriteLine(" --threads=<value> number of worker threads");
|
||||||
Console.WriteLine(" --block-size=<value> values processed per thread batch");
|
Console.WriteLine(" --block-size=<value> values processed per thread batch");
|
||||||
|
|||||||
Reference in new issue
Block a user