#!/usr/bin/env python3
import sys, os

precision = 1e-6

RC_CORRECT = 42
RC_WRONG_ANSWER = 43
RC_JUDGE_ERROR = 44

def point_in_poly(x, y, poly):
    inside = False

    size = len(poly)
    for i in range(size):
        a, b = poly[i], poly[(i - 1) % size]

        if (a[1] > y) != (b[1] > y) and x < (b[0] - a[0]) * (y - a[1]) / (b[1] - a[1]) + a[0]:
            inside = not inside

    return inside


def polygon_distance(x, y, poly):
    minimum = float('inf')
    size = len(poly)

    for i in range(size):
        a, b = poly[i], poly[(i-1)%size]

        minimum = min(minimum, segment_distance(x, y, a, b))

    return max(0, minimum) ** .5


def segment_distance(px, py, a, b):
    x, y = a
    dx = b[0] - x
    dy = b[1] - y

    if dx != 0 or dy != 0:
        t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy)

        if t > 1: x, y = b
        elif t > 0:
            x += dx*t
            y += dy*t

    dx = px-x
    dy = py-y

    return dx*dx + dy*dy

def equal_abs_or_rel(a, b, p):
    diff = abs(a - b)
    basis = max(1, abs(a), abs(b))
    return diff <= basis * p

# take everything in
try:
    in_file: str = sys.argv[1] # x.in
    ans_file: str = sys.argv[2] # x.ans
    feedback_dir: str = sys.argv[3] if len(sys.argv) >= 4 else None
except IndexError as e:
    # we've done something wrong - crash
    raise e

def judgemessage():
    if feedback_dir is not None:
        return open(feedback_dir + "/judgemessage.txt", "w+")
    else:
        return sys.stdout

try:
    output: str = str(sys.stdin.read(10000)) # team output
    if len(output) > 1000:
      print('Team output is too long')
      sys.exit(RC_WRONG_ANSWER)
except UnicodeDecodeError as e:
    print(e)
    sys.exit(RC_WRONG_ANSWER) # Rejected; candidates have done something wrong?

try:
    in_data: str
    with open(in_file) as f:
        in_data = f.read()

    ans_data: str
    with open(ans_file) as f:
        ans_data = f.read()
except e:
    print(e)
    sys.exit(1) # Rejected; we've done something wrong

# check solutions
try:
    # a[0] = time; a[1] = x, a[2] = y
    correct = sum([line.split(" ") for line in ans_data.rstrip().split("\n")], [])  # sum(list, []) flattens [][] into []
    result = sum([line.split(" ") for line in output.rstrip().split("\n")], [])

    # if 'time' output is worse (smaller) than solution,
    # don't even bother checking the rest
    expected_time = float(correct[0])
    candidate_time = float(result[0])

    # candidate time is <= 0 or less than judge -> wrong
    if (candidate_time <= 0 or
            (not equal_abs_or_rel(candidate_time, expected_time, precision) and
                    candidate_time < expected_time)):
        with judgemessage() as f:
            f.write(f"Team answer t={candidate_time} is worse than {expected_time}\n")
        sys.exit(RC_WRONG_ANSWER)

    # result is better than or equal to judge answer
    # check solution to see if it's actually better than judge solution, or just wrong

    split_input = in_data.rstrip().split("\n")
    raw_poly = split_input[1:]
    poly = [list(map(int, vert.split(" "))) for vert in raw_poly]

    v = int(split_input[0].split(" ")[0])
    candidate_r, candidate_x, candidate_y = map(float, result[:3])
    judge_r, judge_x, judge_y = map(float, correct[:3])

    # check if point is inside poly:
    if not point_in_poly(candidate_x, candidate_y, poly):
        with judgemessage() as f:
          f.write(f"Team output is not inside polygon: {candidate_x} {candidate_y}\n")
        sys.exit(RC_WRONG_ANSWER)  # invalid if coords are outside polygon

    distance = polygon_distance(candidate_x, candidate_y, poly) / v

    good_distance = equal_abs_or_rel(distance, judge_r, precision)
    good_time = equal_abs_or_rel(expected_time, candidate_time, precision)

    if good_distance and good_time:
        # candidate is within allowed error of the judge, pass it
        sys.exit(RC_CORRECT)
    else:
        # something doesn't check out
        team_did_better = False
        with judgemessage() as f:
            if good_distance and not good_time:
                f.write(f"team's point has correct distance={distance}, but the stated time didn't match.\n")
                sys.exit(RC_WRONG_ANSWER)
            elif good_time and not good_distance:
                f.write(f"team's time is correct, but the given point has distance={distance} expected={judge_r}\n")
            else:
                f.write(f"team's time and distance don't match ours. Team point distance={distance} expected={judge_r}\n")

            if distance > judge_r:
              f.write("team improved upon our answer!\n")
              team_did_better = True

        if team_did_better:
            # throw JE; we've gone wrong somewhere oops
            sys.exit(RC_JUDGE_ERROR)
        else:
            # phew, we're not wrong, they're wrong
            sys.exit(RC_WRONG_ANSWER)

except Exception as e:
    # Rejected
    sys.exit(RC_WRONG_ANSWER)
