Problem:


Distance

For given two segments s1 and s2, print the distance between them.

s1 is formed by end points p0 and p1, and
s2 is formed by end points p2 and p3.

Input

The entire input looks like:

q (the number of queries)
1st query
2nd query
...
qth query

Each query consists of integer coordinates of end points of s1 and s2 in the following format:

xp0 yp0 xp1 yp1 xp2 yp2 xp3 yp3

Output

For each query, print the distance. The output values should be in a decimal fraction with an error less than 0.00000001.

Constraints

1 ≤ q ≤ 1000

-10000 ≤ xpi, ypi ≤ 10000

p0 &ne; p1 and
p2 &ne; p3.

Sample Input

3
0 0 1 0 0 1 1 1
0 0 1 0 2 1 1 2
-1 0 1 0 0 1 0 -1

Sample Output

1.0000000000
1.4142135624
0.0000000000



Sample input:
3
0 0 1 0 0 1 1 1
0 0 1 0 2 1 1 2
-1 0 1 0 0 1 0 -1


Sample output:
1.0000000000
1.4142135624
0.0000000000

Submission status: Wrong Answer

Solution code:
from sys import stdin
import math

EPS = 1e-10

class Vector:
    def __init__(self, x=None, y=None):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y)

    def __mul__(self, k):
        return Vector(self.x * k, self.y * k)

    def __gt__(self, other):
        return self.x > other.x and self.y > other.yb

    def __lt__(self, other):
        return self.x < other.x and self.y < other.yb

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    # usually cross operation return Vector but it returns scalor
    def cross(self, other):
        return self.x * other.y - self.y * other.x

    def norm(self):
        return self.x * self.x + self.y * self.y

    def abs(self):
        return math.sqrt(self.norm())

class Point(Vector):
    def __init__(self, *args, **kargs):
        return super().__init__(*args, **kargs)

class Segment:
    def __init__(self, p1=Point(0, 0), p2=Point(1, 1)):
        self.p1 = p1
        self.p2 = p2

def ccw(p0, p1, p2):
    a = p1 - p0
    b = p2 - p0
    if a.cross(b) > EPS:
        return 1
    elif a.cross(b) < -EPS:
        return -1
    elif a.dot(b) < -EPS:
        return 2
    elif a.norm() < b.norm():
        return -2
    else:
        return 0

def intersect(*args, **kwargs):
    # input two segments
    if len(args) == 2:
        s1, s2 = args
        return (ccw(s1.p1, s1.p2, s2.p1) * ccw(s1.p1, s1.p2, s2.p2) <= 0 and
                    ccw(s2.p1, s2.p2, s1.p1) * ccw(s2.p1, s2.p2, s1.p2) <= 0)
    # input four points
    elif len(args) == 4:
        p0, p1, p2, p3 = args
        return (ccw(p0, p1, p2) * ccw(p0, p1, p3) <= 0 and
                    ccw(p2, p3, p0) * ccw(p2, p3, p1) <= 0)
    else:
        raise ArgsError

def get_distance_lp(l, p):
    v1 = l.p1 - l.p2
    v2 = p - l.p1
    return abs(v1.cross(v2))/v1.abs()

def get_distance_sp(s, p):
    v1 = s.p2 - s.p1
    v2 = p - s.p1
    v3 = s.p1 - s.p2
    v4 = p - s.p2
    if v1.dot(v2) < 0:
        return v2.abs()
    elif v3.dot(v4):
        return v4.abs()
    else:
        return get_distance_lp(s, p)

def get_distance(*args, **kwargs):
    # input two points with the startpoint (0, 0)
    if len(args) == 2:
        p1, p2 = args
        v = p1 - p2
        return v.abs()
    # input two segments
    elif len(kwargs) == 2:
        s1 = kwargs['s1']
        s2 = kwargs['s2']
        if intersect(s1, s2):
            return 0.0
        else:
            return min(min(get_distance_sp(s1, s2.p1), get_distance_sp(s1, s2.p2)),
                        min(get_distance_sp(s2, s1.p1), get_distance_sp(s2, s1.p2)))
    else:
        raise ArgsError

def read_and_print_results(n):
    for _ in range(n):
        line = stdin.readline().strip().split()
        p0 = Vector(int(line[0]), int(line[1]))
        p1 = Vector(int(line[2]), int(line[3]))
        p2 = Vector(int(line[4]), int(line[5]))
        p3 = Vector(int(line[6]), int(line[7]))
        s1 = Segment(p0, p1)
        s2 = Segment(p2, p3)
        d = get_distance(s1=s1, s2=s2)
        print("{0:0.10f}".format(d))

n = int(input())
read_and_print_results(n)

Submission status: Wrong Answer

Solution code:
from sys import stdin
readline = stdin.readline


def main():
    q = int(readline())
    for i in range(q):
        xy = map(int, readline().split())
        p0, p1, p2, p3 = [x + y * 1j for x, y in zip(*[xy] * 2)]
        print('{:.10f}'.format(distance(p0, p1, p2, p3)))

def lt(a, b):
    if a.real != b.real:
        return a.real < b.real
    return a.imag < b.imag
import itertools
def distance(p0, p1, p2, p3):
    if is_intersected_ls(p0, p1, p2, p3):
        return 0
    p = []
    for i, j in itertools.product([p0, p1], [p2, p3]):
        p.append(abs(i - j))
    for i,j,k in [(p0,p1,p2),(p0,p1,p3),(p2,p3,p0),(p2,p3,p1)]:
        tmp = intersection_of_perpendicular(i,j,k)
        if (lt(i, k) and lt(k, j)) or (lt(j, k) and lt(k, i)):
            p.append(abs(tmp - k))

    return min(p)

# line(p1, p2) point(p3)
def intersection_of_perpendicular(p1, p2, p3):
    return p1 + (p2 - p1) * projecter(p2 - p1, p3 - p1)
 
 
def projecter(a, b):
    return dot(a, b) / dot(a, a)
 
 
def dot(a, b):
    return a.real * b.real + a.imag * b.imag


def is_intersected_ls(a1, a2, b1, b2):
    eps = 0
    if max(a1.real, a2.real) < min(b1.real, b2.real)\
      or max(b1.real, b2.real) < min(a1.real, a2.real)\
      or max(a1.imag, a2.imag) < min(b1.imag, b2.imag)\
      or max(b1.imag, b2.imag) < min(a1.imag, a2.imag):
        return False
    return (cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) <= eps)\
        and (cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) <= eps)

# http://imagingsolution.blog107.fc2.com/blog-entry-137.html
def intersection(p1, p2, p3, p4):
    a1 = p4 - p2
    b1 = p2 - p3
    b2 = p1 - p2
    s1 = cross(a1, b2) / 2
    s2 = cross(a1, b1) / 2
    c1 = p1 + (p3 - p1) * s1 / (s1 + s2)
    return c1


def cross(a, b):
    return a.real * b.imag - a.imag * b.real
main()

Submission status: Wrong Answer

Solution code:
from math import sqrt
for t in xrange(input()):
    x0, y0, x1, y1, x2, y2, x3, y3 = map(int, raw_input().split())
    dx0 = x1 - x0
    dy0 = y1 - y0
    dx1 = x3 - x2
    dy1 = y3 - y2

    s = (y0-y2)*dx1 - (x0-x2)*dy1
    sm = dx0*dy1 - dy0*dx1
    if s < 0:
        s = -s
        sm = -sm
    t = (y2-y0)*dx0 - (x2-x0)*dy0
    tm = dx1*dy0 - dy1*dx0
    intersection = 0
    if t < 0:
        t = -t
        tm = -tm
    if 0 <= s <= max(sm, 0) and 0 <= t <= max(tm, 0):
        ov = dx0*dy1 - dy0*dx1
        if ov == 0:
            r0 = dx0**2 + dy0**2
            r1 = (x2-x0)*dx0 + (y2-y0)*dy0
            r2 = (x3-x0)*dx0 + (y3-y0)*dy0
            if r1 > r2: r1, r2 = r2, r1
            if r2 < 0 or r0 < r1:
                intersection = 0
            else:
                intersection = 1
        else:
            intersection = 1
    else:
        intersection = 0
    if intersection:
        print "%.09f" % 0
    else:
        print sqrt(min((x2-x0)**2 + (y2-y0)**2, (x3-x0)**2 + (y3-x0)**2, (x2-x1)**2 + (y2-y1)**2, (x3-x1)**2 + (y3-y1)**2))

Submission status: Wrong Answer

Solution code:
from math import sqrt
for t in xrange(input()):
    x0, y0, x1, y1, x2, y2, x3, y3 = map(int, raw_input().split())
    dx0 = x1 - x0
    dy0 = y1 - y0
    dx1 = x3 - x2
    dy1 = y3 - y2

    s = (y0-y2)*dx1 - (x0-x2)*dy1
    sm = dx0*dy1 - dy0*dx1
    if s < 0:
        s = -s
        sm = -sm
    t = (y2-y0)*dx0 - (x2-x0)*dy0
    tm = dx1*dy0 - dy1*dx0
    intersection = 0
    if t < 0:
        t = -t
        tm = -tm
    dis = sqrt(
            min(
                (x2-x0)**2 + (y2-y0)**2,
                (x3-x0)**2 + (y3-y0)**2,
                (x2-x1)**2 + (y2-y1)**2,
                (x3-x1)**2 + (y3-y1)**2
                )
            )
    ov = dx0*dy1 - dy0*dx1
    if 0 <= s <= max(sm, 0) and 0 <= t <= max(tm, 0):
        if ov == 0:
            r0 = dx0**2 + dy0**2
            r1 = (x2-x0)*dx0 + (y2-y0)*dy0
            r2 = (x3-x0)*dx0 + (y3-y0)*dy0
            if r1 > r2: r1, r2 = r2, r1
            if r2 < 0 or r0 < r1:
                intersection = 0
            else:
                intersection = 1
        else:
            intersection = 1
    else:
        if ov == 0:
            r0 = dx0**2 + dy0**2
            r1 = dx0*(x2-x0) + dy0*(y2-y0)
            r2 = dx0*(x3-x0) + dy0*(y3-y0)
            if 0 <= r2 and r1 <= r0:
                dis = min(dis, (dx0*(y2-y0) - dy0*(x2-x0)) / sqrt(r0))
        else:
            r0 = dx0**2 + dy0**2
            r1 = dx0*(x2-x0) + dy0*(y2-y0)
            r2 = dx0*(x3-x0) + dy0*(y3-y0)
            if 0 <= r1 <= r0:
                o1 = abs(dx0*(y2-y0) - dy0*(x2-x0))
                dis = min(dis, o1 / sqrt(r0))
            if 0 <= r2 <= r0:
                o2 = abs(dx0*(y3-y0) - dy0*(x3-x0))
                dis = min(dis, o2 / sqrt(r0))
            s0 = dx1**2 + dy1**2
            s1 = dx1*(x0-x2) + dy1*(y0-y2)
            s2 = dx1*(x1-x2) + dy1*(y1-y2)
            if 0 <= s1 <= s0:
                o1 = abs(dx1*(y0-y2) - dy1*(x0-x2))
                dis = min(dis, o1 / sqrt(s0))
            if 0 <= s2 <= s0:
                o2 = abs(dx1*(y1-y2) - dy1*(x1-x2))
                dis = min(dis, o2 / sqrt(s0))

        intersection = 0
    if intersection:
        print "%.09f" % 0
    else:
        print "%.09f" % dis

Submission status: Wrong Answer

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3
0 0 1 0 0 1 1 1
0 0 1 0 2 1 1 2
-1 0 1 0 0 1 0 -1

output:
1.0000000000
1.4142135624
0.0000000000
"""

import sys


class Segment(object):
    __slots__ = ('source', 'target')

    def __init__(self, source, target):
        self.source = complex(source)
        self.target = complex(target)


def cross(a, b):
    return a.real * b.imag - a.imag * b.real


def dot(a, b):
    return a.real * b.real + a.imag * b.imag


def get_distance_lp(l, p):
    return abs(cross(l.target - l.source, p - l.source) / abs(l.target - l.source))


def get_distance_sp(s, p):
    if dot(s.target - s.source, p - s.source) < 0:
        return abs(p - s.source)
    elif dot(s.source - s.target, p - s.target) < 0:
        return abs(p - s.target)
    else:
        return get_distance_lp(s, p)


def calc_distance(line_info):
    for line_pair in line_info:
        line_axis = tuple(map(int, line_pair))
        p0, p1, p2, p3 = (x + y * 1j for x, y in zip(line_axis[::2], line_axis[1::2]))
        s1, s2 = Segment(p0, p1), Segment(p2, p3)
        # TODO: check intersection of segments: s1, s2
        distance = min(min(get_distance_sp(s1, s2.source), get_distance_sp(s1, s2.target)),
                       min(get_distance_sp(s2, s1.source), get_distance_sp(s2, s1.target))
                       )
        print('{0:.10f}'.format(distance))

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    questions = int(_input[0])
    lines = map(lambda x: x.split(), _input[1:])
    calc_distance(lines)

Submission status: Wrong Answer

Solution code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3
0 0 1 0 0 1 1 1
0 0 1 0 2 1 1 2
-1 0 1 0 0 1 0 -1

output:
1.0000000000
1.4142135624
0.0000000000
"""

import sys


class Segment(object):
    __slots__ = ('source', 'target')

    def __init__(self, source, target):
        self.source = complex(source)
        self.target = complex(target)


def cross(a, b):
    return a.real * b.imag - a.imag * b.real


def dot(a, b):
    return a.real * b.real + a.imag * b.imag


def get_distance_lp(l, p):
    return abs(cross(l.target - l.source, p - l.source) / abs(l.target - l.source))


def get_distance_sp(s, p):
    if dot(s.target - s.source, p - s.source) < 0:
        return abs(p - s.source)
    elif dot(s.source - s.target, p - s.target) < 0:
        return abs(p - s.target)
    else:
        return get_distance_lp(s, p)


def calc_distance(line_info):
    for line_pair in line_info:
        line_axis = tuple(map(int, line_pair))
        p0, p1, p2, p3 = (x + y * 1j for x, y in zip(line_axis[::2], line_axis[1::2]))
        s1, s2 = Segment(p0, p1), Segment(p2, p3)
        # TODO: check intersection of segments: s1, s2
        distance = min(min(get_distance_sp(s1, s2.source), get_distance_sp(s1, s2.target)),
                       min(get_distance_sp(s2, s1.source), get_distance_sp(s2, s1.target))
                       )
        print('{ans:.10f}'.format(ans=distance))

    return None


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    questions = int(_input[0])
    lines = map(lambda x: x.split(), _input[1:])
    calc_distance(lines)

Submission status: Wrong Answer

Solution code:
import sys
class Line:
    def __init__(self,p1,p2):
        if p1[1] < p2[1]:self.s=p2;self.e=p1
        elif p1[1] > p2[1]:self.s=p1;self.e=p2
        else:
            if p1[0] < p2[0]:self.s=p1;self.e=p2
            else:self.s=p2;self.e=p1

def cross(a,b):return a[0]*b[1] - a[1]*b[0]
def dot(a,b):return a[0]*b[0]+a[1]*b[1]
def dif(a,b):return [x-y for x,y in zip(a,b)]
def dist(a,b):return ((a[0]-b[0])**2+(a[1]-b[1])**2)**0.5
def isec(l,m):
    a = dif(l.e,l.s);b = dif(m.e,l.s);c = dif(m.s,l.s)
    d = dif(m.e,m.s);e = dif(l.e,m.s);f = dif(l.s,m.s)
    g = lambda a, b : cross(a,b)==0 and dot(a,b)>0 and dot(b,b)<dot(a,a)
    if g(a,b) or g(a,c) or g(d,e) or g(d,f):return True
    elif l.s == m.e or l.s == m.s or l.e == m.e or l.e == m.s:return True
    elif cross(a,b) * cross(a,c) >= 0 or cross(d,e) * cross(d,f) >= 0:return False
    else:return True
def plus(a,b):return [x+y for x,y in zip(a,b)]
def projection(a,b):return [x*dot(a,b)/dot(a,a) for x in a]
def proj(A,B,C,D):
    AB = dif(B,A) ; AC = dif(C,A) ; AD = dif(D,A)
    CD = dif(D,C) ; CA = dif(A,C) ; CB = dif(B,C)
    _A = plus(projection(CD,CA),C) 
    _B = plus(projection(CD,CB),C)
    _C = plus(projection(AB,AC),A)
    _D = plus(projection(AB,AD),A)
    return [_A,_B,_C,_D]
def Order(a,b):
    crs = cross(a,b)
    if crs > 0 : return "COUNTER_CLOCKWISE"
    elif crs < 0 : return "CLOCKWISE"
    else:
        if dot(a,b) < 0 : return "ONLINE_BACK"
        elif dot(a,a) < dot(b,b) : return "ONLINE_FRONT"
        else : return "ON_SEGMENT"


q = int(input())
for i in range(q):
    a,b,c,d,e,f,g,h = [int(i) for i in input().split()]
    A = [a,b] ; B = [c,d] ; C = [e,f] ; D = [g,h]
    l = Line(A,B) ; m = Line(C,D)
    if isec(l,m):
        print(0.0)
        continue
    _A,_B,_C,_D = proj(A,B,C,D)
    AB = dif(B,A) ; CD = dif(D,C)
    A_C = dif(_C,A) ; A_D = dif(_D,A) ; C_A = dif(_A,C) ; C_B = dif(_B,C)
    DIST = [dist(A,C),dist(A,D),dist(B,C),dist(B,D),dist(_A,A),dist(_B,B),dist(_C,C),dist(_D,D)]
    fun = lambda x : x != "ON_SEGMENT"
    if fun(Order(CD,C_A)) : DIST[4] = sys.maxsize
    if fun(Order(CD,C_B)) : DIST[5] = sys.maxsize
    if fun(Order(AB,A_C)) : DIST[6] = sys.maxsize
    if fun(Order(AB,A_D)) : DIST[7] = sys.maxsize
    print(min(DIST))

Submission status: Wrong Answer

Solution code:
import sys
class Line:
    def __init__(self,p1,p2):
        if p1[1] < p2[1]:self.s=p2;self.e=p1
        elif p1[1] > p2[1]:self.s=p1;self.e=p2
        else:
            if p1[0] < p2[0]:self.s=p1;self.e=p2
            else:self.s=p2;self.e=p1

def cross(a,b):return a[0]*b[1] - a[1]*b[0]
def dot(a,b):return a[0]*b[0]+a[1]*b[1]
def dif(a,b):return [x-y for x,y in zip(a,b)]
def dist(a,b):return ((a[0]-b[0])**2+(a[1]-b[1])**2)**0.5
def isec(l,m):
    a = dif(l.e,l.s);b = dif(m.e,l.s);c = dif(m.s,l.s)
    d = dif(m.e,m.s);e = dif(l.e,m.s);f = dif(l.s,m.s)
    g = lambda a, b : cross(a,b)==0 and dot(a,b)>0 and dot(b,b)<dot(a,a)
    if g(a,b) or g(a,c) or g(d,e) or g(d,f):return True
    elif l.s == m.e or l.s == m.s or l.e == m.e or l.e == m.s:return True
    elif cross(a,b) * cross(a,c) >= 0 or cross(d,e) * cross(d,f) >= 0:return False
    else:return True
def plus(a,b):return [x+y for x,y in zip(a,b)]
def projection(a,b):return [x*dot(a,b)/dot(a,a) for x in a]
def proj(A,B,C,D):
    AB = dif(B,A) ; AC = dif(C,A) ; AD = dif(D,A)
    CD = dif(D,C) ; CA = dif(A,C) ; CB = dif(B,C)
    _A = plus(projection(CD,CA),C) 
    _B = plus(projection(CD,CB),C)
    _C = plus(projection(AB,AC),A)
    _D = plus(projection(AB,AD),A)
    return [_A,_B,_C,_D]
def Order(a,b):
    crs = cross(a,b)
    if abs(crs) < 1.0e-12 : crs = 0.0
    if crs > 0 : return "COUNTER_CLOCKWISE"
    elif crs < 0 : return "CLOCKWISE"
    else:
        if dot(a,b) < 0 : return "ONLINE_BACK"
        elif dot(a,a) < dot(b,b) : return "ONLINE_FRONT"
        else : return "ON_SEGMENT"

q = int(input())
for i in range(q):
    a,b,c,d,e,f,g,h = [int(i) for i in input().split()]
    A = [a,b] ; B = [c,d] ; C = [e,f] ; D = [g,h]
    l = Line(A,B) ; m = Line(C,D)
    if isec(l,m):
        print(0.0)
        continue
    _A,_B,_C,_D = proj(A,B,C,D)
    AB = dif(B,A) ; CD = dif(D,C)
    A_C = dif(_C,A) ; A_D = dif(_D,A) ; C_A = dif(_A,C) ; C_B = dif(_B,C)
    DIST = [dist(A,C),dist(A,D),dist(B,C),dist(B,D),dist(_A,A),dist(_B,B),dist(_C,C),dist(_D,D)]
    fun = lambda x : x != "ON_SEGMENT"
    if fun(Order(CD,C_A)) : DIST[4] = sys.maxsize
    if fun(Order(CD,C_B)) : DIST[5] = sys.maxsize
    if fun(Order(AB,A_C)) : DIST[6] = sys.maxsize
    if fun(Order(AB,A_D)) : DIST[7] = sys.maxsize
    print(min(DIST))

Submission status: Wrong Answer

Solution code:
import sys
class Line:
    def __init__(self,p1,p2):
        if p1[1] < p2[1]:self.s=p2;self.e=p1
        elif p1[1] > p2[1]:self.s=p1;self.e=p2
        else:
            if p1[0] < p2[0]:self.s=p1;self.e=p2
            else:self.s=p2;self.e=p1

def cross(a,b):return a[0]*b[1] - a[1]*b[0]
def dot(a,b):return a[0]*b[0]+a[1]*b[1]
def dif(a,b):return [x-y for x,y in zip(a,b)]
def dist(a,b):return ((a[0]-b[0])**2+(a[1]-b[1])**2)**0.5
def isec(l,m):
    a = dif(l.e,l.s);b = dif(m.e,l.s);c = dif(m.s,l.s)
    d = dif(m.e,m.s);e = dif(l.e,m.s);f = dif(l.s,m.s)
    g = lambda a, b : cross(a,b)==0 and dot(a,b)>0 and dot(b,b)<dot(a,a)
    if g(a,b) or g(a,c) or g(d,e) or g(d,f):return True
    elif l.s == m.e or l.s == m.s or l.e == m.e or l.e == m.s:return True
    elif cross(a,b) * cross(a,c) >= 0 or cross(d,e) * cross(d,f) >= 0:return False
    else:return True
def plus(a,b):return [x+y for x,y in zip(a,b)]
def projection(a,b):return [x*dot(a,b)/dot(a,a) for x in a]
def proj(A,B,C,D):
    AB = dif(B,A) ; AC = dif(C,A) ; AD = dif(D,A)
    CD = dif(D,C) ; CA = dif(A,C) ; CB = dif(B,C)
    _A = plus(projection(CD,CA),C) 
    _B = plus(projection(CD,CB),C)
    _C = plus(projection(AB,AC),A)
    _D = plus(projection(AB,AD),A)
    return [_A,_B,_C,_D]
def Order(a,b):
    crs = cross(a,b)
    if abs(crs) < 1.0e-11 : crs = 0.0
    if crs > 0 : return "COUNTER_CLOCKWISE"
    elif crs < 0 : return "CLOCKWISE"
    else:
        if dot(a,b) < 0 : return "ONLINE_BACK"
        elif dot(a,a) < dot(b,b) : return "ONLINE_FRONT"
        else : return "ON_SEGMENT"

q = int(input())
for i in range(q):
    a,b,c,d,e,f,g,h = [int(i) for i in input().split()]
    A = [a,b] ; B = [c,d] ; C = [e,f] ; D = [g,h]
    l = Line(A,B) ; m = Line(C,D)
    if isec(l,m):
        print(0.0)
        continue
    _A,_B,_C,_D = proj(A,B,C,D)
    AB = dif(B,A) ; CD = dif(D,C)
    A_C = dif(_C,A) ; A_D = dif(_D,A) ; C_A = dif(_A,C) ; C_B = dif(_B,C)
    DIST = [dist(A,C),dist(A,D),dist(B,C),dist(B,D),dist(_A,A),dist(_B,B),dist(_C,C),dist(_D,D)]
    fun = lambda x : x != "ON_SEGMENT"
    if fun(Order(CD,C_A)) : DIST[4] = sys.maxsize
    if fun(Order(CD,C_B)) : DIST[5] = sys.maxsize
    if fun(Order(AB,A_C)) : DIST[6] = sys.maxsize
    if fun(Order(AB,A_D)) : DIST[7] = sys.maxsize
    print(min(DIST))

Submission status: Wrong Answer

Solution code:
from math import sqrt
q = int(input())

class Segment(): pass

def dot(a, b):
    return sum([i * j for i,j in zip(a, b)])

def sub(a, b):
    return [a[0] - b[0],a[1] - b[1]]

def cross(a, b):
    return  a[0] * b[1] - a[1] * b[0]

def norm(a):
    return sqrt(a[0] ** 2 + a[1] ** 2)

def ccw(a, b, c):
    x = sub(b, a)
    y = sub(c, a)
    if cross(x, y) > 0: return 1
    if cross(x, y) < 0: return -1
    return 0

def intersect(p1, p2, p3, p4):
    return ccw(p1, p2, p3) ** ccw(p1, p2, p4) <= 0 and \
           ccw(p3, p4, p1) ** ccw(p3, p4, p2) <= 0

def getDistLP(s, p):
    return abs(cross(sub(s.r, s.l), sub(p, s.l))) / norm(sub(s.r, s.l))

def getDistSP(s, p):
    if dot(sub(s.r, s.l),sub(p, s.l)) < 0: return norm(sub(p, s.l))
    if dot(sub(s.l, s.r),sub(p, s.r)) < 0: return norm(sub(p, s.r))
    return getDistLP(s, p)

def getDist(s1, s2):
    if intersect(s1.l, s1.r, s2.l, s2.r): return 0
    return min(getDistSP(s1, s2.l), 
               getDistSP(s1, s2.r),
               getDistSP(s2, s1.l),
               getDistSP(s2, s1.r))

for i in range(q):
    xp0, yp0, xp1, yp1, xp2, yp2, xp3, yp3  = map(int, input().split())
    s1 = Segment()
    s2 = Segment()
    s1.l = [xp0, yp0]
    s1.r = [xp1, yp1]
    s2.l = [xp2, yp2]
    s2.r = [xp3, yp3]
    print(getDist(s1, s2))

Submission status: Wrong Answer

Solution code:
from math import sqrt
q = int(input())

class Segment(): pass

def dot(a, b):
    return sum([i * j for i,j in zip(a, b)])

def sub(a, b):
    return [a[0] - b[0],a[1] - b[1]]

def cross(a, b):
    return  a[0] * b[1] - a[1] * b[0]

def norm(a):
    return sqrt(a[0] ** 2 + a[1] ** 2)

def ccw(a, b, c):
    x = sub(b, a)
    y = sub(c, a)
    if cross(x, y) > 0: return 1
    if cross(x, y) < 0: return -1
    if dot(x, y) < 0: return 2
    if norm(x) < norm(y): return -2
    return 0

def intersect(p1, p2, p3, p4):
    return ccw(p1, p2, p3) ** ccw(p1, p2, p4) <= 0 and \
           ccw(p3, p4, p1) ** ccw(p3, p4, p2) <= 0

def getDistLP(s, p):
    return abs(cross(sub(s.r, s.l), sub(p, s.l))) / norm(sub(s.r, s.l))

def getDistSP(s, p):
    if dot(sub(s.r, s.l),sub(p, s.l)) < 0: return norm(sub(p, s.l))
    if dot(sub(s.l, s.r),sub(p, s.r)) < 0: return norm(sub(p, s.r))
    return getDistLP(s, p)

def getDist(s1, s2):
    if intersect(s1.l, s1.r, s2.l, s2.r): return 0
    return min(getDistSP(s1, s2.l), 
               getDistSP(s1, s2.r),
               getDistSP(s2, s1.l),
               getDistSP(s2, s1.r))

for i in range(q):
    xp0, yp0, xp1, yp1, xp2, yp2, xp3, yp3  = map(int, input().split())
    s1 = Segment()
    s2 = Segment()
    s1.l = [xp0, yp0]
    s1.r = [xp1, yp1]
    s2.l = [xp2, yp2]
    s2.r = [xp3, yp3]
    print(getDist(s1, s2))

Submission status: Wrong Answer

Solution code:
import math

class Point():
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def distance(self, pnt):
        return math.sqrt((self.x - pnt.x)**2 + (self.y - pnt.y)**2)

class Segment():
    def __init__(self, x1, y1, x2, y2):
        self.p1 = Point(x1, y1)
        self.p2 = Point(x2, y2)
        if self.p1.x == self.p2.x:
            self.a = float('inf')
            self.b = None
        else:
            self.a = (self.p1.y - self.p2.y)/(self.p1.x - self.p2.x)
            self.b = self.p1.y - self.a*self.p1.x

    def is_intersect(self, seg):
        a = (seg.p1.x - seg.p2.x) * (self.p1.y - seg.p1.y) + (seg.p1.y - seg.p2.y) * (seg.p1.x - self.p1.x)
        b = (seg.p1.x - seg.p2.x) * (self.p2.y - seg.p1.y) + (seg.p1.y - seg.p2.y) * (seg.p1.x - self.p2.x)
        c = (self.p1.x - self.p2.x) * (seg.p1.y - self.p1.y) + (self.p1.y - self.p2.y) * (self.p1.x - seg.p1.x)
        d = (self.p1.x - self.p2.x) * (seg.p2.y - self.p1.y) + (self.p1.y - self.p2.y) * (self.p1.x - seg.p2.x)
        e = (self.p1.x - seg.p1.x)*(self.p2.x - seg.p2.x)
        f = (self.p1.x - seg.p2.x)*(self.p2.x - seg.p1.x)
        g = (self.p1.y - seg.p1.y)*(self.p2.y - seg.p2.y)
        h = (self.p1.y - seg.p2.y)*(self.p2.y - seg.p1.y)
        return a*b <= 0 and c*d <= 0 and (e <= 0 or f <= 0) and (g <= 0 or h <= 0)

    def cross_point(self, seg):
        if self.is_intersect(seg) == False: return None
        if self.a == float('inf'):
            return self.p1.x, seg.a * self.p1.x + seg.b
        elif seg.a == float('inf'):
            return seg.p1.x, self.a * seg.p1.x + self.b
        else:
            x = -(self.b - seg.b)/(self.a - seg.a)
            y = seg.a * x + seg.b
            return x, y

    def distance_with_point(self, pnt):
        if self.a == float('inf'):
            return abs(pnt.x - self.p1.x)
        dist = abs(pnt.y - self.a*pnt.x - self.b)/math.sqrt(1 + self.a**2)
        a, b = pnt.distance(self.p1), pnt.distance(self.p2)
        lower_bound = min(a, b)
        if lower_bound < dist:
            return dist
        else:
            return lower_bound

    def distance(self, seg):
        if self.is_intersect(seg): return 0
        a = self.distance_with_point(seg.p1)
        b = self.distance_with_point(seg.p2)
        c = seg.distance_with_point(self.p1)
        d = seg.distance_with_point(self.p2)
        return min(a, b, c, d)

q = int(input())
for i in range(q):
    x0, y0, x1, y1, x2, y2, x3, y3 = list(map(int, input().split(' ')))
    line1, line2 = Segment(x0, y0, x1, y1), Segment(x2, y2, x3, y3)
    dist = line1.distance(line2)
    print('%.9f'%dist)

Submission status: Accepted

Solution code:
def dot(a, b):
  return a.real * b.real + a.imag * b.imag

def cross(a, b):
  return a.real * b.imag - a.imag * b.real

def ccw(p0, p1, p2):
  a = p1-p0
  b = p2-p0
  if cross(a,b) > 0:
    return 1 #couner_clockwise
  elif cross(a,b) <0:
    return -1 #clockwise
  elif dot(a,b) < 0:
    return 2 #online_back
  elif abs(a) < abs(b):
    return -2 #online_front
  else:
    return 0 #on_segment

def get_distanceLP(p0,p1,p2):
  return abs(cross(p1 - p0,p2-p0)/abs(p1-p0))

def get_distanceSP(p0,p1,p2):
  if dot(p1-p0,p2-p0)<0:
    return abs(p2-p0)
  if dot(p0-p1,p2-p1)<0:
    return abs(p2-p1)
  return get_distanceLP(p0,p1,p2)

def get_distance(a,b,c,d):
  if intersect(a,b,c,d):
    return 0
  return min(min(get_distanceSP(a,b,c),get_distanceSP(a,b,d)),min(get_distanceSP(c,d,a),get_distanceSP(c,d,b)))

def intersect(a,b,c,d):
  return ccw(a,b,c) * ccw(a,b,d) <=0 and ccw(c,d,a) * ccw(c,d,b) <=0

n=int(input())
for i in range(n):
  x0,y0,x1,y1,x2,y2,x3,y3 = map(int,input().split())
  p0=complex(x0,y0)
  p1=complex(x1,y1)
  p2=complex(x2,y2)
  p3=complex(x3,y3)
  print(get_distance(p0,p1,p2,p3))

Submission status: Accepted

Solution code:
#! /usr/bin/env python3

from typing import List, Tuple
from math import sqrt

EPS = 1e-10


def float_equal(x: float, y: float) -> bool:
    return abs(x - y) < EPS


class Point:

    def __init__(self, x: float=0.0, y: float=0.0) -> None:
        self.x = x
        self.y = y

    def __repr__(self) -> str:
        return "Point({}, {})".format(self.x, self.y)

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Point):
            # print("NotImplemented in Point")
            return NotImplemented
        return float_equal(self.x, other.x) and \
            float_equal(self.y, other.y)

    def __add__(self, other: 'Point') -> 'Point':
        return Point(self.x + other.x, self.y + other.y)

    def __sub__(self, other: 'Point') -> 'Point':
        return Point(self.x - other.x, self.y - other.y)

    def __mul__(self, k: float) -> 'Point':
        return Point(self.x * k, self.y * k)

    def __rmul__(self, k: float) -> 'Point':
        return self * k

    def __truediv__(self, k: float) -> 'Point':
        return Point(self.x / k, self.y / k)

    def __lt__(self, other: 'Point') -> bool:
        return self.y < other.y \
            if abs(self.x - other.x) < EPS \
            else self.x < other.x

    def norm(self):
        return self.x * self.x + self.y * self.y

    def abs(self):
        return sqrt(self.norm())

    def dot(self, other: 'Point') -> float:
        return self.x * other.x + self.y * other.y

    def cross(self, other: 'Point') -> float:
        return self.x * other.y - self.y * other.x

    def is_orthogonal(self, other: 'Point') -> bool:
        return float_equal(self.dot(other), 0.0)

    def is_parallel(self, other: 'Point') -> bool:
        return float_equal(self.cross(other), 0.0)

    def distance(self, other: 'Point') -> float:
        return Segment(self, other).vector().abs()

    def in_side_of(self, seg: 'Segment') -> bool:
        return seg.vector().dot(
            Segment(seg.p1, self).vector()) >= 0

    def in_width_of(self, seg: 'Segment') -> bool:
        return \
            self.in_side_of(seg) and \
            self.in_side_of(seg.reverse())

    def distance_to_segment(self, seg: 'Segment') -> float:
        if self.in_width_of(seg):
            return self.distance(seg.projection(self))
        else:
            return min(self.distance(seg.p1),
                       self.distance(seg.p2))


Vector = Point


class Segment:

    def __init__(self, p1: Point = None, p2: Point = None) -> None:
        self.p1: Point = Point() if p1 is None else p1
        self.p2: Point = Point() if p2 is None else p2

    def __repr__(self) -> str:
        return "Segment({}, {})".format(self.p1, self.p2)

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Segment):
            # print("NotImplemented in Segment")
            return NotImplemented
        return self.p1 == other.p1 and self.p2 == other.p2

    def vector(self) -> Vector:
        return self.p2 - self.p1

    def reverse(self) -> 'Segment':
        return Segment(self.p2, self.p1)

    def is_orthogonal(self, other: 'Segment') -> bool:
        return self.vector().is_orthogonal(other.vector())

    def is_parallel(self, other: 'Segment') -> bool:
        return self.vector().is_parallel(other.vector())

    def projection(self, p: Point) -> Point:
        v = self.vector()
        vp = p - self.p1
        return v.dot(vp) / v.norm() * v + self.p1

    def reflection(self, p: Point) -> Point:
        x = self.projection(p)
        return p + 2 * (x - p)

    def intersect_ratio(self, other: 'Segment') -> Tuple[float, float]:
        a = self.vector()
        b = other.vector()
        c = self.p1 - other.p1
        s = b.cross(c) / a.cross(b)
        t = a.cross(c) / a.cross(b)
        return s, t

    def intersects(self, other: 'Segment') -> bool:
        s, t = self.intersect_ratio(other)
        return (0 <= s <= 1) and (0 <= t <= 1)

    def intersection(self, other: 'Segment') -> Point:
        s, _ = self.intersect_ratio(other)
        return self.p1 + s * self.vector()

    def distance_with_segment(self, other: 'Segment') -> float:
        if not self.is_parallel(other) and \
                self.intersects(other):
            return 0
        else:
            return min(
                self.p1.distance_to_segment(other),
                self.p2.distance_to_segment(other),
                other.p1.distance_to_segment(self),
                other.p2.distance_to_segment(self))


Line = Segment


class Circle:

    def __init__(self, c: Point=None, r: float=0.0) -> None:
        self.c: Point = Point() if c is None else c
        self.r: float = r

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, Circle):
            return NotImplemented
        return self.c == other.c and self.r == other.r

    def __repr__(self) -> str:
        return "Circle({}, {})".format(self.c, self.r)
        
def main() -> None:
    n = int(input())

    for _ in range(n):
        x1, y1, x2, y2, x3, y3, x4, y4 = [int(x) for x in input().split()]
        s1 = Segment(Point(x1, y1), Point(x2, y2))
        s2 = Segment(Point(x3, y3), Point(x4, y4))
        print(s1.distance_with_segment(s2))


if __name__ == "__main__":
    main()