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 ≠ p1 and
p2 ≠ 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

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using static System.Console;
using System.Text;
using System.IO;


namespace AOJ
{
    using Vector = Point;
    using Line = Segment;
    using Polygon = List<Point>;

    class Consts
    {
        public static readonly double EPS = 1e-10;
    }
    class Point
    {
        double x, y;
        public double X { get { return this.x; } set { this.x = value; } }
        public double Y { get { return this.y; } set { this.y = value; } }
        public Point(double x = 0, double y = 0)
        {
            this.x = x;
            this.y = y;
        }

        static public Point operator +(Point p1, Point p2) => new Point(p1.x + p2.x, p1.y + p2.y);
        static public Point operator -(Point p1, Point p2) => new Point(p1.x - p2.x, p1.y - p2.y);
        static public Point operator *(Point p, double a) => new Point(a * p.x, a * p.y);
        static public Point operator *(double a, Point p) => p * a;
        static public Point operator /(Point p, double a) => new Point(p.x / a, p.y / a);
        static public bool operator <(Point p1, Point p2) => p1.x != p2.x ? p1.x < p2.x : p1.y < p2.y;
        static public bool operator >(Point p1, Point p2) => p2 < p1;

        static public bool operator ==(Point p1, Point p2) => (p1.x - p2.x) < Consts.EPS && (p1.y - p2.y) < Consts.EPS;
        static public bool operator !=(Point p1, Point p2) => !(p1 == p2);

        public double abs() => Math.Sqrt(norm());
        public double norm() => this.x * this.x + this.y * this.y;

        public override bool Equals(object obj)
        {
            if ((object)obj == null || this.GetType() != obj.GetType())
            {
                return false;
            }
            var c = (Point)obj;
            return this == c;
        }
        public override int GetHashCode()
        {
            return this.x.GetHashCode() ^ this.y.GetHashCode();
        }
    }
    struct Segment
    {
        public Point p1, p2;
    }
    class Circle
    {
        public Point c;
        public double r;
        public Circle(Point c, double r)
        {
            this.c = c;
            this.r = r;
        }
    }

    class VecCalc
    {
        static bool equals(double a, double b) => Math.Abs(a - b) < Consts.EPS;
        //内積
        static public double dot(Vector a, Vector b)
        {
            return a.X * b.X + a.Y * b.Y;
        }
        //外積
        static public double cross(Vector a, Vector b)
        {
            return a.X * b.Y - a.Y * b.X;
        }
        //16.2 直行判定
        static public bool isOrthogonal(Vector a, Vector b)
        {
            return equals(dot(a, b), 0.0);
        }
        static public bool isOrthogonal(Point a1, Point a2, Point b1, Point b2)
        {
            return isOrthogonal(a1 - a2, b1 - b2);
        }
        static public bool isOrthogonal(Segment s1, Segment s2)
        {
            return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
        }
        //16.2 平行判定
        static public bool isParallel(Vector a, Vector b)
        {
            return equals(cross(a, b), 0.0);
        }
        static public bool isParallel(Point a1, Point a2, Point b1, Point b2)
        {
            return isParallel(a1 - a2, b1 - b2);
        }
        static public bool isParallel(Segment s1, Segment s2)
        {
            return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
        }
        //16.3 射影
        static public Point project(Segment s, Point p)
        {
            Vector b = s.p2 - s.p1;
            double r = dot(p - s.p1, b) / b.norm();
            return s.p1 + b * r;
        }
        //16.4 反射
        static public Point reflection(Segment s, Point p)
        {
            return 2 * project(s, p) - p;
            //mid = project(s, p) - p;
            //return mid + mid - p;
        }
        //16.5 距離
        //2点間の距離
        static public double getDistance(Point a, Point b)
        {
            return (a - b).abs();
        }
        //直線lと点pの距離
        static public double getDistanceLP(Line l,Point p)
        {
            return Math.Abs(cross(l.p2 - l.p1, p - l.p1) / (l.p2 - l.p1).abs());
        }
        //線分sと点pの距離
        static public double getDistanceSP(Segment s, Point p)
        {
            if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return (p - s.p1).abs();
            if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return (p - s.p2).abs();
            return getDistanceLP(s, p);
        }
        static public double getDistance(Segment s1, Segment s2)
        {
            if (intersect(s1, s2)) return 0.0;
            return Math.Min(
                    Math.Min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
                    Math.Min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2))
                );
        }
        //16.6 反時計回り
        static public readonly int COUNTER_CLOCKWISE=1;
        static public readonly int CLOCKWISE = -1;
        static public readonly int ONLINE_BACK = 2;
        static public readonly int ONLINE_FRONT = -2;
        static public readonly int ON_SEGMENT = 0;
        static public int ccw(Point p0, Point p1, Point p2)
        {
            Vector a = p1 - p0;
            Vector b = p2 - p0;
            var dot_ = dot(a, b);
            var cross_ = cross(a, b);
            if (Consts.EPS < cross_) return COUNTER_CLOCKWISE;
            if (cross_ < -Consts.EPS) return CLOCKWISE;
            if (dot_ < -Consts.EPS) return ONLINE_BACK;
            if (a.norm() < b.norm()) return ONLINE_FRONT;
            return ON_SEGMENT;
        }
        static public int ccw(Segment s, Point p)
        {
            return ccw(s.p1, s.p2, p);

        }
        //16.7 線分の交差判定
        static public bool intersect(Point p1, Point p2,Point p3,Point p4)
        {
            return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
                ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0
                );
        }
        static public bool intersect(Segment s1, Segment s2)
        {
            return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
        }
    }
    class Program
    {
        static public long[] Sarray() { return ReadLine().Trim().Split().Select(long.Parse).ToArray(); }
        static public List<long> Slist() { return ReadLine().Split().Select(long.Parse).ToList(); }


        static void Main(string[] args)
        {
            var Q = Sarray()[0];
            for (var i = 0; i < Q; ++i)
            {
                var p0123 = Sarray();
                var p0 = new Point(p0123[0], p0123[1]);
                var p1 = new Point(p0123[2], p0123[3]);
                var p2 = new Point(p0123[4], p0123[5]);
                var p3 = new Point(p0123[6], p0123[7]);

                var ans = VecCalc.getDistance(new Segment() { p1 = p0, p2 = p1 }, new Segment() { p1 = p2, p2 = p3 });
                WriteLine(ans);
            }
        }
    }
}