The following Python 3 code tries to find all paths that start by moving to (0,1) and return back to origin from (16,0). The vector candidates are hardcoded to eliminate unnecessary branches. (I know they can be reordered to eliminate branches earlier, but I'm too lazy.) It took ~5 minutes to run on my PC.
import time
def cmp(a, b):
return (a > b) - (a < b)
def orientation(p, q, r):
return cmp((q[1] - p[1]) * (r[0] - p[0]), (q[0] - p[0]) * (r[1] - q[1]))
def intersect_test(p, q, r, s):
return (orientation(p, q, r) != orientation(p, q, s) and
orientation(r, s, p) != orientation(r, s, q))
vecs = [
[(16,0)],
[(12,9),(9,12),(0,15),(-9,12),(-12,9),(-12,-9),(-9,-12),(0,-15),(9,-12),(12,-9)],
[(14,0),(0,14),(-14,0),(0,-14)],
[(13,0),(12,5),(5,12),(0,13),(-5,12),(-12,5),(-13,0),(-12,-5),(-5,-12),(0,-13),(5,-12),(12,-5)],
[(12,0),(0,12),(-12,0),(0,-12)],
[(11,0),(0,11),(-11,0),(0,-11)],
[(10,0),(8,6),(6,8),(0,10),(-6,8),(-8,6),(-10,0),(-8,-6),(-6,-8),(0,-10),(6,-8),(8,-6)],
[(9,0),(0,9),(-9,0),(0,-9)],
[(8,0),(0,8),(-8,0),(0,-8)],
[(7,0),(0,7),(-7,0),(0,-7)],
[(6,0),(0,6),(-6,0),(0,-6)],
[(4,3),(3,4),(0,5),(-3,4),(-4,3),(-4,-3),(-3,-4),(0,-5),(3,-4),(4,-3)],
[(4,0),(-4,0)],
[(0,3),(0,-3)],
[(2,0),(-2,0)],
[(0,-1)]
]
solutions = []
def find_polygons(pts, segs, last_vec, vecs):
if not vecs:
solutions.append(pts)
return
vecs2 = vecs[1:]
xlast, ylast = last_vec
for xoff, yoff in vecs[0]:
if xlast * yoff == xoff * ylast: continue
newpt = (pts[-1][0] + xoff, pts[-1][1] + yoff)
newseg = (pts[-1], newpt)
if (not vecs2) and newpt != (0,0): continue
exclude_first = not vecs2
if any(intersect_test(*seg,*newseg) for seg in segs[exclude_first:-1]): continue
find_polygons(pts + [newpt], segs + [newseg], (xoff,yoff), vecs2)
start = time.time()
find_polygons([(0,0)], [], (99,1), vecs)
print(len(solutions))
end = time.time()
print(end - start)
maxdist = max(max(max(abs(x),abs(y)) for x,y in pts) for pts in solutions)
print([pts[:0:-1] for pts in solutions if any(maxdist in pt or -maxdist in pt for pt in pts)])
maxdist2 = max(max(x*x+y*y for x,y in pts) for pts in solutions)
print([pts[:0:-1] for pts in solutions if any(x*x+y*y==maxdist2 for x,y in pts)])
In total, the program found
681 distinct paths modulo reflection and rotation.
According to the program, the answer to Q1 is
there are three paths that achieve distance of 44 from y-axis (which can be reflected by the line y=x to get the same distance from x-axis), which are:
[(0, 0), (0, 1), (2, 1), (2, 4), (6, 4), (9, 8), (9, 14), (16, 14), (16, 6), (25, 6), (33, 12), (44, 12), (44, 0), (39, -12), (25, -12), (16, 0)]
[(0, 0), (0, 1), (2, 1), (2, 4), (6, 4), (10, 1), (16, 1), (16, 8), (24, 8), (24, 17), (32, 11), (32, 0), (44, 0), (39, -12), (25, -12), (16, 0)]
[(0, 0), (0, 1), (2, 1), (2, 4), (6, 4), (10, 7), (16, 7), (16, 14), (24, 14), (24, 5), (32, 11), (32, 0), (44, 0), (39, -12), (25, -12), (16, 0)]
and the answer to Q2 is
there is only one path that achieves squared distance 372+332=2458 (sqrt(2458) ~ 49.578) from the origin, which is:
[(0, 0), (0, 1), (2, 1), (2, 4), (6, 4), (6, 9), (12, 9), (12, 16), (20, 16), (20, 25), (26, 33), (37, 33), (37, 21), (42, 9), (28, 9), (16, 0)]