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)
To embed this project on your website, copy the following code and paste it into your website's HTML: