Question: By rotating 2 lists either from left to right, Find the smallest possible sum of the absolute value of the differences between each corresponding item in the two lists given they're the same length. Rotation Sample: List [0, 1, 2, 3, 4, 5] rotated to the left = [1, 2, 3, 4, 5, 0] List [0, 1, 2, 3, 4, 5] rotated to the right= [5, 0, 1, 2, 3, 4]  Sum of Absolute Difference: List 1 = [1, 2, 3, 4] List 2 = [5, 6, 7, 8] Sum of Abs. Diff. = |1-5| + |2-6| + |3-7| + |4-8| = 16  Once again, for any arbitrary length of list and integer values, task is to look for the least possible sum by simply rotating to the left/right of either or both lists. I had no problem with the rotation and acquiring of the minimum sum of absolute difference. I just want to know the smarter approach since my algorithm checks for every possible combination which is quite slow. Here is my bruteforce approach: list1 = [45, 21, 64, 33, 49] list2 = [90, 12, 77, 52, 28] choices = [] # Put all possible sums into a list to find the minimum value. for j in range(len(list1)): # List1 does a full rotation total = 0 for k in range(len(list1)): total += abs(list1[k] - list2[k]) list1.append(list1.pop(0)) choices.append(total) print(min(choices))  What's a smarter approach? I would appreciate a shorter code and time complexity as well. I managed to make it faster by applying generators. Credits to @kuriboh for the idea! But since I'm still new in generator implementation, just want to know if this is the best way of implementing it to reduce my time complexity especially for my loop. Can we still go faster than this configuration? list1 = [45, 21, 64, 33, 49] list2 = [90, 12, 77, 52, 28] choices = [] l = len(list1) for j in range(l): total = sum([abs(int(list1[k])-int(list2[k])) for k in range(l)]) list1.append(list1.pop(0)) choices.append(total) print(min(choices)) 

Answer: I haven't cracked the full problem, but in the special case where the input values are all 0 or 1 (or any two different values, or any of O(1) different values, but we'll need another idea to get much further than that), we can get an O(n log n)-time algorithm by applying fast convolution. The idea is to compute all of the sums of absolute differences as List1 * reverse(1 - List2) + (1 - List1) * reverse(List2) where 1 - List means doing that operation point-wise and * denotes circular convolution (computable in time O(n log n) using a pair of FFTs). The definition of circular convolution here is  n-1 __ \ (f * g)(i) = /_ f(j) g((i - j) mod n). j=0  Substituting List1 for f and reverse(1 - List2) for g, we get  n-1 __ \ (List1 * reverse(1 - List2))(i) = /_ List1(j) (1 - List2((n-1-(i-j)) mod n)) j=0 n-1 __ \ = /_ List1(j) (1 - List2((j-(i+1)) mod n)). j=0  The product List1(j) (1 - List2((j-(i+1)) mod n)) is 1 if and only if List1(j) = 1 and List2((j-(i+1)) mod n) = 0, and 0 otherwise. Thus the i value of the convolution counts the number of places where List1 has a 1 offset i+1 circularly to the left of where List2 has a 0. The other convolution counts 0s corresponding to 1s. Given our input restrictions, this is the sum of absolute differences. Code: import numpy def convolve_circularly(a1, a2): return numpy.round(numpy.abs(numpy.fft.ifft(numpy.fft.fft(a1) * numpy.fft.fft(a2)))) def min_sum_abs_diff(a1, a2): a1 = numpy.array(a1) a2 = numpy.array(a2)[::-1] return numpy.min(convolve_circularly(a1, 1 - a2) + convolve_circularly(1 - a1, a2)) def slow_min_sum_abs_diff(a1, a2): return min( sum(abs(a1[i] - a2[i - k]) for i in range(len(a1))) for k in range(len(a2)) ) def main(): n = 100 for r in range(100000): a1 = numpy.random.randint(2, size=n) a2 = numpy.random.randint(2, size=n) r = min_sum_abs_diff(a1, a2) slow_r = slow_min_sum_abs_diff(a1, a2) if r != slow_r: print(a1, a2, r, slow_r) break if __name__ == "__main__": main()