pythoncircular-listmodular-arithmetic

Finding whether 2 indices are adjacent in circular list


Say I have a circular list which would look like this to a human:

enter image description here

How can I determine whether two indices are adjacent please?

So far I have:

def is_next_to(a, b):
    if a == b:
        return False
    return abs(a - b) == 1
    
    
assert is_next_to(1, 1) is False
assert is_next_to(1, 2) is True
assert is_next_to(0, 1) is True
assert is_next_to(5, 0) is True
assert is_next_to(4, 3) is True
assert is_next_to(3, 4) is True

Do I need to make special cases for (0, 5) or (5, 0), or is there some way to use modular arithmetic to solve this?


Solution

  • In a circle of 6, the number 5 is a neighbor of 0, but in a circle of 8, the number 5 would not be a neighbor of 0. So you can only reliable determine this when you know the size of the circle: this should be an extra parameter to your function.

    Once you have that, you can use this:

    def is_next_to(n, a, b):
        return abs(a - b) == 1 or a + b == n - 1
    
        
    n = 6    
    assert is_next_to(n, 1, 1) is False
    assert is_next_to(n, 1, 2) is True
    assert is_next_to(n, 0, 1) is True
    assert is_next_to(n, 5, 0) is True
    assert is_next_to(n, 4, 3) is True
    assert is_next_to(n, 3, 4) is True
    

    With modular arithmetic it would look like this:

        return (a + 1) % n == b or (b + 1) % n == a 
    

    or:

        return (a - b) % n in (1, n - 1)