If you use Google Maps1 to look up a route between two points $$p_0$$ and $$p_n$$, the itinerary is given as a sequence of intermediate points \[p_0, p_1, p_2, \ldots, p_n\] If we write the distance between two consecutive points $$p_i$$ and $$p_{i+1}$$ as $$d(p_i, p_{i+1})$$, the total distance of the route equals \[\sum_{i=0}^{n - 1} d(p_i, p_{i+1})\] If the route ends back in its starting point, we finally also have to add the distance $$d(p_n, p_0)$$.

In this assignment, we represent the coordinates of a point $$p$$ as a tuple $$(x, y)$$. Based on this representation, the distance between two points $$p_a = (x_a, y_a)$$ and $$p_b = (x_b, y_b)$$ can be defined in different ways. The most intuitive distance is the Euclidean distance, that corresponds with the distance as the crow flies. In practice, however, this distance isn't always as useful.

The Manhattan-distance is an alternative distance that gets its name from the typical street pattern of Manhattan2. There, all streets are either perpendicular or parallel to each other. The Manhattan-distance is given as the sum of the absolute difference of the $$x$$-coordinates and the absolute difference of the $$y$$-coordinates. This is equal to the road you would take from one point to another if you were only allowed to walk parallel with the $$x$$-axis and the $$y$$-axis.

The Chebyshev distance or chessboard distance gets its name from the fact that it corresponds with the amount of moves the chess piece king needs to cross a discrete grid. This distance is given by the maximum of the absolute difference of the $$x$$-coordinates and the absolute difference of the $$y$$-coordinates.

The table below gives an overview of the different formulas for the distance between two points $$(x_a, y_a)$$ en $$(x_b, y_b)$$ as defined by the distance measures above.

name formula
Euclidian distance $$\sqrt{(x_a-x_b)^2 + (y_a-y_b)^2}$$
Manhattan distance $$|x_a-x_b| + |y_a-y_b|$$
Chess board distance $$\max(|x_a-x_b|,|y_a-y_b|)$$

Preparation

In Python, functions are themselves objects, so that they can be used just like any other object. In particular, you can assign functions to variables or pass them as arguments to other functions. Take a look at the following three functions definitions.

def repeat(value, function, iterations):
    for i in range(iterations):
        value = function(value)
    return value

def increment(value):
    return value + 1

def decrement(value):
    return value - 1

Below you find an example of how these functions can be used. Verify how Python responds if you execute these instructions in succession in an interactive Python session in which you first define the above functions. Make sure you understand why you obtain a certain value and what happens exactly in the interactive session before moving on to the actual assignment.

>>> increment(5)
>>> decrement(101)
>>> repeat(5, increment, 3)
>>> repeat(5, decrement, 3)
>>> repeat(5, decrement, increment(3))

Assignment

We represent a point as a tuple containing two real valued numbers (float) that respectively indicate the $$x$$ and $$y$$ coordinates of a point in a plane. Your task:

Example

>>> euclidean((42.36, 56.78), (125.65, 236.47))
198.05484139500354
>>> manhattan((42.36, 56.78), (125.65, 236.47))
262.98
>>> chessboard((42.36, 56.78), (125.65, 236.47))
179.69

>>> route([(6.59, 6.73), (4.59, 5.54), (5.33, -13.98)])
21.861273201261746
>>> route(cycle=True, points=[(6.59, 6.73), (4.59, 5.54), (5.33, -13.98)])
42.60956710702662
>>> route([(6.59, 6.73), (4.59, 5.54), (5.33, -13.98)], distance=manhattan)
23.45
>>> route([(6.59, 6.73), (4.59, 5.54), (5.33, -13.98)], cycle=True, distance=manhattan)
45.42