Делая это в 1D, я бы попытался найти самое большое совпадение во второй коллекции для каждого индекса в первой коллекции. Если матч подходит к концу, у меня есть совпадение (как в действии ион и ион луч).
match( A on B ):
for each i in length(A):
see if A[i..] matches B[0..]
if no match found: do the same for B on A.
Для 2D вы делаете то же самое, в основном: находите «ребро» A, которое перекрывается с противоположным ребром B. Только ребра не 1D, но 2D:
for each point xa,ya in A:
find a row yb in B that has a match( A[ya] on B[yb] )
see if A[ya..] matches B[yb..]
Вы должны сделать это для 2 диагоналей, в каждом смысле.