from math import ceil

# n = 20
# arr =[ ['' for _ in range(n)] for _ in range(n)]
# for x in range(n):
#     for y in range(n):
#         if x + y == 1:
#             arr[x][y] = ' 3'
#         elif x == y == 2:
#             arr[x][y] = ' 4'
#         else:            
#             a = ceil(max(x / 2, y / 2, (x + y) / 3))
#             arr[x][y] = str(a + (a + x + y) % 2).rjust(2, ' ')
# print('\n'.join(' '.join(x) for x in arr))

def knight_dist(_x, _y):
    x, y = abs(_x), abs(_y)
    if x + y == 1:
        return 3
    elif x == y == 2:
        return 4
    else:            
        a = ceil(max(x / 2, y / 2, (x + y) / 3))
        return a + (a + x + y) % 2
        
def solve(_x, _y):
    sx, sy = 1 if _x >= 0 else -1, 1 if _y >= 0 else -1
    x, y = abs(_x), abs(_y)
    if (x, y) == (1, 1):
        return [(-sx, 2 * sy), (2 * sx, -sy)]
    if (x, y) == (2, 2):
        return [(1, -2), (-2, 1), (2, 1), (1, 2)]
    if (x, y) == (1, 0):
        return [(1, -2), (-2, 1), (2, 1)]
    if (x, y) == (0, 1):
        return [(-2, 1), (1, -2), (1, 2)]
    if (x, y) == (2, 0):
        return [(1, -2), (1, 2)]
    if (x, y) == (0, 2):
        return [(-2, 1), (2, 1)]

    if y <= x / 2:
        b = x / 2 - y
        l = max(0, min(x // 2 - 1, y - 1))
        snd = [(2, 1)] * l
        x, y =  x - 2 * l, y - l
        # print("pos start", x, y, l)
        k = int((x - 2) / 4)  
        fst = [(2, 1) if i % 2 == 0 else (2, -1) for i in range(k * 2)] if k > 0 else []
        x -= 4 * k
        # print("pos med", x, y)
        if x - 2 >= 2:
            if y == 1:
                fst.insert(0, (2, 1))
                x -= 2
                y -= 1
            else:
                fst.insert(0, (2, -1))
                x -= 2
                y += 1
        print("pos before", x, y, fst)
        if (x, y) == (3, 0):
            fst.insert(0, (2, -1))
            fst.insert(0, (-1, 2))
            fst.insert(0, (2, -1))
        elif (x, y) == (3, 1):
            
            fst.insert(0, (1, 2))
            fst.insert(0, (2, -1))
        elif (x, y) == (2, 0):
            fst.insert(0, (1, 2))
            fst.insert(0, (1, -2))
        elif (x, y) == (2, 1):
            fst.insert(0, (2, 1))
        return [(sx * X, sy * Y) for X, Y in fst + snd]
    elif x <= y / 2:
        return [(sx * Y, sy * X) for X, Y in solve(y, x)]
    else:
        if y <= x:
            d = ceil((2 * y - x) / 3)
            snd = [(1, 2) for _ in range(d)]
            fst = solve(x - d, y - 2 * d)
            return [(sx * X, sy * Y) for X, Y in fst + snd]
        else:
            d = ceil((2 * x - y) / 3)
            snd = [(2, 1) for _ in range(d)]
            fst = solve(x - 2 * d, y - d)
            return [(sx * X, sy * Y) for X, Y in fst + snd]

        
from random import randint


def show_path(x, y):
    print("#" * 30)
    path = solve(x, y)
    
    print(x, y)
    print(path)
    l, k = len(path), knight_dist(x, y)

    
    ans = [(x, y)]
    X, Y = x, y
    for dx, dy in reversed(path):
        x, y = x - dx, y - dy
        ans.append((x, y))
    if l != k or (x, y) != (0, 0):
        print("x, y :", X, Y)
        print("len :", l)
        print("distance :", k)
        print(ans)

show_path(4, 4)
# show_path(7, 4)
# show_path(18, 10)
# for _ in range(100):
#     y = randint(1, 100)
#     x = randint(1, 100)
#     show_path(x,y)
        

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: