From c3afdd339d24591c292b97b1edb63771788677cd Mon Sep 17 00:00:00 2001 From: mzuenni Date: Sat, 18 Oct 2025 15:17:07 +0200 Subject: [PATCH 1/3] local-time-multiplier --- bin/config.py | 1 + bin/latex.py | 2 +- bin/problem.py | 51 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/bin/config.py b/bin/config.py index 8c1b5438..d4943ccb 100644 --- a/bin/config.py +++ b/bin/config.py @@ -111,6 +111,7 @@ "verbose": 0, "action": None, "no_visualizer": True, + "local_time_multiplier": 2, } diff --git a/bin/latex.py b/bin/latex.py index 6fd11442..ac81f542 100644 --- a/bin/latex.py +++ b/bin/latex.py @@ -187,7 +187,7 @@ def prepare_problem(problem: "Problem", language: str): def get_tl(problem: "Problem"): - tl = problem.limits.time_limit + tl = problem.limits.raw_time_limit tl = int(tl) if abs(tl - int(tl)) < 0.0001 else tl if "print_time_limit" in contest_yaml(): diff --git a/bin/problem.py b/bin/problem.py index 2ad80bc2..911915a0 100644 --- a/bin/problem.py +++ b/bin/problem.py @@ -162,7 +162,9 @@ def __init__( check_unknown_keys(time_multipliers, "limits.time_multipliers") self.time_limit_is_default: bool = "time_limit" not in yaml_data - self.time_limit: float = parse_setting(yaml_data, "time_limit", 1.0, "> 0") # in seconds + self.raw_time_limit: float = parse_setting( + yaml_data, "time_limit", 1.0, "> 0" + ) # in seconds self.time_resolution: float = parse_setting(yaml_data, "time_resolution", 1.0, "> 0") self.memory: int = parse_setting(yaml_data, "memory", 2048, "> 0") # in MiB self.output: int = parse_setting(yaml_data, "output", 8, "> 0") # in MiB @@ -209,7 +211,10 @@ def __init__( check_unknown_keys(yaml_data, "limits") # Override limmits by command line arguments. - self.time_limit = config.args.time_limit or self.time_limit + self.raw_time_limit = config.args.time_limit or self.raw_time_limit + self.time_limit: float = self.raw_time_limit + if config.args.local_time_multiplier is not None: + self.time_limit *= config.args.local_time_multiplier self.timeout: int = int(config.args.timeout or self.time_limit_to_tle * self.time_limit + 1) if config.args.timeout: self.validation_time = self.generator_time = self.visualizer_time = config.args.timeout @@ -1529,30 +1534,28 @@ def get_slowest(result): error("No AC submissions found") return False - problem.limits.time_limit = problem.limits.time_resolution * math.ceil( - duration * problem.limits.ac_to_time_limit / problem.limits.time_resolution + raw_time_limit = duration * problem.limits.ac_to_time_limit + if config.args.local_time_multiplier is not None: + raw_time_limit /= config.args.local_time_multiplier + problem.limits.raw_time_limit = problem.limits.time_resolution * math.ceil( + raw_time_limit / problem.limits.time_resolution ) + problem.limits.time_limit = problem.limits.raw_time_limit + if config.args.local_time_multiplier is not None: + problem.limits.time_limit *= config.args.local_time_multiplier safety_time_limit = problem.limits.time_limit * problem.limits.time_limit_to_tle problem.limits.timeout = int(safety_time_limit * problem.limits.time_limit_to_tle + 1) - if config.args.write: - if not has_ryaml: - warn("ruamel.yaml library not found. Please update the time limit fields manually.") - else: - yaml_path = problem.path / "problem.yaml" - problem_yaml = read_yaml(yaml_path) - if problem_yaml is None: - problem_yaml = ruamel.yaml.comments.CommentedMap() - limits = ryaml_get_or_add(problem_yaml, "limits") - limits["time_limit"] = problem.limits.time_limit - write_yaml(problem_yaml, problem.path / "problem.yaml") - - print() + print(file=sys.stderr) message(f"{duration:.3f}s @ {testcase} ({submission})", "slowest AC") message( f"{problem.limits.time_limit}s >= {duration:.3f}s * {problem.limits.ac_to_time_limit}", "time limit", ) + if config.args.local_time_multiplier is not None: + warn( + f"local_time_multiplier = {config.args.local_time_multiplier:.1f} => time_limit should be set as {problem.limits.raw_time_limit}s" + ) message( f"{safety_time_limit}s >= {problem.limits.time_limit}s * {problem.limits.time_limit_to_tle}", "safety limit", @@ -1561,7 +1564,19 @@ def get_slowest(result): f"{problem.limits.timeout}s >= {problem.limits.time_limit}s * {problem.limits.time_limit_to_tle}²", "timeout", ) - print() + print(file=sys.stderr) + + if config.args.write: + if not has_ryaml: + warn("ruamel.yaml library not found. Please update the time limit fields manually.") + else: + yaml_path = problem.path / "problem.yaml" + problem_yaml = read_yaml(yaml_path) + if problem_yaml is None: + problem_yaml = ruamel.yaml.comments.CommentedMap() + limits = ryaml_get_or_add(problem_yaml, "limits") + limits["time_limit"] = problem.limits.raw_time_limit + write_yaml(problem_yaml, problem.path / "problem.yaml") submission, testcase, duration = run_all( lambda vs: vs == [verdicts.Verdict.TIME_LIMIT_EXCEEDED], min From f959d537061dd5122fe80807ccda3b77ad4e91e3 Mon Sep 17 00:00:00 2001 From: mzuenni Date: Sat, 18 Oct 2025 15:27:07 +0200 Subject: [PATCH 2/3] remove default local_time_multiplier set for tests --- bin/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/config.py b/bin/config.py index d4943ccb..03c85cf6 100644 --- a/bin/config.py +++ b/bin/config.py @@ -111,7 +111,7 @@ "verbose": 0, "action": None, "no_visualizer": True, - "local_time_multiplier": 2, + "local_time_multiplier": None, } From b9158e430d1351fcbd030e4138b04d7a14e1236d Mon Sep 17 00:00:00 2001 From: mzuenni Date: Mon, 20 Oct 2025 19:06:46 +0200 Subject: [PATCH 3/3] adjust code --- bin/latex.py | 4 ++-- bin/problem.py | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/latex.py b/bin/latex.py index ac81f542..8c89716c 100644 --- a/bin/latex.py +++ b/bin/latex.py @@ -186,7 +186,7 @@ def prepare_problem(problem: "Problem", language: str): create_constants_file(problem, language) -def get_tl(problem: "Problem"): +def get_raw_tl(problem: "Problem"): tl = problem.limits.raw_time_limit tl = int(tl) if abs(tl - int(tl)) < 0.0001 else tl @@ -221,7 +221,7 @@ def problem_data(problem: "Problem", language: str): "problembackground": background, "problemforeground": foreground, "problemborder": border, - "timelimit": get_tl(problem), + "timelimit": get_raw_tl(problem), "problemdir": problem.path.absolute().as_posix(), "problemdirname": problem.name, "builddir": latex_builddir(problem, language).as_posix(), diff --git a/bin/problem.py b/bin/problem.py index 911915a0..89a1c2be 100644 --- a/bin/problem.py +++ b/bin/problem.py @@ -210,11 +210,15 @@ def __init__( check_unknown_keys(yaml_data, "limits") - # Override limmits by command line arguments. - self.raw_time_limit = config.args.time_limit or self.raw_time_limit + # adjust actual time_limit based on local_time_multiplier self.time_limit: float = self.raw_time_limit if config.args.local_time_multiplier is not None: self.time_limit *= config.args.local_time_multiplier + + # Override limmits by command line arguments. + if config.args.time_limit: + self.time_limit = config.args.time_limit + self.raw_time_limit = config.args.time_limit self.timeout: int = int(config.args.timeout or self.time_limit_to_tle * self.time_limit + 1) if config.args.timeout: self.validation_time = self.generator_time = self.visualizer_time = config.args.timeout