Files
coding-practice/README.md

290 lines
8.9 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LeetCode 練習專案
這是一個用來紀錄與管理 LeetCode 練習的專案,整合 C# 與 Go 的題解、基本測試模板、月度學習日誌,以及一支小工具腳本,協助快速建立新題目與維持一致的結構與習慣。
## 專案架構
```
.
├── problems/ # 每題一個資料夾 (NNNN-kebab-case)
│ └── 3516-find-closest-person/
│ ├── README.md # 題目說明與解題筆記
│ ├── csharp/ # C# 解法 (dotnet)
│ ├── go/ # Go 解法 (go module)
│ └── test/ # C#/Go 測試模板與測試檔
├── utils/
│ ├── leetcode_helper.sh # 建題、更新 README、建立月誌
│ └── run_tests.sh # 全域測試執行器(選擇 C#/Go 或全部)
├── logs/ # 月度練習紀錄 (YYYY-MM.md)
├── templates/ # 檔案模板 (.tmpl)
│ ├── problem/ # 建題用模板README、C#/Go、test
│ ├── problem-template.md.tmpl # 題解寫作指引模板(參考用)
│ └── logs-template.md.tmpl # 月誌模板
├── legacy/ # 舊題或舊結構的紀錄
├── LICENSE
└── README.md
```
命名慣例問題資料夾以「4 位數題號 + 題目英文 kebab-case」命名例如 `3025-find-the-number-of-ways-to-place-people-i`
## 需求與環境
- C#: 安裝 `.NET SDK 8+`,常用指令 `dotnet build / run / test`
- Go: 安裝 `Go 1.21+`,常用指令 `go build / run / test`
- Bash: 可執行 `utils/leetcode_helper.sh``utils/run_tests.sh`
初次使用請先授權腳本:
```
chmod +x utils/leetcode_helper.sh utils/run_tests.sh
```
## 常用操作
- 新增題目自動建立資料夾、README、C#/Go 程式與測試模板)
```
./utils/leetcode_helper.sh problem <題號> <題目名稱-kebab> <難度>
# 範例
./utils/leetcode_helper.sh problem 1 two-sum Easy
./utils/leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
# 顯示說明:
./utils/leetcode_helper.sh --help
```
建立完成後的結構(示意):
```
problems/NNNN-name/
├── README.md
├── csharp/
│ ├── Program.cs
│ └── csharp.csproj
├── go/
│ ├── main.go
│ └── go.mod
└── test/
├── SolutionTests.cs # xUnit 測試
├── TestProject.csproj
├── main_test.go # Go testing
└── edge_cases.md
```
- 建立月度日誌(依模板生成 `logs/YYYY-MM.md`
```
./utils/leetcode_helper.sh log 2025-09
```
- 更新主 README目前顯示題目統計後續可擴充自動彙整
```
./utils/leetcode_helper.sh readme
```
## 執行與測試
- 執行 C# 解法:
```
cd problems/NNNN-name/csharp
dotnet run
```
- 執行 Go 解法:
```
cd problems/NNNN-name/go
go run main.go
```
- 執行該題的測試(同時跑 C# 與 Go
```
./utils/run_tests.sh NNNN-name [all|csharp|go]
# 也可只給題號:
./utils/run_tests.sh 3025
# 僅跑 C# 或 Go
./utils/run_tests.sh 3025 csharp
./utils/run_tests.sh 3025 go
# 顯示說明:
./utils/run_tests.sh --help
# 列出目前可用題目:
./utils/run_tests.sh --list
```
或分別執行:
```
cd problems/NNNN-name/test
dotnet test
go test -v
```
## utils 的用途
`utils/leetcode_helper.sh` 提供三個主要功能,將繁瑣步驟自動化、保持專案一致性;`utils/run_tests.sh` 則統一執行測試。
- problem根據輸入的題號、名稱與難度建立一個完整題目骨架
- 產生題目 `README.md`(含題目資訊、思路、測試與筆記段落)
- 建立 `csharp/``go/` 目錄及基本程式碼
- 建立 `test/` 目錄,內含 xUnit、Go 測試模板(統一用 `utils/run_tests.sh` 執行)
- 初始化 Go module`go.mod`
- readme掃描 `problems/` 題目數量,輸出簡單統計到終端(可再擴充寫回本檔)
- log`templates/logs-template.md.tmpl` 生成月誌雛形,方便每日記錄與月度回顧
`utils/run_tests.sh` 全域測試執行:
- 用法:`./utils/run_tests.sh <problem> [all|csharp|go]`
- <problem> 可為題號(如 `3025`)、資料夾名(如 `3025-find-...`)、或完整路徑(如 `problems/3025-...`
- 其他:`--help` 顯示說明、`--list` 列出可用題目
- 範例:
- `./utils/run_tests.sh 3025`(同時跑 C# 與 Go
- `./utils/run_tests.sh 3025 csharp`(只跑 C#
- `./utils/run_tests.sh --list`
小提醒:腳本內建的模板語言為繁中,可依需求修改 `templates/` 與腳本內容。
## 模板與筆記
- 題目模板:`templates/problem-template.md.tmpl`
- 月誌模板:`templates/logs-template.md.tmpl`
建議每題完成後:
- 更新該題 `README.md` 的「解題思路」「測試案例」「學習筆記」段落
-`logs/YYYY-MM.md` 紀錄當日題目、時間、心得與統計
## Templates 強化(重點)
- **Problem 模板新增**
- 先備條件與限制(輸入範圍、是否需要 in-place/排序)
- 解法比較A/B/C、正確性要點、優缺點
- 乾跑Dry Run步驟示例
- API 設計C#/Go 方法簽名)與常見陷阱清單
- 對拍/隨機測試建議;更完整的邊界清單
- **Logs 模板新增**
- 本月設定(主題/目標/挑戰)與主題覆蓋追蹤
- 連續天數Streak與錯誤類型統計
- 困難案例復盤與下月計畫欄位
## Problem 模板範例節錄3516
```
# [3516] Find Closest Person
## 題目資訊
- 難度: Easy
- 標籤: Math
- 題目連結: https://leetcode.com/problems/find-closest-person/
- 練習日期: 2025-09-04
- 目標複雜度: 時間 O(1), 空間 O(1)
## 先備條件與限制
- 輸入: x, y, z 為整數;值域小;需比較兩者距離
- 回傳: 1/2/0 表示誰先到或同時到
## 解法比較
1. 解法A直接比距離
- 思路: 計算 |x-z| 與 |y-z|,比較大小
- 正確性: 距離等速 → 距離小者先到
- 複雜度: O(1) / O(1)
2. 解法B
## 乾跑
- x=2, y=7, z=4 → |2-4|=2, |7-4|=3 → 回傳 1
## 實作細節與 API 設計
- C#
public int FindClosest(int x, int y, int z) { ... }
- Go
func findClosest(x, y, z int) int { ... }
## 測試案例
- 邊界: 等距回傳0、同點、極小/極大值
```
完整寫法可參考:`problems/3516-find-closest-person/README.md`
## 測試範例(可直接複製改題名)
- xUnitC#
```csharp
using Xunit;
public class SolutionTests {
[Theory]
[InlineData(2, 7, 4, 1)]
[InlineData(2, 5, 6, 2)]
[InlineData(1, 5, 3, 0)]
public void FindClosest_Works(int x, int y, int z, int expected) {
var s = new Solution();
Assert.Equal(expected, s.FindClosest(x, y, z));
}
}
```
- Go testing
```go
package main
import "testing"
func TestFindClosest(t *testing.T) {
tests := []struct{ x, y, z, want int }{
{2, 7, 4, 1},
{2, 5, 6, 2},
{1, 5, 3, 0},
}
for _, tt := range tests {
if got := findClosest(tt.x, tt.y, tt.z); got != tt.want {
t.Fatalf("x=%d y=%d z=%d want=%d got=%d", tt.x, tt.y, tt.z, tt.want, got)
}
}
}
```
## 自訂模板
- 直接編輯:`templates/problem-template.md.tmpl``templates/logs-template.md.tmpl`
- 工具腳本已改為讀取 `templates/` 目錄的檔案生成骨架:
- 問題頁:`templates/problem/README.md.tmpl`
- C#`templates/problem/csharp/*`
- Go`templates/problem/go/*`
- 測試:`templates/problem/test/*`
- 月誌:`templates/logs-template.md.tmpl`
不需修改腳本本身即可客製化模板。
## 工具清單
- `utils/leetcode_helper.sh`: 管理題目與月誌
- 功能:
- `problem <題號> <題目名稱-kebab> <難度>`:建立新題目(產生 `README.md``csharp/``go/``test/` 骨架)
- `log [YYYY-MM]`:建立月度學習日誌(預設本月)
- `readme`:顯示題目數量統計
- `-h|--help`:顯示說明
- 範例:
- `./utils/leetcode_helper.sh problem 3025 find-the-number-of-ways-to-place-people-i Medium`
- `./utils/leetcode_helper.sh log 2025-09`
- `./utils/leetcode_helper.sh --help`
- `utils/run_tests.sh`: 執行指定題目的測試
- 語法:`./utils/run_tests.sh <problem> [all|csharp|go]`
- <problem> 可為:題號(如 `3025`/ 目錄名(如 `3025-find-…`/ 完整路徑(如 `problems/3025-…`
- 參數:`--help` 顯示說明、`--list` 列出現有題目
- 範例:
- `./utils/run_tests.sh 3025`(同時跑 C# 與 Go
- `./utils/run_tests.sh 3025 csharp`(只跑 C#
- `./utils/run_tests.sh --list`
## 未來可擴充方向
- 主 README 自動彙整各題狀態(難度、語言、連結、完成度)
- 加入 CI如 GitHub Actions自動跑各題測試
- 更完整的模板與範例(含 I/O、邊界測資
---
歡迎依個人習慣調整腳本與模板,持續穩定地練習最重要!