Files
coding-practice/leetcode_helper.sh

586 lines
13 KiB
Bash
Executable File
Raw 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.

# 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 --force > /dev/null 2>&1
# 覆寫自動生成的 Program.cs
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 "│ └── *.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