public void TransformToMagicSquareWithMinimumCostTest() { Assert.AreEqual(24, MagicSquares.TransformToMagicSquareWithMinimumCost(new int[, ] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } })); Assert.AreEqual(7, MagicSquares.TransformToMagicSquareWithMinimumCost(new int[, ] { { 5, 3, 4 }, { 1, 5, 8 }, { 6, 4, 2 } })); Assert.AreEqual(1, MagicSquares.TransformToMagicSquareWithMinimumCost(new int[, ] { { 4, 9, 2 }, { 3, 5, 7 }, { 8, 1, 5 } })); Assert.AreEqual(4, MagicSquares.TransformToMagicSquareWithMinimumCost(new int[, ] { { 4, 8, 2 }, { 4, 5, 7 }, { 6, 1, 6 } })); }
public void ComputeSets_ForNonUniqueValues_Throws() { var values = new int[4]; values.AsSpan().Fill(3); Assert.Throws <ArgumentException>(() => MagicSquares.ComputeSets(values)); }
/// <summary> /// Constructs a constraint that will enforce that the given <paramref name="squares"/> are /// magic squares based on the rows, columns, and, optionally, the diagonals. /// </summary> /// <param name="possibleValues"> /// The possible values that can be in the magic squares. /// </param> /// <param name="squares"> /// The locations of the magic squares. /// </param> /// <param name="includeDiagonals"> /// If true, values along the diagonals of the square must also sum to the magic number. /// </param> /// <exception cref="ArgumentException"> /// If the any of the given <paramref name="squares"/>' sizes are not compatible with the /// length of <paramref name="possibleValues"/>. /// </exception> public MagicSquaresConstraint(ReadOnlySpan <int> possibleValues, IEnumerable <Box> squares, bool includeDiagonals = true) { _size = possibleValues.Length; _magicSquares = squares.ToArray(); _squareSize = Boxes.IntSquareRoot(_size); _includeDiagonals = includeDiagonals; if (_magicSquares.Any( b => b.TopLeft.Row < 0 || b.TopLeft.Column < 0 || b.TopLeft.Row + b.Size > _size || b.TopLeft.Column + b.Size > _size || b.Size != _squareSize)) { throw new ArgumentException( $"Based on the {nameof(possibleValues)}, {nameof(squares)} must fit in a puzzle of size {_size} and have size {_squareSize}."); } _allPossibleValues = new BitVector(); for (int i = 0; i < possibleValues.Length; ++i) { if (_allPossibleValues.IsBitSet(possibleValues[i])) { throw new ArgumentException("Values must be unique."); } _allPossibleValues.SetBit(possibleValues[i]); } _possibleSets = MagicSquares.ComputeSets(possibleValues, _squareSize, _allPossibleValues); }
public void ComputeSets_ForNonSquareSizes_Throws(int size) { var values = new int[size]; for (int i = 0; i < size; ++i) { values[i] = i + 1; } Assert.Throws <ArgumentException>(() => MagicSquares.ComputeSets(values)); }
public void ComputeSum_ForStandardValues_Works(int size, int expectedSum) { var values = new int[size]; for (int i = 0; i < size; ++i) { values[i] = i + 1; } Assert.Equal(expectedSum, MagicSquares.ComputeSum(values)); }