From 262a934d8996c085e78dce92e8f11aba2d792b78 Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 09:57:41 +0800 Subject: [PATCH 1/7] [#3025] note(numberOfPairs): add Description and init C# project --- .../README.md | 70 +++++++++++++++++++ .../csharp/Program.cs | 36 ++++++++++ .../csharp/csharp.csproj | 10 +++ .../test/SolutionTests.cs | 43 ++++++++++++ .../test/TestProject.csproj | 22 ++++++ .../test/edge_cases.md | 21 ++++++ 6 files changed, 202 insertions(+) create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/README.md create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/csharp/csharp.csproj create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/test/TestProject.csproj create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/README.md b/problems/3025-find-the-number-of-ways-to-place-people-i/README.md new file mode 100644 index 0000000..053c910 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/README.md @@ -0,0 +1,70 @@ +# [3025] Find The Number Of Ways To Place People I + +## 題目資訊 +- **難度**: Medium +- **標籤**: Array, Math, Geometry, Sorting, Enumeration +- **題目連結**: [LeetCode](https://leetcode.com/problems/find-the-number-of-ways-to-place-people-i/) +- **練習日期**: 2025-09-02 + +## 題目描述 +You are given a 2D array `points` of size `n x 2` representing integer coordinates of some points on a 2D plane, where `points[i] = [xi, yi]`. + +Count the number of pairs of points `(A, B)`, where + - `A` is on **the upper** left side of `B`, and + - there are no other points in the rectangle (or line) they make (**including the border**). + +Return the count. + +## 解題思路 + +### 初步分析 +- 這題主要考察什麼概念? +- 有什麼關鍵限制條件? +- 預期時間/空間複雜度? + +### 解法概述 +1. **暴力解法**: + - 思路: + - 時間複雜度:O(?) + - 空間複雜度:O(?) + +2. **優化解法**: + - 思路: + - 時間複雜度:O(?) + - 空間複雜度:O(?) + +## 測試案例 + +### 範例輸入輸出 +``` +Input: points = [[6,2],[4,4],[2,6]] +Output: 2 +Explanation: + - The left one is the pair (points[1], points[0]), where points[1] is on the upper left side of points[0] and the rectangle is empty. + - The left one is the pair (points[1], points[0]), where points[1] is on the upper left side of points[0] and the rectangle is empty. + - The right one is the pair (points[2], points[0]), where points[2] is on the upper left side of points[0], but points[1] is inside the rectangle so it's not a valid pair. +``` + +### 邊界情況 +- `2 <= n <= 50` +- `points[i].length == 2` +- `0 <= points[i][0], points[i][1] <= 50` +- All `points[i]` are distinct. + +## 學習筆記 + +### 今天學到什麼? +- + +### 遇到的困難 +- + +### 改善方向 +- + +### 相關題目 +- [題目編號] 題目名稱 - 相似概念 +- [題目編號] 題目名稱 - 進階版本 + +--- +**總結**: 這題的核心概念是...,適合練習...技巧。 diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs new file mode 100644 index 0000000..62d8ffc --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs @@ -0,0 +1,36 @@ +// LeetCode 3025: Find The Number Of Ways To Place People I +// 難度: Medium +// 日期: 2025-09-02 + +using System; +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public void Solve() { + // TODO: 實作解法 + Console.WriteLine("Hello LeetCode 3025!"); + } +} + +// 測試程式 +public class Program { + public static void Main() { + Solution sol = new Solution(); + sol.Solve(); + + // TODO: 加入測試案例 + // TestCase1(); + // TestCase2(); + } + + // 測試案例模板 + /* + static void TestCase1() { + // Input: + // Expected: + // Actual: + Console.WriteLine("Test 1: "); + } + */ +} diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/csharp.csproj b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/csharp.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/csharp.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs b/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs new file mode 100644 index 0000000..b7edff4 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs @@ -0,0 +1,43 @@ +// LeetCode 3025 單元測試 +// 使用 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() { + // Arrange + // TODO: 設定輸入資料 + // var input = ; + // var expected = ; + + // Act + // var result = _solution.YourMethod(input); + + // Assert + // Assert.Equal(expected, result); + + Assert.True(true); // 暫時通過,等待實作 + } + + [Fact] + public void TestCase2() { + // TODO: 第二個測試案例 + Assert.True(true); + } + + [Fact] + public void TestEdgeCases() { + // TODO: 邊界情況測試 + // 空陣列、單一元素、最大值、最小值等 + Assert.True(true); + } +} diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/test/TestProject.csproj b/problems/3025-find-the-number-of-ways-to-place-people-i/test/TestProject.csproj new file mode 100644 index 0000000..2f44c14 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/test/TestProject.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md b/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md new file mode 100644 index 0000000..977c4c5 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md @@ -0,0 +1,21 @@ +# 邊界情況清單 + +## 需要測試的邊界情況 +- [ ] 空輸入 (空陣列、空字串等) +- [ ] 單一元素 +- [ ] 重複元素 +- [ ] 最大值/最小值 +- [ ] 負數情況 +- [ ] 超大資料量 +- [ ] 特殊字符 (如果是字串題目) + +## 額外測試案例 +### 案例 1: +**輸入**: +**輸出**: +**說明**: + +### 案例 2: +**輸入**: +**輸出**: +**說明**: -- 2.49.1 From 5018b4ab9f927c8ec5059f9e28a9ef04cc558599 Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 11:11:15 +0800 Subject: [PATCH 2/7] [#3025] feat(numberOfPairs): add C# solution, add notes --- .../README.md | 20 +++-- .../csharp/Program.cs | 82 +++++++++++++++---- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/README.md b/problems/3025-find-the-number-of-ways-to-place-people-i/README.md index 053c910..aee914d 100644 --- a/problems/3025-find-the-number-of-ways-to-place-people-i/README.md +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/README.md @@ -18,14 +18,19 @@ Return the count. ## 解題思路 ### 初步分析 -- 這題主要考察什麼概念? -- 有什麼關鍵限制條件? +- 核心概念 + 幾何關係判斷 + 區域內點的檢測 +- 關鍵限制條件 + 1. A必須在B的左上方, A.x <= B.x, A.y >= B.y + 2. 矩形區域內(包含邊界)不能有其他點 - 預期時間/空間複雜度? ### 解法概述 1. **暴力解法**: - 思路: - - 時間複雜度:O(?) + - 遍歷所有點對 (A, B) + - 檢查每個pair形成的矩形, 裡面跟邊界會不會包含其他點 + - 時間複雜度:O(N^3) - 空間複雜度:O(?) 2. **優化解法**: @@ -54,17 +59,16 @@ Explanation: ## 學習筆記 ### 今天學到什麼? -- +- 二維空間判斷點大小 ### 遇到的困難 -- +- 無 ### 改善方向 -- +- 無 ### 相關題目 -- [題目編號] 題目名稱 - 相似概念 -- [題目編號] 題目名稱 - 進階版本 +- [#223](https://leetcode.com/problems/rectangle-area/) Rectangle Area --- **總結**: 這題的核心概念是...,適合練習...技巧。 diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs index 62d8ffc..8b43681 100644 --- a/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs @@ -4,33 +4,83 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; -public class Solution { - public void Solve() { - // TODO: 實作解法 - Console.WriteLine("Hello LeetCode 3025!"); +public class Solution +{ + public int NumberOfPairsWithBruteForce(int[][] points) + { + // 遍歷所有點對 (A, B) + // 檢查每個pair形成的矩形, 裡面跟邊界會不會包含其他點 + + // points[0].Length == 2 + int n = points.Length; + int count = 0; + + for (var i = 0; i < n; i++) + { + for (var j = 0; j < n; j++) + { + if (i == j) continue; + + int[] pointA = points[i]; + int[] pointB = points[j]; + + // check if A.x <= B.x && A.y >= B.y + // if yes, check if any points in rectangle + if (pointA[0] <= pointB[0] && pointA[1] >= pointB[1]) + { + // difinition of border + bool hasOtherPoint = false; + int minX = pointA[0]; + int maxX = pointB[0]; + int minY = pointB[1]; + int maxY = pointA[1]; + + // check other point if its in border + for (var k = 0; k < n; k++) + { + if (k == i || k == j) continue; + + var pointC = points[k]; + if (minX <= pointC[0] && pointC[0] <= maxX + && minY <= pointC[1] && pointC[1] <= maxY) + { + hasOtherPoint = true; + break; + } + } + + if (!hasOtherPoint) count++; + } + } + } + return count; } } -// 測試程式 public class Program { public static void Main() { - Solution sol = new Solution(); - sol.Solve(); - - // TODO: 加入測試案例 - // TestCase1(); - // TestCase2(); + Solution solution = new Solution(); + + // 測試案例 + TestCase(solution); } - // 測試案例模板 - /* - static void TestCase1() { + static void TestCase(Solution solution) { // Input: + int[][] points = new int[][] { + new int[] {6, 2}, + new int[] {4, 4}, + new int[] {2, 6} + }; // Expected: + Console.WriteLine($"測試案例 1: [[6,2],[4,4],[2,6]]"); + Console.WriteLine($"預期: 2"); + // Actual: - Console.WriteLine("Test 1: "); + int result1 = solution.NumberOfPairsWithBruteForce(points); + Console.WriteLine($"Brute Force: {result1}"); } - */ } -- 2.49.1 From 38f948f6911acde17dc2f25d20f1a385ae701b41 Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 12:28:52 +0800 Subject: [PATCH 3/7] [#3025] test(numberOfPairs): write C# unit test --- .../README.md | 9 +- .../csharp/Program.cs | 10 +- .../test/SolutionTests.cs | 251 ++++++++++++++++-- .../test/edge_cases.md | 28 +- 4 files changed, 243 insertions(+), 55 deletions(-) diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/README.md b/problems/3025-find-the-number-of-ways-to-place-people-i/README.md index aee914d..97f42de 100644 --- a/problems/3025-find-the-number-of-ways-to-place-people-i/README.md +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/README.md @@ -26,17 +26,12 @@ Return the count. - 預期時間/空間複雜度? ### 解法概述 -1. **暴力解法**: +**解法**: - 思路: - 遍歷所有點對 (A, B) - 檢查每個pair形成的矩形, 裡面跟邊界會不會包含其他點 - 時間複雜度:O(N^3) - - 空間複雜度:O(?) - -2. **優化解法**: - - 思路: - - 時間複雜度:O(?) - - 空間複雜度:O(?) + - 空間複雜度:O(1) ## 測試案例 diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs index 8b43681..ff14dbc 100644 --- a/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/csharp/Program.cs @@ -9,7 +9,7 @@ using System.Linq; public class Solution { - public int NumberOfPairsWithBruteForce(int[][] points) + public int NumberOfPairs(int[][] points) { // 遍歷所有點對 (A, B) // 檢查每個pair形成的矩形, 裡面跟邊界會不會包含其他點 @@ -76,11 +76,11 @@ public class Program { new int[] {2, 6} }; // Expected: - Console.WriteLine($"測試案例 1: [[6,2],[4,4],[2,6]]"); - Console.WriteLine($"預期: 2"); + Console.WriteLine($"Test Case: [[6,2],[4,4],[2,6]]"); + Console.WriteLine($"Expected: 2"); // Actual: - int result1 = solution.NumberOfPairsWithBruteForce(points); - Console.WriteLine($"Brute Force: {result1}"); + int result1 = solution.NumberOfPairs(points); + Console.WriteLine($"Result: {result1}"); } } diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs b/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs index b7edff4..0dbedc2 100644 --- a/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/test/SolutionTests.cs @@ -5,39 +5,240 @@ using Xunit; using System; using System.Collections.Generic; -public class SolutionTests { +public class SolutionTests +{ private readonly Solution _solution; - - public SolutionTests() { + + public SolutionTests() + { _solution = new Solution(); } - + [Fact] - public void TestCase1() { + public void TestCase1_ExampleFromProblem() + { // Arrange - // TODO: 設定輸入資料 - // var input = ; - // var expected = ; + 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 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_IdenticalCoordinates() + { + // Arrange - 座標值相同的情況 + int[][] points = new int[][] { + new int[] {2, 2}, + new int[] {2, 2} // 題目保證所有點都不同,但測試邊界 + }; + + // 這個測試案例實際上違反了題目條件 (All points[i] are distinct) + // 但可以測試程式的健壯性 + int expected = 2; // 兩個相同點互相滿足左上方條件 + + // Act + int result = _solution.NumberOfPairs(points); + + // Assert + Assert.Equal(expected, result); + } + + [Fact] + public void TestEdgeCases_MaxCoordinateValues() + { + // Arrange - 最大座標值情況 (題目限制 0 <= coordinates <= 50) + int[][] points = new int[][] { + new int[] {0, 50}, + new int[] {50, 0}, + new int[] {25, 25} + }; + int expected = 2; // (A,C) 和 (C,B) 有效 + + // Act + int result = _solution.NumberOfPairs(points); + + // Assert + Assert.Equal(expected, result); + } + + [Fact] + public void TestEdgeCases_EmptyArray() + { + // Arrange - 空陣列情況 + int[][] points = new int[0][]; + int expected = 0; + + // Act + int result = _solution.NumberOfPairs(points); + + // Assert + Assert.Equal(expected, result); + } + + [Fact] + public void TestEdgeCases_MaxPoints_AllDistinct_RandomPattern() { + // Arrange - 50個不同的點,更複雜的模式 + var points = new List(); + + // 創建一個螺旋模式的50個不同點,確保都在 [0,50] 範圍內且互不相同 + var usedPoints = new HashSet(); + var random = new Random(42); // 固定種子確保測試可重現 + + while (points.Count < 50) { + int x = random.Next(0, 51); // 0-50 + int y = random.Next(0, 51); // 0-50 + string pointKey = $"{x},{y}"; + + if (!usedPoints.Contains(pointKey)) { + usedPoints.Add(pointKey); + points.Add(new int[] { x, y }); + } + } + + int[][] pointsArray = points.ToArray(); + + // 由於是隨機分佈,很難預測確切結果,但應該是一個合理的正數 + // 這個測試主要驗證程式在最大輸入時不會崩潰或超時 // Act - // var result = _solution.YourMethod(input); + int result = _solution.NumberOfPairs(pointsArray); // Assert - // Assert.Equal(expected, result); - - Assert.True(true); // 暫時通過,等待實作 - } - - [Fact] - public void TestCase2() { - // TODO: 第二個測試案例 - Assert.True(true); - } - - [Fact] - public void TestEdgeCases() { - // TODO: 邊界情況測試 - // 空陣列、單一元素、最大值、最小值等 - Assert.True(true); + Assert.True(result >= 0); // 至少結果應該是非負數 + Assert.True(result <= 50 * 49); // 最多不會超過所有可能的點對 } } diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md b/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md index 977c4c5..866e9a2 100644 --- a/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/test/edge_cases.md @@ -1,21 +1,13 @@ # 邊界情況清單 ## 需要測試的邊界情況 -- [ ] 空輸入 (空陣列、空字串等) -- [ ] 單一元素 -- [ ] 重複元素 -- [ ] 最大值/最小值 -- [ ] 負數情況 -- [ ] 超大資料量 -- [ ] 特殊字符 (如果是字串題目) - -## 額外測試案例 -### 案例 1: -**輸入**: -**輸出**: -**說明**: - -### 案例 2: -**輸入**: -**輸出**: -**說明**: +- [x] 空輸入 (空陣列) - `TestEdgeCases_EmptyArray` +- [x] 最少元素 (n=2) - `TestEdgeCases_MinimumPoints` +- [x] 重複座標 (雖然違反題目條件) - `TestEdgeCases_IdenticalCoordinates` +- [x] 最大值/最小值 (座標範圍 [0,50]) - `TestEdgeCases_MaxCoordinateValues` +- [x] 最大資料量 (n=50) - `TestEdgeCases_MaxPoints_AllDistinct_RandomPattern` +- [x] 相同 x 座標 - `TestCase4_SameXCoordinate` +- [x] 相同 y 座標 - `TestCase5_SameYCoordinate` +- [x] 矩形內含其他點 - `TestCase6_PointsInsideRectangle` +- [x] 點在矩形邊界上 - `TestCase7_PointsOnBorder` +- [x] 無有效點對情況 - `TestCase3_NoValidPairs` -- 2.49.1 From b99708dc3682a1f0833c6695b4c2ecd0888f340a Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 12:35:26 +0800 Subject: [PATCH 4/7] [#3025] note(numberOfPairs): add monthly note --- logs/2025-09.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/logs/2025-09.md b/logs/2025-09.md index 7f7c42e..66a5363 100644 --- a/logs/2025-09.md +++ b/logs/2025-09.md @@ -5,7 +5,8 @@ ### Week 1 | 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 | |------|------|------|------|------|------|------| -| 09-01 | Maximum Average Pass Ratio | Medium | C# | 1hr | Done | 第一次用到Priority Queue | +| 09/01 | Maximum Average Pass Ratio | Medium | C# | 1hr | Done | 第一次用到Priority Queue | +| 09/02| Find The Number of Ways to Place People I | Medium | C# | 0.5hr | Done | 二維點位判斷 | ### Week 2 | 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 | @@ -25,13 +26,13 @@ ## 📈 本月統計 ### 完成情況 -- **總練習天數**: 1 天 -- **完成題數**: 1題 -- **語言分布**: C# 1(題), Go 0(題) -- **難度分布**: Easy 0(題), Medium 1(題), Hard 0(題) +- **總練習天數**: 2 天 +- **完成題數**: 2題 +- **語言分布**: C# 2(題), Go 0(題) +- **難度分布**: Easy 0(題), Medium 2(題), Hard 0(題) ### 時間投入 -- **總時間**: 1小時 +- **總時間**: 1.5小時 - **平均每題**: 分鐘 - **每日平均**: 分鐘 -- 2.49.1 From c760afc0f76f0713a55c1cb0b4870edb9713a670 Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 13:31:22 +0800 Subject: [PATCH 5/7] [#3025] feat(numberOfPairs): add golang solution --- .../go/go.mod | 3 + .../go/main.go | 70 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/go/go.mod create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/go/main.go diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/go/go.mod b/problems/3025-find-the-number-of-ways-to-place-people-i/go/go.mod new file mode 100644 index 0000000..3879058 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/go/go.mod @@ -0,0 +1,3 @@ +module leetcode-3025 + +go 1.18 diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/go/main.go b/problems/3025-find-the-number-of-ways-to-place-people-i/go/main.go new file mode 100644 index 0000000..b48d086 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/go/main.go @@ -0,0 +1,70 @@ +// LeetCode 3025: Find The Number Of Ways To Place People I +// 難度: Medium +// 日期: 2025-09-02 + +package main + +import "fmt" + +// TODO: 實作解法 +func numberOfPairs(points [][]int) int { + n := len(points) + count := 0; + + for i:= 0; i < n; i++{ + for j := 0; j < n; j++{ + if i == j { + continue + } + + pointA := points[i] + pointB := points[j] + + if pointA[0] <= pointB[0] && pointA[1] >= pointB[1] { + hasOtherPoint := false; + minX := pointA[0] + maxX := pointB[0] + minY := pointB[1] + maxY := pointA[1] + + for k := 0; k < n; k++{ + if i == k || j == k{ + continue + } + + pointC := points[k] + + if minX <= pointC[0] && pointC[0] <= maxX && minY <= pointC[1] && pointC[1] <= maxY{ + hasOtherPoint = true + break + } + } + + if !hasOtherPoint{ + count++ + } + } + } + } + return count; +} + +func main() { + testCase() +} + +// 測試案例模板 +func testCase() { + // Input: + points := [][]int{ + {6, 2}, + {4, 4}, + {2, 6}, + } + // Expected: + fmt.Printf("Test Case: [[6,2],[4,4],[2,6]]\n") + fmt.Printf("Expected: 2\n") + // Actual: + result := numberOfPairs(points) + fmt.Printf("Result: %d\n", result) +} -- 2.49.1 From 0c278fa275e2a77335685ead8239999da8c0e84f Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 14:05:40 +0800 Subject: [PATCH 6/7] [#3025] test(numberOfPairs): add golang unit test --- .../go/main_test.go | 239 ++++++++++++++++++ .../test/run_tests.sh | 39 +++ 2 files changed, 278 insertions(+) create mode 100644 problems/3025-find-the-number-of-ways-to-place-people-i/go/main_test.go create mode 100755 problems/3025-find-the-number-of-ways-to-place-people-i/test/run_tests.sh diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/go/main_test.go b/problems/3025-find-the-number-of-ways-to-place-people-i/go/main_test.go new file mode 100644 index 0000000..dd276cf --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/go/main_test.go @@ -0,0 +1,239 @@ +// LeetCode 3025 Go 單元測試 +package main + +import ( + "math/rand" + "testing" + "fmt" +) + +func TestCase1_ExampleFromProblem(t *testing.T) { + // Arrange + points := [][]int{ + {6, 2}, + {4, 4}, + {2, 6}, + } + expected := 2 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase1 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestCase2_TwoPoints(t *testing.T) { + // Arrange + points := [][]int{ + {1, 3}, + {2, 1}, + } + expected := 1 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase2 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestCase3_NoValidPairs(t *testing.T) { + // Arrange - 沒有有效點對的情況 + points := [][]int{ + {1, 1}, + {2, 2}, + {3, 3}, + } + expected := 0 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase3 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestCase4_SameXCoordinate(t *testing.T) { + // Arrange - x 座標相同的情況 + points := [][]int{ + {3, 5}, // A + {3, 2}, // B + {3, 1}, // C + } + // 詳細分析: + // (A, B): (3,5) -> (3,2) ✓ 矩形是線段,無其他點 + // (A, C): (3,5) -> (3,1) ✗ 點B在矩形內 + // (B, C): (3,2) -> (3,1) ✓ 矩形是線段,無其他點 + expected := 2 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase4 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestCase5_SameYCoordinate(t *testing.T) { + // Arrange - y 座標相同的情況 + points := [][]int{ + {1, 4}, // A + {3, 4}, // B + {5, 4}, // C + } + // 詳細分析: + // (A, B): (1,4) -> (3,4) ✓ 矩形是線段,無其他點 + // (A, C): (1,4) -> (5,4) ✗ 點B在矩形內 + // (B, C): (3,4) -> (5,4) ✓ 矩形是線段,無其他點 + expected := 2 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase5 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestCase6_PointsInsideRectangle(t *testing.T) { + // Arrange - 矩形內有其他點的情況 + points := [][]int{ + {0, 4}, // A + {4, 0}, // B + {2, 2}, // C + } + // 詳細分析: + // (A, B): (0,4) -> (4,0) ✗ 點C在矩形內 + // (A, C): (0,4) -> (2,2) ✓ 點B不在矩形內 + // (C, B): (2,2) -> (4,0) ✓ 點A不在矩形內 + expected := 2 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase6 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestCase7_PointsOnBorder(t *testing.T) { + // Arrange - 點在矩形邊界上的情況 + points := [][]int{ + {0, 3}, // A + {3, 0}, // B + {0, 0}, // C + } + // 詳細分析: + // (A, B): (0,3) -> (3,0) ✗ 點C在矩形邊界上 + // (A, C): (0,3) -> (0,0) ✓ 矩形是線段,點B不在其中 + // (C, B): (0,0) -> (3,0) ✓ 矩形是線段,點A不在其中 + expected := 2 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestCase7 failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestEdgeCases_MinimumPoints(t *testing.T) { + // Arrange - 最少點數情況 (題目限制 n >= 2) + points := [][]int{ + {0, 1}, + {1, 0}, + } + expected := 1 // (0,1) 在 (1,0) 的左上方 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestEdgeCases_MinimumPoints failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestEdgeCases_MaxCoordinateValues(t *testing.T) { + // Arrange - 最大座標值情況 (題目限制 0 <= coordinates <= 50) + points := [][]int{ + {0, 50}, // A + {50, 0}, // B + {25, 25}, // C + } + expected := 2 // (A,C) 和 (C,B) 有效 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestEdgeCases_MaxCoordinateValues failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestEdgeCases_EmptyArray(t *testing.T) { + // Arrange - 空陣列情況 + points := [][]int{} + expected := 0 + + // Act + result := numberOfPairs(points) + + // Assert + if result != expected { + t.Errorf("TestEdgeCases_EmptyArray failed. Expected: %v, Got: %v", expected, result) + } +} + +func TestEdgeCases_MaxPoints_RandomPattern(t *testing.T) { + // Arrange - 50個不同的點,隨機模式 + points := make([][]int, 0, 50) + usedPoints := make(map[string]bool) + + // 使用固定種子確保測試可重現 + rand.Seed(42) + + for len(points) < 50 { + x := rand.Intn(51) // 0-50 + y := rand.Intn(51) // 0-50 + pointKey := fmt.Sprintf("%d,%d", x, y) + + if !usedPoints[pointKey] { + usedPoints[pointKey] = true + points = append(points, []int{x, y}) + } + } + + // Act + result := numberOfPairs(points) + + // Assert + if result < 0 { + t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Result should be non-negative, got: %v", result) + } + if result > 50*49 { + t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Result should not exceed 50*49, got: %v", result) + } + + // 額外驗證:確保所有點都是不同的 + distinctPoints := make(map[string]bool) + for _, point := range points { + key := fmt.Sprintf("%d,%d", point[0], point[1]) + distinctPoints[key] = true + } + if len(distinctPoints) != 50 { + t.Errorf("TestEdgeCases_MaxPoints_RandomPattern failed. Expected 50 distinct points, got: %v", len(distinctPoints)) + } +} diff --git a/problems/3025-find-the-number-of-ways-to-place-people-i/test/run_tests.sh b/problems/3025-find-the-number-of-ways-to-place-people-i/test/run_tests.sh new file mode 100755 index 0000000..59227c5 --- /dev/null +++ b/problems/3025-find-the-number-of-ways-to-place-people-i/test/run_tests.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +echo "🧪 執行 LeetCode 題目測試" +echo "==========================" + +# 執行 C# 測試 +echo "📋 C# 測試結果:" +cd ../csharp +if dotnet build > /dev/null 2>&1; then + cd ../test + if dotnet test --logger "console;verbosity=minimal" 2>/dev/null; then + echo "✅ C# 測試通過" + else + echo "❌ C# 測試失敗" + fi +else + echo "❌ C# 編譯失敗" +fi + +echo "" + +# 執行 Go 測試 +echo "📋 Go 測試結果:" +cd ../go +if go build > /dev/null 2>&1; then + # cd ../test + if go test -v > /dev/null 2>&1; then + echo "✅ Go 測試通過" + else + echo "❌ Go 測試失敗" + echo "詳細輸出:" + go test -v + fi +else + echo "❌ Go 編譯失敗" +fi + +echo "" +echo "📊 測試完成!" -- 2.49.1 From 8a49217c3d7083991c713157d1299ee6c010bb6e Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 2 Sep 2025 14:08:30 +0800 Subject: [PATCH 7/7] [#3025] note(numbersOfPairs): add monthly note --- logs/2025-09.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/logs/2025-09.md b/logs/2025-09.md index 66a5363..4f24173 100644 --- a/logs/2025-09.md +++ b/logs/2025-09.md @@ -7,6 +7,7 @@ |------|------|------|------|------|------|------| | 09/01 | Maximum Average Pass Ratio | Medium | C# | 1hr | Done | 第一次用到Priority Queue | | 09/02| Find The Number of Ways to Place People I | Medium | C# | 0.5hr | Done | 二維點位判斷 | +| 09/02| Find The Number of Ways to Place People I | Medium | go | 0.2hr | Done | go Prictice | ### Week 2 | 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 | @@ -28,11 +29,11 @@ ### 完成情況 - **總練習天數**: 2 天 - **完成題數**: 2題 -- **語言分布**: C# 2(題), Go 0(題) +- **語言分布**: C# 2(題), Go 1(題) - **難度分布**: Easy 0(題), Medium 2(題), Hard 0(題) ### 時間投入 -- **總時間**: 1.5小時 +- **總時間**: 1.7小時 - **平均每題**: 分鐘 - **每日平均**: 分鐘 -- 2.49.1