Search code examples
pythonarrayscircular-buffercircular-list

Calculate the distances between elements in a circular array


people = ["James","COP","George","COP","Sam","Mac","Johnny","Karina"]

cops = [(idx+1) for idx, val in enumerate(people) if val == "COP"]  #cops' positions
peoplePositions = [(x+1) for x in range(len(people))] #index positions
distances = []
for x in peoplePositions:
    for y in cops:
        distances.append(abs(x-y))

#the output would be "Johnny" 

Hello, guys! I'm working on this question and basically I have a list with some people/objects that is actually a circular table, i.e., its head it is connected to its tail. Now I want to take the distance (of index positions) between the "COPs" and people, then output who got the maximum distance from the "COPs". In case all of them got the same distance, the output must be all of them.

This is my code and in the end I got the distances between all the people and the "COPs". I thought about making a nested loop through the distances with a range of len(peoplePositions) and a range of len(cops), but I had no progress.


Solution

  • You need to compute the minimum distance from each person to each COP. This can be computed as:

    min((p - c) % l, (c - p) % l)
    

    where p is the index of the person, c is the index of the COP and l the length of the array. Then you can compute the minimum of those distances to get the minimum distance from a person to any of the COPs. You can then compute the maximum of those values, and filter the people array based on their distance being equal to the maximum:

    people = ["James","COP","George","COP","Sam","Mac","Johnny","Karina"]
    cops = [idx for idx, val in enumerate(people) if val == "COP"]
    l = len(people)
    distances = [min(min((p - c) % l, (c - p) % l) for c in cops) for p in range(l)]
    maxd = max(distances)
    pmax = [p for i, p in enumerate(people) if distances[i] == maxd]
    print(pmax)
    

    Output:

    ['Johnny']