Problem:


Counter-Clockwise

For given three points p0, p1, p2, print

COUNTER_CLOCKWISE

if p0, p1, p2 make a counterclockwise turn (1),

CLOCKWISE

if p0, p1, p2 make a clockwise turn (2),

ONLINE_BACK

if p2 is on a line p2, p0, p1 in this order (3),

ONLINE_FRONT

if p2 is on a line p0, p1, p2 in this order (4),

ON_SEGMENT

if p2 is on a segment p0p1 (5).

Input

xp0 yp0 xp1 yp1
q
xp20 yp20
xp21 yp21
...
xp2q-1 yp2q-1

In the first line, integer coordinates of p0 and p1 are given. Then, q queries are given for integer coordinates of p2.

Output

For each query, print the above mentioned status.

Constraints

1 ≤ q ≤ 1000

-10000 ≤ xi, yi ≤ 10000

p0 and p1 are not identical.

Sample Input 1

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

Sample Output 1

COUNTER_CLOCKWISE
CLOCKWISE

Sample Input 2

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

Sample Output 2

ONLINE_BACK
ON_SEGMENT
ONLINE_FRONT



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


Sample output:
COUNTER_CLOCKWISE
CLOCKWISE

Submission status: Wrong Answer

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

from typing import List, Tuple
from math import sqrt
from enum import Enum

EPS = 1e-10


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


class PointLocation(Enum):
    COUNTER_CLOCKWISE = 1
    CLOCKWISE = 2
    ONLINE_BACK = 3
    ONLINE__FRONT = 4
    ON_SEGMENT = 5


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 (self - other).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_line(self, seg: 'Segment') -> float:
        return \
            abs((self - seg.p1).cross(seg.vector())) / \
            seg.length()

    def distance_to_segment(self, seg: 'Segment') -> float:
        if not self.in_side_of(seg):
            return self.distance(seg.p1)
        if not self.in_side_of(seg.reverse()):
            return self.distance(seg.p2)
        else:
            return self.distance_to_line(seg)

    def location(self, seg: 'Segment') -> PointLocation:
        p = self - seg.p1
        d = seg.vector().cross(p)
        if d < 0:
            return PointLocation.CLOCKWISE
        elif d > 0:
            return PointLocation.COUNTER_CLOCKWISE
        else:
            r = (self.x - seg.p1.x) / (seg.p2.x - seg.p1.x)
            if r < 0:
                return PointLocation.ONLINE_BACK
            elif r > 1:
                return PointLocation.ONLINE__FRONT
            else:
                return PointLocation.ON_SEGMENT


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 length(self) -> float:
        return self.p1.distance(self.p2)

    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:
    x0, y0, x1, y1 = [int(x) for x in input().split()]
    s = Segment(Point(x0, y0), Point(x1, y1))
    q = int(input())

    for _ in range(q):
        x2, y2 = [int(x) for x in input().split()]
        print(Point(x2, y2).location(s).name)


if __name__ == "__main__":
    main()

Submission status: Wrong Answer

Solution code:
x0, y0, x1, y1 = map(int, input().split())
q = int(input())

p0, p1 = complex(x0, y0), complex(x1, y1)
p0p1 = p1 - p0

while q:
    q -= 1
    p2 = complex(*map(int, input().split()))
    p0p2 = p2 - p0
    prod_cross = p0p1.real * p0p2.imag + p0p1.imag * p0p2.real
    if abs(prod_cross) < 1e-6:
        if p0p1.real * p0p2.real >= 0:
            print('ONLINE_FRONT' if p0p1.real < p0p2.real else 'ON_SEGMENT')
        else:
            print('ONLINE_BACK')
    else:
        print('COUNTER_CLOCKWISE' if prod_cross > 0 else 'CLOCKWISE')

Submission status: Wrong Answer

Solution code:
x0, y0, x1, y1 = map(int, input().split())
q = int(input())

p0, p1 = complex(x0, y0), complex(x1, y1)
p0p1 = p1 - p0

while q:
    q -= 1
    p2 = complex(*map(int, input().split()))
    p0p2 = p2 - p0
    prod_cross = p0p1.real * p0p2.imag - p0p1.imag * p0p2.real
    if abs(prod_cross) < 1e-6:
        if p0p1.real * p0p2.real >= 0:
            print('ONLINE_FRONT' if p0p1.real < p0p2.real else 'ON_SEGMENT')
        else:
            print('ONLINE_BACK')
    else:
        print('COUNTER_CLOCKWISE' if prod_cross > 0 else 'CLOCKWISE')

Submission status: Wrong Answer

Solution code:
x0, y0, x1, y1 = map(int, input().split())
q = int(input())

p0, p1 = complex(x0, y0), complex(x1, y1)
p0p1 = p1 - p0

while q:
    q -= 1
    p2 = complex(*map(int, input().split()))
    p0p2 = p2 - p0
    prod_cross = p0p1.real * p0p2.imag - p0p1.imag * p0p2.real
    if abs(prod_cross) < 1e-6:
        if p0p1.real * p0p2.real >= 0 and p0p1.imag * p0p2.imag >= 0:
            print('ONLINE_FRONT' if p0p1.real < p0p2.real else 'ON_SEGMENT')
        else:
            print('ONLINE_BACK')
    else:
        print('COUNTER_CLOCKWISE' if prod_cross > 0 else 'CLOCKWISE')

Submission status: Wrong Answer

Solution code:
x0,y0,x1,y1 = map(float, raw_input().split())
q = int(raw_input())
for _ in xrange(q):
  x2,y2 = map(float, raw_input().split())
  ax = x1-x0
  ay = y1-y0
  bx = x2-x0
  by = y2-y0
  # check sin is positive or negative
  sin = ax*by-ay*bx
  if sin == 0:
    if(ax*bx < 0):
      print "ONLINE_BACK"
    else:
      if bx > ax:
        print "ONLINE_FRONT"
      else:
        print "ON_SEGMENT"
  elif sin > 0:
    print "COUNTER_CLOCKWISE"
  else:
    print "CLOCKWISE"

Submission status: Wrong Answer

Solution code:
class Point:
    def __init__(self, x , y):
        self.x = x
        self.y = y
    def __sub__(self, p):
        x_sub = self.x - p.x
        y_sub = self.y - p.y
        return Point(x_sub, y_sub)

class Vector:
    def __init__(self, p):
        self.x = p.x
        self.y = p.y
    def norm(self):
        return (self.x ** 2 + self.y ** 2) ** 0.5

def cross(v1, v2):
    return v1.x * v2.y - v1.y * v2.x

def dot(v1, v2):
    return v1.x * v2.x + v1.x * v2.x

def ccw(p0, p1, p2):
    a = Vector(p1 - p0)
    b = Vector(p2 - p0)
    cross_ab = cross(a, b)
    if cross_ab > 0:
        print("COUNTER_CLOCKWISE")
    elif cross_ab < 0:
        print("CLOCKWISE")
    elif dot(a, b) < 0:
        print("ONLINE_BACK")
    elif a.norm() < b.norm():
        print("ONLINE_FRONT")
    else:
        print("ON_SEGMENT")

import sys

file_input = sys.stdin

x_p0, y_p0, x_p1, y_p1 = map(int, file_input.readline().split())
p0 = Point(x_p0, y_p0)
p1 = Point(x_p1, y_p1)

q = map(int, file_input.readline())

for line in file_input:
    x_p2, y_p2 = map(int, line.split())
    p2 = Point(x_p2, y_p2)
    ccw(p0, p1, p2)

Submission status: Wrong Answer

Solution code:
from math import sqrt
xp0, yp0, xp1, yp1 = map(int, input().split())
a = [xp0, yp0]
b = [xp1, yp1]
q = int(input())

CCW = {1: 'COUNTER_CLOCKWISE',
       2: 'CLOCKWISE',
       3: 'ONLINE_BACK',
       4: 'ONLINE_FRONT',
       5: 'ON_SEGMENT',}

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 _abs(a):
    return sqrt(a[0] ** 2 + a[1] ** 2)

def ccw(a, b, c):
    x = sub(b, c)
    y = sub(c, a)
    if cross(x, y) > 0: return 1
    if cross(x, y) < 0: return 2
    if dot(x, y) < 0: return 3
    if _abs(x) < _abs(y): return 4
    return 5

for i in range(q):
    c = list(map(int, input().split()))
    print(CCW[ccw(a, b, c)])

Submission status: Wrong Answer

Solution code:
# -*- coding: utf-8 -*-

import collections
import math


class Vector2(collections.namedtuple("Vector2", ["x",  "y"])):

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

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

    def __mul__(self, scalar):
        return Vector2(self.x * scalar, self.y * scalar)

    def __neg__(self):
        return Vector2(-self.x, -self.y)

    def __pos__(self):
        return Vector2(+self.x, +self.y)

    def __abs__(self):  # norm
        return math.sqrt(float(self.x * self.x + self.y * self.y))

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

    def cross(self, other):  # cross product
        return self.x * other.y - self.y * other.x


def getDistanceSP(segment, point):
    p = point
    p1, p2 = segment
    if (p2 - p1).dot(p - p1) < 0:
        return abs(p - p1)
    if (p1 - p2).dot(p - p2) < 0:
        return abs(p - p2)
    return abs((p2 - p1).cross(p - p1)) / abs(p2 - p1)


def getDistance(s1, s2):
    if 0:  # intersect
        return 0
    a, b = s1
    c, d = s2
    return min(getDistanceSP(s1, c), getDistanceSP(s1, d), getDistanceSP(s2, a), getDistanceSP(s2, b))


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


if __name__ == '__main__':

    a, b, c, d = map(int, input().split())
    p0 = Vector2(a, b)
    p1 = Vector2(c, d)
    q = int(input())
    ans = []
    for _ in range(q):
        e, f = map(int, input().split())
        p2 = Vector2(e, f)
        ans.append(ccw(p0, p1, p2))
    dic = {1: "COUNTER_CLOCKWISE", -1: "CLOCLWISE",
           2: "ONLINE_BACK", -2: "ONLINE_FRONT", 0: "ON_SEGMENT"}
    for a in ans:
        print(dic[a])

Submission status: Wrong Answer

Solution code:
import math

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

class Vector():
    def __init__(self, start, end):
        self.x = end.x - start.x
        self.y = end.y - start.y
        self.r = math.sqrt(pow(self.x, 2) + pow(self.y, 2))
        self.theta = math.atan2(self.y, self.x)

x0, y0, x1, y1 = list(map(int, input().split(' ')))
p0, p1 = Point(x0, y0), Point(x1, y1)
vec1 = Vector(p0, p1)

q = int(input())
for i in range(q):
    x2, y2 = list(map(int, input().split(' ')))
    p2 = Point(x2, y2)
    vec2 = Vector(p0, p2)
    if vec1.theta == vec2.theta:
        if vec1.r < vec2.r:
            print('ONLINE_FRONT')
        else:
            print('ON_SEGMENT')
    elif abs(vec1.theta - vec2.theta) == math.pi:
        print('ONLINE_BACK')
    elif vec2.theta - vec1.theta > 0:
        print('COUNTER_CLOCKWISE')
    elif vec2.theta - vec1.theta < 0:
        print('CLOCKWISE')

Submission status: Wrong Answer

Solution code:
import math

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

class Vector():
    def __init__(self, start, end):
        self.x = end.x - start.x
        self.y = end.y - start.y
        self.r = math.sqrt(pow(self.x, 2) + pow(self.y, 2))
        self.theta = math.atan2(self.y, self.x)

x0, y0, x1, y1 = list(map(int, input().split(' ')))
p0, p1 = Point(x0, y0), Point(x1, y1)
vec1 = Vector(p0, p1)

q = int(input())
for i in range(q):
    x2, y2 = list(map(int, input().split(' ')))
    p2 = Point(x2, y2)
    vec2 = Vector(p0, p2)
    if vec1.theta == vec2.theta:
        if vec1.r < vec2.r:
            print('ONLINE_FRONT')
        else:
            print('ON_SEGMENT')
    elif abs(vec1.theta - vec2.theta) == math.pi:
        print('ONLINE_BACK')
    elif vec2.theta - vec1.theta > 0 or vec2.theta - vec1.theta < -1*math.pi:
        print('COUNTER_CLOCKWISE')
    elif vec2.theta - vec1.theta < 0 or vec2.theta - vec1.theta > math.pi:
        print('CLOCKWISE')

Submission status: Wrong Answer

Solution code:
import math

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

class Vector():
    def __init__(self, start, end):
        self.x = end.x - start.x
        self.y = end.y - start.y
        self.r = math.sqrt(pow(self.x, 2) + pow(self.y, 2))
        self.theta = math.atan2(self.y, self.x)

x0, y0, x1, y1 = list(map(int, input().split(' ')))
p0, p1 = Point(x0, y0), Point(x1, y1)
vec1 = Vector(p0, p1)

q = int(input())
for i in range(q):
    x2, y2 = list(map(int, input().split(' ')))
    p2 = Point(x2, y2)
    vec2 = Vector(p0, p2)
    if vec1.theta == vec2.theta:
        if vec1.r < vec2.r:
            print('ONLINE_FRONT')
        else:
            print('ON_SEGMENT')
    elif abs(vec1.theta - vec2.theta) == math.pi:
        print('ONLINE_BACK')
    elif (0 < vec2.theta - vec1.theta and vec2.theta - vec1.theta < math.pi)  or vec2.theta - vec1.theta < -1*math.pi:
        print('COUNTER_CLOCKWISE')
    elif (-1*math.pi < vec2.theta - vec1.theta and vec2.theta - vec1.theta < 0) or vec2.theta - vec1.theta > math.pi:
        print('CLOCKWISE')

Submission status: Accepted

Solution code:
x0,y0,x1,y1 = map(int, input().split())
p0=complex(x0,y0)
p1=complex(x1,y1)
q = int(input())

CCW = {1: 'COUNTER_CLOCKWISE',
       -1: 'CLOCKWISE',
       2: 'ONLINE_BACK',
       -2: 'ONLINE_FRONT',
       0: 'ON_SEGMENT',}

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

for i in range(q):
  p2=complex(*map(int,input().split()))
  print(CCW[ccw(p0,p1,p2)])

Submission status: Accepted

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

from typing import List, Tuple
from math import sqrt
from enum import Enum

EPS = 1e-10


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


class PointLocation(Enum):
    COUNTER_CLOCKWISE = 1
    CLOCKWISE = 2
    ONLINE_BACK = 3
    ONLINE_FRONT = 4
    ON_SEGMENT = 5


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 (self - other).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_line(self, seg: 'Segment') -> float:
        return \
            abs((self - seg.p1).cross(seg.vector())) / \
            seg.length()

    def distance_to_segment(self, seg: 'Segment') -> float:
        if not self.in_side_of(seg):
            return self.distance(seg.p1)
        if not self.in_side_of(seg.reverse()):
            return self.distance(seg.p2)
        else:
            return self.distance_to_line(seg)

    def location(self, seg: 'Segment') -> PointLocation:
        p = self - seg.p1
        d = seg.vector().cross(p)
        if d < 0:
            return PointLocation.CLOCKWISE
        elif d > 0:
            return PointLocation.COUNTER_CLOCKWISE
        else:
            if seg.p2.x != seg.p1.x:
                r = (self.x - seg.p1.x) / (seg.p2.x - seg.p1.x)
            else:
                r = (self.y - seg.p1.y) / (seg.p2.y - seg.p1.y)
            if r < 0:
                return PointLocation.ONLINE_BACK
            elif r > 1:
                return PointLocation.ONLINE_FRONT
            else:
                return PointLocation.ON_SEGMENT


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 length(self) -> float:
        return self.p1.distance(self.p2)

    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:
    x0, y0, x1, y1 = [int(x) for x in input().split()]
    s = Segment(Point(x0, y0), Point(x1, y1))
    q = int(input())

    for _ in range(q):
        x2, y2 = [int(x) for x in input().split()]
        print(Point(x2, y2).location(s).name)


if __name__ == "__main__":
    main()

Submission status: Accepted

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

from typing import List, Tuple
from math import sqrt
from enum import Enum

EPS = 1e-10


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


class PointLocation(Enum):
    COUNTER_CLOCKWISE = 1
    CLOCKWISE = 2
    ONLINE_BACK = 3
    ONLINE_FRONT = 4
    ON_SEGMENT = 5


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 (self - other).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_line(self, seg: 'Segment') -> float:
        return \
            abs((self - seg.p1).cross(seg.vector())) / \
            seg.length()

    def distance_to_segment(self, seg: 'Segment') -> float:
        if not self.in_side_of(seg):
            return self.distance(seg.p1)
        if not self.in_side_of(seg.reverse()):
            return self.distance(seg.p2)
        else:
            return self.distance_to_line(seg)

    def location(self, seg: 'Segment') -> PointLocation:
        p = self - seg.p1
        d = seg.vector().cross(p)
        if float_equal(d, 0.0):
            if seg.p2.x != seg.p1.x:
                r = (self.x - seg.p1.x) / (seg.p2.x - seg.p1.x)
            else:
                r = (self.y - seg.p1.y) / (seg.p2.y - seg.p1.y)
            if r < 0:
                return PointLocation.ONLINE_BACK
            elif r > 1:
                return PointLocation.ONLINE_FRONT
            else:
                return PointLocation.ON_SEGMENT
        elif d > 0:
            return PointLocation.COUNTER_CLOCKWISE
        else:
            return PointLocation.CLOCKWISE


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 length(self) -> float:
        return self.p1.distance(self.p2)

    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:
    x0, y0, x1, y1 = [int(x) for x in input().split()]
    s = Segment(Point(x0, y0), Point(x1, y1))
    q = int(input())

    for _ in range(q):
        x2, y2 = [int(x) for x in input().split()]
        print(Point(x2, y2).location(s).name)


if __name__ == "__main__":
    main()

Submission status: Accepted

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



def lt(a, b):
    if a.real != b.real:
        return a.real < b.real
    return a.imag < b.imag


def main():
    x1, y1, x2, y2 = map(int, readline().split())
    p1, p2 = x1 + y1 * 1j, x2 + y2 * 1j
    q = int(readline())
    for i in range(q):
        xi, yi = map(int, readline().split())
        pi = xi + yi * 1j

        s = cross(p2 - p1, pi - p1)
        if abs(s) < 1e-10:
            if (lt(p1, p2) and lt(p2, pi)) or (lt(pi, p2) and lt(p2, p1)):
                print('ONLINE_FRONT')
            elif (lt(pi, p1) and lt(p1, p2)) or (lt(p2, p1) and lt(p1, pi)):
                print('ONLINE_BACK')
            else:
                print('ON_SEGMENT')
        elif s < 0:
            print('CLOCKWISE')
        else:
            print('COUNTER_CLOCKWISE')


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 cross(a, b):
    return a.real * b.imag - a.imag * b.real
main()