Loading...
Loading...
Use when asked to generate Judge v2 problems (Exercode/Judgeの問題), or when coding is part of an Exercode course's learning objective and needs graded practice. Not for use outside Exercode/Judge.
npx skill4agent add willbooster/exercode-problem-utils generate-judge-problemsproblem.mdproblem.md<id>.problem.md<courseId>/problems/<problemId>/mise.toml.mise.toml.tool-versions.tool-versionsmise trust --yesmise installmodel_answers/<languageId>/python/main.pyproblem.mdjudge.tsdebug.tsjudge.tsdebug.tsdebug.tstest_cases/example_*<id>.fin/<id>.fout/.out.fout/cd <problemDir> && for f in test_cases/*.in; do python3 model_answers/python/main.py < "$f" > "${f%.in}.out"; done.fin/_shared.fin/.fout/.in<id>.in<id>.fout/<problemDir>/.tmp/expected.shbash -euo pipefail <problemDir>/.tmp/expected.sh [<outputFile> ...]# The produced file paths are the arguments; stdout-only problems pass none.
cd <problemDir>
root=$PWD
# A scratch directory inside the problem keeps the pinned tools; it is removed on success and kept on failure.
mkdir -p .tmp && scratch=$(mktemp -d .tmp/expected.XXXXXX)
trap 'st=$?; if [ $st -eq 0 ]; then rm -rf "$scratch"; else echo "kept $scratch for inspection" >&2; fi; exit $st' EXIT
# Every test case id (the shared name of its entries), excluding the shared input directory.
for id in $(ls -1 test_cases | sed -E -n 's/\.(in|out|fin|fout)$//p' | sort -u | grep -vx _shared); do
# Stage the case's working directory: shared inputs first, then the case's own inputs.
w=$scratch/$id && mkdir -p "$w"
if [ -d test_cases/_shared.fin ]; then cp -R test_cases/_shared.fin/. "$w"/; fi
if [ -d "test_cases/$id.fin" ]; then cp -R "test_cases/$id.fin/." "$w"/; fi
# Run the model answer with the case's stdin (if any) and capture its stdout.
in=/dev/null && if [ -f "test_cases/$id.in" ]; then in="$root/test_cases/$id.in"; fi
(cd "$w" && python3 "$root/model_answers/python/main.py" < "$in" > "$root/$scratch/$id.stdout")
if [ -d "test_cases/$id.fout" ]; then
# A file case: the produced file paths (the script arguments) are required and every file must exist
# before .fout/ is refilled, which protects committed contents; .out is refreshed only when the case has one.
[ $# -gt 0 ] || { echo "usage: expected.sh <outputFile> ... (test_cases/$id.fout/ needs the produced file paths)" >&2; exit 2; }
for f in "$@"; do test -f "$w/$f"; done
find "test_cases/$id.fout" -mindepth 1 -delete
for f in "$@"; do mkdir -p "test_cases/$id.fout/$(dirname "$f")" && cp "$w/$f" "test_cases/$id.fout/$f"; done
if [ -f "test_cases/$id.out" ]; then mv "$scratch/$id.stdout" "test_cases/$id.out"; fi
else
# A stdout case: the captured stdout is its expectation.
mv "$scratch/$id.stdout" "test_cases/$id.out"
fi
done.fout/bash -euo pipefailtest_cases/<id>.fout/.out.outtest_cases/<id>.outjudge.ts.in.fin/_shared.fin/.outrequiredOutputFilePathsmodel_answers/<problemDir>/.tmp/cross_check/exercode-problem@exercode/problem-utilscd <problemDir> && bunx exercode-problem judge model_answers/<languageId>'{ "model": "<modelId>" }'TEST_CASE_RESULT2000.outtemplates/bunx exercode-problem judge templates/<languageId>templates/_defaultbunx exercode-problem judge templates/_defaulttemplates/bunx exercode-problem judge templates'{ "language": "<languageId>" }'main file not found1201requiredRegExpsInCodeforbiddenRegExpsInCodeforbiddenTextsInCodeScannermapintsplitrangebunx exercode-problem validate-problem <problemDir>...