77 lines
2.1 KiB
C#
77 lines
2.1 KiB
C#
using System.Numerics;
|
|
using FluentAssertions;
|
|
using PerfectNumbers.Core.ByDivisor;
|
|
using Xunit;
|
|
using static PerfectNumbers.Core.ByDivisor.BitContradictionSolverWithAMultiplier;
|
|
|
|
namespace PerfectNumbers.Core.Tests;
|
|
|
|
public class BitContradictionSolverTests
|
|
{
|
|
[Fact]
|
|
public void ComputeColumnBounds_TracksForcedAndPossibleOnes()
|
|
{
|
|
bool[] a = [true, false];
|
|
bool[] q = [true, true];
|
|
|
|
ColumnBounds bounds = ComputeColumnBounds(a, q, 1);
|
|
|
|
bounds.ForcedOnes.Should().Be(1);
|
|
bounds.PossibleOnes.Should().Be(2);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryPropagateCarry_FailsWhenParityUnreachable()
|
|
{
|
|
CarryRange carry = CarryRange.Single(0);
|
|
bool success = TryPropagateCarry(
|
|
currentCarry: ref carry,
|
|
forcedOnes: 0,
|
|
possibleOnes: 0,
|
|
requiredResultBit: 1);
|
|
|
|
success.Should().BeFalse();
|
|
carry.Min.Should().Be(0);
|
|
carry.Max.Should().Be(0);
|
|
}
|
|
|
|
[Fact]
|
|
[Trait("Category", "Fast")]
|
|
public void ShouldPruneWithFinalPow2Shift_ReturnsTrue_WhenShiftedResidueStaysBelowModulusAndResidueIsNotOne()
|
|
{
|
|
bool shouldPrune = ShouldPruneWithFinalPow2Shift(
|
|
prefixResidue: new BigInteger(3),
|
|
modulus: new BigInteger(1000),
|
|
tailShift: 8);
|
|
|
|
shouldPrune.Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
[Trait("Category", "Fast")]
|
|
public void ShouldPruneWithFinalPow2Shift_ReturnsFalse_WhenResidueIsOne()
|
|
{
|
|
bool shouldPrune = ShouldPruneWithFinalPow2Shift(
|
|
prefixResidue: BigInteger.One,
|
|
modulus: new BigInteger(1000),
|
|
tailShift: 8);
|
|
|
|
shouldPrune.Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void TryPropagateCarry_ComputesNextCarryRange()
|
|
{
|
|
CarryRange carry = new(0, 1);
|
|
bool success = TryPropagateCarry(
|
|
currentCarry: ref carry,
|
|
forcedOnes: 1,
|
|
possibleOnes: 3,
|
|
requiredResultBit: 1);
|
|
|
|
success.Should().BeTrue();
|
|
carry.Min.Should().Be(0);
|
|
carry.Max.Should().Be(1);
|
|
}
|
|
}
|