feat(template): add readme templates and leetcode helper

This commit is contained in:
2025-09-01 09:48:11 +08:00
parent 11e62e4eac
commit ed0d2f344d
4 changed files with 756 additions and 4 deletions

586
leetcode_helper.sh Executable file
View File

@@ -0,0 +1,586 @@
# 1. 讓腳本可執行:
# chmod +x leetcode_helper.sh
# 2. 建立新題目:
# ./leetcode_helper.sh problem 1 two-sum Easy
# ./leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
# 3. 建立月度日誌:
# ./leetcode_helper.sh log 2025-09
# 4. 更新README
# ./leetcode_helper.sh readme
#!/bin/bash
# 建立測試檔案
function create_test_files() {
local problem_dir="$1"
local number="$2"
local name="$3"
# 建立 C# 單元測試 (xUnit)
cat > "$problem_dir/test/SolutionTests.cs" << EOF
// LeetCode $number 單元測試
// 使用 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);
}
}
EOF
# 建立 C# 測試專案檔
cat > "$problem_dir/test/TestProject.csproj" << EOF
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../csharp/Problem$number.csproj" />
</ItemGroup>
</Project>
EOF
# 建立 Go 測試檔案
cat > "$problem_dir/test/main_test.go" << EOF
// LeetCode $number Go 單元測試
package main
import (
"testing"
"reflect"
)
func TestCase1(t *testing.T) {
// TODO: 設定測試資料
// input :=
// expected :=
// result := solve(input)
// if !reflect.DeepEqual(result, expected) {
// t.Errorf("TestCase1 failed. Expected: %v, Got: %v", expected, result)
// }
// 暫時通過測試
if false {
t.Errorf("請實作測試案例")
}
}
func TestCase2(t *testing.T) {
// TODO: 第二個測試案例
if false {
t.Errorf("請實作測試案例")
}
}
func TestEdgeCases(t *testing.T) {
// TODO: 邊界情況測試
if false {
t.Errorf("請實作邊界測試")
}
}
// 輔助函數:比較 slice
func equalSlices(a, b []int) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
EOF
# 建立測試資料檔案模板
cat > "$problem_dir/test/input1.txt" << EOF
# 測試案例 1 輸入
# TODO: 從 LeetCode 複製範例輸入
EOF
cat > "$problem_dir/test/output1.txt" << EOF
# 測試案例 1 期望輸出
# TODO: 從 LeetCode 複製範例輸出
EOF
cat > "$problem_dir/test/input2.txt" << EOF
# 測試案例 2 輸入
# TODO: 加入額外測試案例
EOF
cat > "$problem_dir/test/output2.txt" << EOF
# 測試案例 2 期望輸出
# TODO: 加入額外測試案例期望結果
EOF
cat > "$problem_dir/test/edge_cases.md" << EOF
# 邊界情況清單
## 需要測試的邊界情況
- [ ] 空輸入 (空陣列、空字串等)
- [ ] 單一元素
- [ ] 重複元素
- [ ] 最大值/最小值
- [ ] 負數情況
- [ ] 超大資料量
- [ ] 特殊字符 (如果是字串題目)
## 額外測試案例
### 案例 1:
**輸入**:
**輸出**:
**說明**:
### 案例 2:
**輸入**:
**輸出**:
**說明**:
EOF
# 建立測試執行腳本
cat > "$problem_dir/test/run_tests.sh" << 'EOF'
#!/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 "📊 測試完成!"
EOF
chmod +x "$problem_dir/test/run_tests.sh"
}
# create_problem.sh - 建立新題目資料夾和檔案
function create_problem() {
local number="$1"
local name="$2"
local difficulty="$3"
if [[ -z "$number" || -z "$name" || -z "$difficulty" ]]; then
echo "使用方法: create_problem <題號> <題目名稱> <難度>"
echo "範例: create_problem 1 two-sum Easy"
exit 1
fi
# 格式化題號 (補零到4位數)
local formatted_number=$(printf "%04d" "$number")
local folder_name="${formatted_number}-${name}"
local problem_dir="problems/${folder_name}"
# 建立資料夾結構
mkdir -p "$problem_dir"
mkdir -p "$problem_dir/test"
# 建立 README.md
cat > "$problem_dir/README.md" << EOF
# [$number] $(echo "$name" | tr '-' ' ' | sed 's/\b\w/\u&/g')
## 題目資訊
- **難度**: $difficulty
- **標籤**:
- **題目連結**: [LeetCode](https://leetcode.com/problems/$name/)
- **練習日期**: $(date +%Y-%m-%d)
## 題目描述
>
## 解題思路
### 初步分析
- 這題主要考察什麼概念?
- 有什麼關鍵限制條件?
- 預期時間/空間複雜度?
### 解法概述
1. **暴力解法**:
- 思路:
- 時間複雜度O(?)
- 空間複雜度O(?)
2. **優化解法**:
- 思路:
- 時間複雜度O(?)
- 空間複雜度O(?)
## 實作細節
### C# 解法
\`\`\`csharp
// 核心程式碼片段或關鍵邏輯說明
\`\`\`
### Go 解法
\`\`\`go
// 核心程式碼片段或關鍵邏輯說明
\`\`\`
## 測試案例
### 範例輸入輸出
\`\`\`
Input:
Output:
Explanation:
\`\`\`
### 邊界情況
- [ ] 空陣列/空字串
- [ ] 單一元素
- [ ] 最大/最小值
- [ ] 重複元素
## 學習筆記
### 今天學到什麼?
-
### 遇到的困難
-
### 改善方向
-
### 相關題目
- [題目編號] 題目名稱 - 相似概念
- [題目編號] 題目名稱 - 進階版本
---
**總結**: 這題的核心概念是...,適合練習...技巧。
EOF
# 建立 C# 專案
mkdir -p "$problem_dir/csharp"
cd "$problem_dir/csharp"
dotnet new console -n "Problem$number" --force > /dev/null 2>&1
# 建立 C# 解法檔案
cat > "Program.cs" << EOF
// LeetCode $number: $(echo "$name" | tr '-' ' ' | sed 's/\b\w/\u&/g')
// 難度: $difficulty
// 日期: $(date +%Y-%m-%d)
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
public void Solve() {
// TODO: 實作解法
Console.WriteLine("Hello LeetCode $number!");
}
}
// 測試程式
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: ");
}
*/
}
EOF
cd - > /dev/null
# 建立 Go 解法檔案
mkdir -p "$problem_dir/go"
cat > "$problem_dir/go/main.go" << EOF
// LeetCode $number: $(echo "$name" | tr '-' ' ' | sed 's/\b\w/\u&/g')
// 難度: $difficulty
// 日期: $(date +%Y-%m-%d)
package main
import "fmt"
// TODO: 實作解法
func solve() {
fmt.Printf("Hello LeetCode %d!\n", $number)
}
// 測試程式
func main() {
solve()
// TODO: 加入測試案例
// testCase1()
// testCase2()
}
// 測試案例模板
/*
func testCase1() {
// Input:
// Expected:
// Actual:
fmt.Println("Test 1:")
}
*/
EOF
# 初始化 Go module
cd "$problem_dir/go"
go mod init "leetcode-$number" > /dev/null 2>&1
cd - > /dev/null
# 建立測試檔案
create_test_files "$problem_dir" "$number" "$name"
echo "✅ 已建立題目資料夾: $problem_dir"
echo "📁 檔案結構:"
echo "$problem_dir/"
echo "├── README.md"
echo "├── csharp/"
echo "│ ├── Program.cs"
echo "│ └── Problem$number.csproj"
echo "├── go/"
echo "│ ├── main.go"
echo "│ └── go.mod"
echo "└── test/"
echo " ├── SolutionTests.cs"
echo " ├── TestProject.csproj"
echo " ├── main_test.go"
echo " ├── input1.txt"
echo " ├── output1.txt"
echo " ├── input2.txt"
echo " ├── output2.txt"
echo " ├── edge_cases.md"
echo " └── run_tests.sh"
echo ""
echo "🚀 執行方式:"
echo "C#: cd $problem_dir/csharp && dotnet run"
echo "Go: cd $problem_dir/go && go run main.go"
echo "測試: cd $problem_dir/test && ./run_tests.sh"
}
# update_readme.sh - 更新主 README
function update_readme() {
echo "🔄 更新主 README.md..."
# 計算統計資料
local total_problems=$(find problems -maxdepth 1 -type d | wc -l)
total_problems=$((total_problems - 1)) # 排除 problems 資料夾本身
local completed_problems=$(find problems -name "README.md" -exec grep -l "✅" {} \; | wc -l)
echo "📊 發現 $total_problems 個題目,其中 $completed_problems 個已完成"
# 這裡可以加入更複雜的統計和README更新邏輯
# 暫時只顯示統計結果
}
# create_monthly_log.sh - 建立月度日誌
function create_monthly_log() {
local year_month="$1"
if [[ -z "$year_month" ]]; then
year_month=$(date +%Y-%m)
fi
local log_file="logs/${year_month}.md"
if [[ -f "$log_file" ]]; then
echo "⚠️ 月度日誌已存在: $log_file"
return 1
fi
mkdir -p logs
cat > "$log_file" << EOF
# ${year_month} 學習記錄
## 📅 每日練習記錄
### Week 1
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 2
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 3
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
### Week 4
| 日期 | 題目 | 難度 | 語言 | 耗時 | 狀態 | 心得 |
|------|------|------|------|------|------|------|
| | | | | | | |
## 📈 本月統計
### 完成情況
- **總練習天數**: 天
- **完成題數**: 題
- **語言分布**: C# (題), Go (題)
- **難度分布**: Easy (題), Medium (題), Hard (題)
### 時間投入
- **總時間**: 小時
- **平均每題**: 分鐘
- **每日平均**: 分鐘
## 🎯 本月重點學習
### 新掌握的技巧
1.
### 常犯錯誤分析
1.
### 語言學習心得
- **C#**:
- **Go**:
## 🔄 遇到的困難與解決
### 困難1:
- **問題**:
- **解決**:
- **學習**:
## 📝 改進計畫
### 下月目標
1.
### 學習方法調整
1.
## 💡 本月金句
>
---
**總結**:
EOF
echo "✅ 已建立月度日誌: $log_file"
}
# 主程式
case "$1" in
"problem")
create_problem "$2" "$3" "$4"
;;
"readme")
update_readme
;;
"log")
create_monthly_log "$2"
;;
*)
echo "LeetCode Practice Helper"
echo ""
echo "使用方法:"
echo " $0 problem <題號> <題目名稱> <難度> # 建立新題目"
echo " $0 readme # 更新主README"
echo " $0 log [年月] # 建立月度日誌"
echo ""
echo "範例:"
echo " $0 problem 1 two-sum Easy"
echo " $0 problem 15 3sum Medium"
echo " $0 log 2025-09"
;;
esac