diff --git a/PerfectNumbers.Core.Tests/HeuristicCombinedPrimeTesterTests.cs b/PerfectNumbers.Core.Tests/HeuristicCombinedPrimeTesterTests.cs index a03ccc5..307fdc7 100644 --- a/PerfectNumbers.Core.Tests/HeuristicCombinedPrimeTesterTests.cs +++ b/PerfectNumbers.Core.Tests/HeuristicCombinedPrimeTesterTests.cs @@ -13,7 +13,7 @@ public class HeuristicCombinedPrimeTesterTests [InlineData((byte)1)] [InlineData((byte)7)] [InlineData((byte)9)] - public void Enumerator_uses_two_a_one_b_schedule_by_default(byte lastDigit) + public void Enumerator_uses_one_a_one_b_schedule_by_default(byte lastDigit) { Span groupBState = stackalloc HeuristicCombinedPrimeTester.HeuristicGroupBSequenceState[4]; @@ -26,7 +26,8 @@ public class HeuristicCombinedPrimeTesterTests results.Add(candidate); } - results.Count.Should().BeGreaterThanOrEqualTo(16); + const int segmentsToCheck = 6; + results.Count.Should().BeGreaterThanOrEqualTo(4 + segmentsToCheck * 2); results[0].Value.Should().Be(3UL); results[0].Group.Should().Be(HeuristicCombinedPrimeTester.HeuristicDivisorGroup.GroupAConstant); results[1].Value.Should().Be(7UL); @@ -37,25 +38,51 @@ public class HeuristicCombinedPrimeTesterTests results[3].Group.Should().Be(HeuristicCombinedPrimeTester.HeuristicDivisorGroup.GroupAConstant); int index = 4; - const int segmentsToCheck = 3; for (int segment = 0; segment < segmentsToCheck; segment++) { - for (int i = 0; i < 2; i++) - { - HeuristicCombinedPrimeTester.HeuristicDivisorCandidate groupACandidate = results[index++]; - groupACandidate.Value.Should().BeGreaterThan(13UL); - (groupACandidate.Value % 10UL).Should().Be(3UL); - groupACandidate.Group.Should().NotBe(HeuristicCombinedPrimeTester.HeuristicDivisorGroup.GroupB); - } + HeuristicCombinedPrimeTester.HeuristicDivisorCandidate groupACandidate = results[index++]; + groupACandidate.Value.Should().BeGreaterThan(13UL); + (groupACandidate.Value % 10UL).Should().Be(3UL); + groupACandidate.Group.Should().NotBe(HeuristicCombinedPrimeTester.HeuristicDivisorGroup.GroupB); - for (int i = 0; i < 1; i++) - { - HeuristicCombinedPrimeTester.HeuristicDivisorCandidate groupBCandidate = results[index++]; - groupBCandidate.Value.Should().BeGreaterThan(13UL); - (groupBCandidate.Value % 10UL).Should().NotBe(3UL); - groupBCandidate.Group.Should().Be(HeuristicCombinedPrimeTester.HeuristicDivisorGroup.GroupB); - } + HeuristicCombinedPrimeTester.HeuristicDivisorCandidate groupBCandidate = results[index++]; + groupBCandidate.Value.Should().BeGreaterThan(13UL); + (groupBCandidate.Value % 10UL).Should().NotBe(3UL); + groupBCandidate.Group.Should().Be(HeuristicCombinedPrimeTester.HeuristicDivisorGroup.GroupB); + } + + } + + [Theory] + [Trait("Category", "Fast")] + [InlineData((byte)1)] + [InlineData((byte)7)] + [InlineData((byte)9)] + public void One_a_one_b_pattern_interleaves_group_a_and_group_b_values(byte lastDigit) + { + ReadOnlySpan combined = HeuristicCombinedPrimeTester.GetCombinedDivisors( + lastDigit, + HeuristicCombinedPrimeTester.CombinedDivisorPattern.OneAOneB); + + combined.Length.Should().BeGreaterThan(18); + combined[0].Should().Be(3U); + combined[1].Should().Be(7U); + combined[2].Should().Be(11U); + combined[3].Should().Be(13U); + + int index = 4; + const int segmentsToCheck = 6; + + for (int segment = 0; segment < segmentsToCheck; segment++) + { + uint groupAValue = combined[index++]; + groupAValue.Should().BeGreaterThan(13U); + (groupAValue % 10U).Should().Be(3U); + + uint groupBValue = combined[index++]; + groupBValue.Should().BeGreaterThan(13U); + (groupBValue % 10U).Should().NotBe(3U); } } diff --git a/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs b/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs index 240180f..88d36c5 100644 --- a/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs +++ b/PerfectNumbers.Core/HeuristicCombinedPrimeTester.cs @@ -428,7 +428,7 @@ Cleanup: private static ReadOnlySpan GetCombinedDivisors(byte nMod10) { - return GetCombinedDivisors(nMod10, CombinedDivisorPattern.TwoAOneB); + return GetCombinedDivisors(nMod10, CombinedDivisorPattern.OneAOneB); } internal static ReadOnlySpan GetCombinedDivisors(byte nMod10, CombinedDivisorPattern pattern)