Files
coding-practice/utils/leetcode_helper.sh

170 lines
6.6 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 utils/leetcode_helper.sh
# 2. 建立新題目:
# ./utils/leetcode_helper.sh problem 1 two-sum Easy
# ./utils/leetcode_helper.sh problem 3000 maximum-area-rectangle Medium
# 3. 建立月度日誌:
# ./utils/leetcode_helper.sh log 2025-09
# 4. 更新README
# ./utils/leetcode_helper.sh readme
#!/bin/bash
set -euo pipefail
# 路徑設定
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
ROOT_DIR=$(cd "$SCRIPT_DIR/.." && pwd)
TEMPLATES_DIR="$ROOT_DIR/templates"
# kebab-case -> Title Casetwo-sum -> Two Sum
to_title_case() {
local s="${1//-/ }"
echo "$s" | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) substr($i,2) } print }'
}
# 渲染模板到目的檔
# 變數:{{NUMBER}}, {{NUMBER_PAD}}, {{NAME_SLUG}}, {{NAME_TITLE}}, {{DIFFICULTY}}, {{DATE}}, {{YEAR_MONTH}}
render_template() {
local src="$1"; shift
local dest="$1"; shift
local number="${1:-}"; shift || true
local number_pad="${1:-}"; shift || true
local name_slug="${1:-}"; shift || true
local name_title="${1:-}"; shift || true
local difficulty="${1:-}"; shift || true
local today="${1:-}"; shift || true
local year_month="${1:-}"; shift || true
mkdir -p "$(dirname "$dest")"
sed -e "s/{{NUMBER}}/${number}/g" \
-e "s/{{NUMBER_PAD}}/${number_pad}/g" \
-e "s/{{NAME_SLUG}}/${name_slug}/g" \
-e "s/{{NAME_TITLE}}/${name_title}/g" \
-e "s/{{DIFFICULTY}}/${difficulty}/g" \
-e "s/{{DATE}}/${today}/g" \
-e "s/{{YEAR_MONTH}}/${year_month}/g" \
"$src" > "$dest"
}
# 建立測試檔案(來自 templates/problem/test/*
create_test_files() {
local problem_dir="$1"; local number="$2"; local name_slug="$3"; local difficulty="$4"
local number_pad=$(printf "%04d" "$number")
local name_title=$(to_title_case "$name_slug")
local today=$(date +%Y-%m-%d)
local year_month=$(date +%Y-%m)
render_template "$TEMPLATES_DIR/problem/test/SolutionTests.cs.tmpl" \
"$problem_dir/test/SolutionTests.cs" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/TestProject.csproj.tmpl" \
"$problem_dir/test/TestProject.csproj" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/main_test.go.tmpl" \
"$problem_dir/test/main_test.go" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/edge_cases.md.tmpl" \
"$problem_dir/test/edge_cases.md" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/input1.txt.tmpl" "$problem_dir/test/input1.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/output1.txt.tmpl" "$problem_dir/test/output1.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/input2.txt.tmpl" "$problem_dir/test/input2.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/output2.txt.tmpl" "$problem_dir/test/output2.txt" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/test/run_tests.sh.tmpl" \
"$problem_dir/test/run_tests.sh" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
chmod +x "$problem_dir/test/run_tests.sh"
}
# 建立新題目
create_problem() {
local number="$1"; local name_slug="$2"; local difficulty="$3"
if [[ -z "${number:-}" || -z "${name_slug:-}" || -z "${difficulty:-}" ]]; then
echo "使用方法: $0 problem <題號> <題目名稱-kebab> <難度>"; exit 1
fi
local number_pad=$(printf "%04d" "$number")
local folder_name="${number_pad}-${name_slug}"
local problem_dir="$ROOT_DIR/problems/${folder_name}"
local name_title=$(to_title_case "$name_slug")
local today=$(date +%Y-%m-%d)
local year_month=$(date +%Y-%m)
mkdir -p "$problem_dir/csharp" "$problem_dir/go" "$problem_dir/test"
# README
render_template "$TEMPLATES_DIR/problem/README.md.tmpl" \
"$problem_dir/README.md" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
# C#
render_template "$TEMPLATES_DIR/problem/csharp/Program.cs.tmpl" \
"$problem_dir/csharp/Program.cs" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
render_template "$TEMPLATES_DIR/problem/csharp/csharp.csproj.tmpl" \
"$problem_dir/csharp/csharp.csproj" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
# Go
render_template "$TEMPLATES_DIR/problem/go/main.go.tmpl" \
"$problem_dir/go/main.go" \
"$number" "$number_pad" "$name_slug" "$name_title" "$difficulty" "$today" "$year_month"
(cd "$problem_dir/go" && go mod init "leetcode-$number" >/dev/null 2>&1 || true)
# Tests
create_test_files "$problem_dir" "$number" "$name_slug" "$difficulty"
echo "✅ 已建立題目: $problem_dir"
echo "C#: cd problems/${folder_name}/csharp && dotnet run"
echo "Go: cd problems/${folder_name}/go && go run main.go"
echo "測試: cd problems/${folder_name}/test && ./run_tests.sh"
}
# 更新主 README目前僅統計列印
update_readme() {
echo "🔄 更新主 README 統計..."
local total_problems=$(find "$ROOT_DIR/problems" -maxdepth 1 -type d | wc -l)
total_problems=$((total_problems - 1))
local completed_problems=$(find "$ROOT_DIR/problems" -name "README.md" -exec grep -l "✅" {} \; | wc -l)
echo "📊 題目總數: $total_problems,標記完成: $completed_problems"
}
# 建立月度日誌(由模板 logs-template.md.tmpl 渲染)
create_monthly_log() {
local year_month="${1:-}"
if [[ -z "$year_month" ]]; then year_month=$(date +%Y-%m); fi
local dest="$ROOT_DIR/logs/${year_month}.md"
if [[ -f "$dest" ]]; then echo "⚠️ 已存在: $dest"; return 1; fi
mkdir -p "$ROOT_DIR/logs"
render_template "$TEMPLATES_DIR/logs-template.md.tmpl" "$dest" "" "" "" "" "" "" "$year_month"
echo "✅ 已建立月度日誌: $dest"
}
# 入口
case "${1:-}" in
problem)
create_problem "${2:-}" "${3:-}" "${4:-}" ;;
readme)
update_readme ;;
log)
create_monthly_log "${2:-}" ;;
*)
echo "LeetCode Practice Helper"
echo "使用:"
echo " $0 problem <題號> <題目名稱-kebab> <難度>"
echo " $0 readme"
echo " $0 log [YYYY-MM]"
;;
esac