feat(template): add readme templates and leetcode helper
This commit is contained in:
586
leetcode_helper.sh
Executable file
586
leetcode_helper.sh
Executable 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
|
Reference in New Issue
Block a user