Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Problems are stored in a `problems` folder. This can be changed in the `settings

Within each difficulty folder, there are the individual problems. Each of these folders will contain a `problem.md` which is the problem statement. There will be a `tests` folder for test cases and a `solutions` folder for reference solutions.

If a problem folder contains a `checker.py` next to `problem.md`, `aucpl problem test` will use it as a custom checker. The file must define `check(process_output, judge_output)` and return a boolean.
If a problem folder contains a `checker.py` next to `problem.md`, `aucpl problem test` will use it as a custom checker. The file must define `check(process_output, judge_output, **kwargs)` and return a boolean. The `judge_input` value is provided in `kwargs`.

Lastly, there is a `problem-mappings.json` file that maps the problem names to its stored location. This is so that in the CLI, you do not have to specify things like the rating or whether it's a new or archived problem. You can also use `aucpl sync` to generate or update the mappings.

Expand Down
16 changes: 12 additions & 4 deletions crates/cli/src/problem/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ checker_path = sys.argv[1]
process_output = sys.argv[2]
judge_output = sys.argv[3]

judge_input = sys.stdin.read()
Comment thread
rayokamoto marked this conversation as resolved.

spec = importlib.util.spec_from_file_location("aucpl_checker", checker_path)
if spec is None or spec.loader is None:
print("Could not load checker.py", file=sys.stderr)
Expand All @@ -32,7 +34,7 @@ if not hasattr(module, "check"):
print("checker.py must define a `check` function", file=sys.stderr)
sys.exit(2)

result = module.check(process_output, judge_output)
result = module.check(process_output, judge_output, judge_input=judge_input)

Comment thread
rayokamoto marked this conversation as resolved.
print("true" if bool(result) else "false")
"#;
Expand All @@ -42,6 +44,7 @@ fn run_custom_checker(
checker_path: &Path,
process_output: &str,
judge_output: &[u8],
input_file_path: &PathBuf,
) -> Result<bool> {
let judge_output = String::from_utf8_lossy(judge_output).into_owned();
let python_cmd = get_python_executable(settings);
Expand All @@ -59,9 +62,8 @@ fn run_custom_checker(
],
)
.context("Failed to prepare checker command")?;

let checker_result = checker_run
.get_result(None)
.get_result(Some(input_file_path))
.context("Failed to run checker.py")?
.output;

Expand Down Expand Up @@ -130,7 +132,13 @@ pub fn test(
output_file.read_to_end(expected)?;

let passed = if use_custom_checker {
run_custom_checker(settings, &checker_path, &out_str, expected)?
run_custom_checker(
settings,
&checker_path,
&out_str,
expected,
&input_file_path,
)?
} else {
expected == out_str.as_bytes()
};
Expand Down