Skip previously excluded by-divisor candidates

This commit is contained in:
Marek Lemańczyk committed 2025-09-29 14:46:37 +02:00
1 parent fc74f2b59b
commit 4d2c70da8b
1 file changed
+72 -49
+72 -49
View File
@@ -1,4 +1,5 @@
using System.Buffers; using System.Buffers;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -30,13 +31,14 @@ internal static class Program
private static bool _primeFoundAfterInit; private static bool _primeFoundAfterInit;
private static bool _useGcdFilter; private static bool _useGcdFilter;
private static bool _useDivisor; private static bool _useDivisor;
private static bool _useResidueMode; private static bool _useResidueMode;
private static bool _useByDivisorMode; private static bool _useByDivisorMode;
private static bool _byDivisorPrecheckOnly; private static bool _byDivisorPrecheckOnly;
private static UInt128 _divisor; private static UInt128 _divisor;
private static MersenneNumberDivisorGpuTester? _divisorTester; private static MersenneNumberDivisorGpuTester? _divisorTester;
private static IMersenneNumberDivisorByDivisorTester? _byDivisorTester; private static IMersenneNumberDivisorByDivisorTester? _byDivisorTester;
private static ulong? _orderWarmupLimitOverride; private static Dictionary<ulong, (bool DetailedCheck, bool PassedAllTests)>? _byDivisorPreviousResults;
private static ulong? _orderWarmupLimitOverride;
private static unsafe delegate*<ulong, ref ulong, ulong> _transformP; private static unsafe delegate*<ulong, ref ulong, ulong> _transformP;
private static long _state; private static long _state;
private static bool _limitReached; private static bool _limitReached;
@@ -588,20 +590,28 @@ internal static class Program
} }
if (File.Exists(ResultsFileName)) Dictionary<ulong, (bool DetailedCheck, bool PassedAllTests)>? previousResults = useByDivisor ? new Dictionary<ulong, (bool DetailedCheck, bool PassedAllTests)>() : null;
{ _byDivisorPreviousResults = previousResults;
Console.WriteLine("Processing previous results...");
LoadResultsFile(ResultsFileName, (p, detailedCheck, passedAllTests) => if (File.Exists(ResultsFileName))
{ {
if (detailedCheck && passedAllTests) Console.WriteLine("Processing previous results...");
{ LoadResultsFile(ResultsFileName, (p, detailedCheck, passedAllTests) =>
_primeCount++; {
} if (detailedCheck && passedAllTests)
}); {
} _primeCount++;
else }
{
File.WriteAllText(ResultsFileName, $"p,searchedMersenne,detailedCheck,passedAllTests{Environment.NewLine}"); if (previousResults is not null)
{
previousResults[p] = (detailedCheck, passedAllTests);
}
});
}
else
{
File.WriteAllText(ResultsFileName, $"p,searchedMersenne,detailedCheck,passedAllTests{Environment.NewLine}");
} }
bool useFilter = !string.IsNullOrEmpty(filterFile); bool useFilter = !string.IsNullOrEmpty(filterFile);
@@ -760,35 +770,43 @@ internal static class Program
private static class ByDivisorScanner private static class ByDivisorScanner
{ {
internal static void Run(List<ulong> primes, ulong divisorCyclesSearchLimit, int threadCount) internal static void Run(List<ulong> primes, ulong divisorCyclesSearchLimit, int threadCount)
{ {
if (primes.Count == 0) if (primes.Count == 0)
{ {
return; return;
} }
List<ByDivisorPrimeState> states = new(primes.Count); List<ByDivisorPrimeState> states = new(primes.Count);
ByDivisorPrimeState stateToAdd; ByDivisorPrimeState stateToAdd;
bool searched = false; bool searched = false;
bool detailed = false; bool detailed = false;
ulong allowedMax = 0UL; ulong allowedMax = 0UL;
Dictionary<ulong, (bool DetailedCheck, bool PassedAllTests)>? previousResults = _byDivisorPreviousResults;
int skippedByPreviousResults = 0;
_byDivisorPrecheckOnly = true; _byDivisorPrecheckOnly = true;
ulong startPrime = _byDivisorStartPrime; ulong startPrime = _byDivisorStartPrime;
bool applyStartPrime = startPrime > 0UL; bool applyStartPrime = startPrime > 0UL;
foreach (ulong prime in primes) foreach (ulong prime in primes)
{ {
if (applyStartPrime && prime < startPrime) if (applyStartPrime && prime < startPrime)
{ {
continue; continue;
} }
if (!IsEvenPerfectCandidate(prime, divisorCyclesSearchLimit, out searched, out detailed)) if (previousResults is not null && previousResults.TryGetValue(prime, out var previousResult) && !previousResult.PassedAllTests)
{ {
PrintResult(prime, searched, detailed, false); skippedByPreviousResults++;
continue; continue;
} }
if (!IsEvenPerfectCandidate(prime, divisorCyclesSearchLimit, out searched, out detailed))
{
PrintResult(prime, searched, detailed, false);
continue;
}
allowedMax = _byDivisorTester!.GetAllowedMaxDivisor(prime); allowedMax = _byDivisorTester!.GetAllowedMaxDivisor(prime);
if (allowedMax < 3UL) if (allowedMax < 3UL)
@@ -806,10 +824,15 @@ internal static class Program
DetailedCheck = false, DetailedCheck = false,
}; };
states.Add(stateToAdd); states.Add(stateToAdd);
} }
_byDivisorPrecheckOnly = false; _byDivisorPrecheckOnly = false;
if (skippedByPreviousResults > 0)
{
Console.WriteLine($"Skipped {skippedByPreviousResults.ToString(CultureInfo.InvariantCulture)} primes excluded by previous results.");
}
if (states.Count == 0) if (states.Count == 0)
{ {