Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atcoderのサイトではacになるコードが"atcoder-tools test" で通らないです。 #285

Closed
akisatoon1 opened this issue Dec 9, 2023 · 0 comments

Comments

@akisatoon1
Copy link

例1:

https://atcoder.jp/contests/typical90/submissions/48284793

例2:

https://atcoder.jp/contests/typical90/submissions/48267031

説明:

例1では"\n"前に空白、そして出力の最後に"\n"と空白を置いています。
例2では、最後の"\n"を出力していません。
現在のatcoder-toolsのテストシステムだと完全一致のみがpassedとして扱われているようなので、"atcoder-tools test"が通りません。

修正提案:

atcoder-tools/atcodertools/common /judgetype.pyを次のように書き換えます。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod
from enum import Enum
import re


class JudgeType(Enum):
    Normal = "normal"
    Decimal = "decimal"
    Other = "other"


class ErrorType(Enum):
    Absolute = "absolute"
    Relative = "relative"
    AbsoluteOrRelative = "absolute_or_relative"


DEFAULT_EPS = 1e-9


class NoJudgeTypeException(Exception):
    pass


class Judge(metaclass=ABCMeta):
    @abstractmethod
    def verify(self, output, expected):
        pass

    @abstractmethod
    def to_dict(self):
        pass


class NormalJudge(Judge):
    def __init__(self):
        self.judge_type = JudgeType.Normal

    def verify(self, output, expected):
        
        # 文字列の最後の改行及び空白をすべて削除
        output = re.sub(r"[ \n]*$", "", output)
        expected = re.sub(r"[ \n]*$", "", expected)
        
        # 改行前の空白を全部削除
        output = re.sub(r" *\n", "\n", output)
        
        return output == expected

    def to_dict(self):
        return {
            "judge_type": self.judge_type.value,
        }

    @classmethod
    def from_dict(cls, dic):
        r = NormalJudge()
        return r


class DecimalJudge(Judge):
    def __init__(self,
                 error_type: ErrorType = ErrorType.AbsoluteOrRelative,
                 diff: float = 0.0
                 ):
        self.judge_type = JudgeType.Decimal
        self.error_type = error_type
        self.diff = diff

    def _verify_sub(self, output: float, expected: float) -> bool:
        if self.error_type in [ErrorType.Absolute, ErrorType.AbsoluteOrRelative] and abs(expected - output) <= self.diff:
            return True
        if self.error_type in [ErrorType.Relative, ErrorType.AbsoluteOrRelative] and self._calc_absolute(output, expected):
            return True
        return False

    def _calc_absolute(self, output: float, expected: float) -> bool:
        if expected == 0:
            return expected == output
        return abs((expected - output) / expected) <= self.diff

    def verify(self, output, expected) -> bool:
        output = output.strip().split()
        expected = expected.strip().split()
        if len(output) != len(expected):
            return False
        for i in range(0, len(output)):
            if not self._verify_sub(float(output[i]), float(expected[i])):
                return False
        return True

    def to_dict(self):
        return {
            "judge_type": self.judge_type.value,
            "error_type": self.error_type.value,
            "diff": self.diff
        }

    @classmethod
    def from_dict(cls, dic):
        r = DecimalJudge(
            diff=dic["diff"]
        )
        r.error_type = ErrorType(dic["error_type"])
        return r


class OtherJudge(Judge):
    # dummy
    pass

変更点

・正規表現で置換するためにreモジュールをimportしました。
・41行目付近のNormalJudge.verifyを修正しました。例2に対応するためにexpectedもいじりました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant