// LeetCode 3027 單元測試 // 使用 xUnit 框架 using Xunit; using System; using System.Collections.Generic; public class SolutionTests { private readonly Solution _solution; public SolutionTests() { _solution = new Solution(); } [Fact] public void TestCase1_ExampleFromProblem() { // Arrange int[][] points = new int[][] { new int[] {6, 2}, new int[] {4, 4}, new int[] {2, 6} }; int expected = 2; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase2_TwoPoints() { // Arrange int[][] points = new int[][] { new int[] {1, 3}, new int[] {2, 1} }; int expected = 1; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase3_NoValidPairs() { // Arrange - 沒有有效點對的情況 int[][] points = new int[][] { new int[] {1, 1}, new int[] {2, 2}, new int[] {3, 3} }; int expected = 0; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase4_SameXCoordinate() { // Arrange - x 座標相同的情況 int[][] points = new int[][] { new int[] {3, 5}, new int[] {3, 2}, new int[] {3, 1} }; int expected = 2; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase5_SameYCoordinate() { // Arrange - y 座標相同的情況 int[][] points = new int[][] { new int[] {1, 4}, new int[] {3, 4}, new int[] {5, 4} }; int expected = 2; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase6_PointsInsideRectangle() { // Arrange - 矩形內有其他點的情況 int[][] points = new int[][] { new int[] {0, 4}, // A new int[] {4, 0}, // B new int[] {2, 2} // C (在 A-B 矩形內) }; int expected = 2; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase7_PointsOnBorder() { // Arrange - 點在矩形邊界上的情況 int[][] points = new int[][] { new int[] {0, 3}, // A new int[] {3, 0}, // B new int[] {0, 0} // C (在矩形邊界上) }; int expected = 2; // (A,C) 和 (C,B) 有效 // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase8_NegativeCoordinates() { // Arrange - 負座標情況 (題目一允許 -10^9 到 10^9) int[][] points = new int[][] { new int[] {-5, 5}, new int[] {5, -5}, new int[] {0, 0} }; int expected = 2; // (-5,5) -> (0,0) 和 (0,0) -> (5,-5) 有效 // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase9_LargeCoordinates() { // Arrange - 大座標值情況 int[][] points = new int[][] { new int[] {-1000000, 1000000}, new int[] {1000000, -1000000}, new int[] {0, 0} }; int expected = 2; // Act var result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestEdgeCases_MinimumPoints() { // Arrange - 最少點數情況 (題目限制 n >= 2) int[][] points = new int[][] { new int[] {0, 1}, new int[] {1, 0} }; int expected = 1; // (0,1) 在 (1,0) 的左上方 // Act int result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestEdgeCases_MaximumCoordinateRange() { // Arrange - 最大座標範圍測試 int[][] points = new int[][] { new int[] {-1000000000, 1000000000}, // 最小x,最大y new int[] {1000000000, -1000000000}, // 最大x,最小y new int[] {0, 0} // 中心點 }; int expected = 2; // Act int result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase_LargerDataSet() { // Arrange - 較大的數據集 (接近題目一的限制 n <= 1000) var points = new List(); // 創建 100 個不同的點 (可以增加到更接近 1000,但為了測試速度這裡用 100) for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { points.Add(new int[] { i * 100 - 500, j * 100 - 500 }); } } int[][] pointsArray = points.ToArray(); // Act int result = _solution.NumberOfPairs(pointsArray); // Assert Assert.True(result >= 0); // 結果應該是非負數 Assert.True(result <= 100 * 99); // 最多不會超過所有可能的點對 } [Fact] public void TestCase_StressTest_MediumSize() { // Arrange - 中等規模壓力測試 (200個點) var points = new List(); var usedPoints = new HashSet(); var random = new Random(42); // 固定種子確保可重現 while (points.Count < 200) { int x = random.Next(-10000, 10001); // 較大範圍 int y = random.Next(-10000, 10001); string pointKey = $"{x},{y}"; if (!usedPoints.Contains(pointKey)) { usedPoints.Add(pointKey); points.Add(new int[] { x, y }); } } int[][] pointsArray = points.ToArray(); // Act var startTime = DateTime.Now; int result = _solution.NumberOfPairs(pointsArray); var endTime = DateTime.Now; var elapsed = endTime - startTime; // Assert Assert.True(result >= 0); Assert.True(result <= 200 * 199); Assert.True(elapsed.TotalMilliseconds < 5000); // 應該在5秒內完成 } [Fact] public void TestCase_AllPointsOnSameLine_Vertical() { // Arrange - 所有點在同一條垂直線上 int[][] points = new int[][] { new int[] {0, 10}, new int[] {0, 5}, new int[] {0, 0}, new int[] {0, -5}, new int[] {0, -10} }; int expected = 4; // 每個點都可以與y座標更小的點配對 // Act int result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } [Fact] public void TestCase_AllPointsOnSameLine_Horizontal() { // Arrange - 所有點在同一條水平線上 int[][] points = new int[][] { new int[] {-10, 0}, new int[] {-5, 0}, new int[] {0, 0}, new int[] {5, 0}, new int[] {10, 0} }; int expected = 4; // 每個點都可以與x座標更大的點配對 // Act int result = _solution.NumberOfPairs(points); // Assert Assert.Equal(expected, result); } }