Located in Texas' northwest corner, the town of Dalhart is closer to six other state capitals than to Texas' own capital Austin. As the crow flies, Dalhart is 306 kilometers from Santa Fe, 432 kilometers from Denver, 464 kilometers from Oklahoma City, 606 kilometers from Cheyenne, 684 kilometers from Topeka and 738 kilometers from Lincoln, but it is 786 kilometers from Austin.
The United States consists of fifty states that have a certain operational autonomy from the US federal government. Each state has its own state capital. In order to avoid confusion due to the fact that some US cities share the same name, place names are usually associated with the state in which they are located. We will indicate cities always with the name of the city, followed by a comma and the two-letter abbreviation of the state in which the city is located (for example: Austin,TX).
Since some states have more than one occurrence of the same place name, it is even less ambiguous to indicate places with their location. We represent the coordinates where a city is located as a tuple $$(b, l)$$ ($$b, l \in \mathbb{R}, -90 < b \leq 90, -180 < l \leq 180$$), where $$b$$ (int) indicates the latitude and $$l$$ (int) the longitude, both expressed in decimal degrees.
For a given city, we are looking for the all state capitals of US states that are closer to the city than the state capital of its own state. In order to do so, we proceed as follows:
Write a function capitals that takes the location (str) of a text file. This file must contain the list of all capitals, with the name of each city on a separate line, followed by a comma and the two-letter abbreviation of the state in which the city is located. The function must return a dictionary (dict) that maps the two-letter abbreviation (str) of each state onto the name (str) of its state capital.
Write a function coordinates that takes the location (str) of a text file. This file must contain a list of cities, with each line containing the following information fields on a single city, separated from each other using comma's: i) name, ii) two-letter abbreviation of the state, iii) latitude, en iv) longitude. The function must return a dictionary (dict) that maps each city (str) onto its coordinate $$(b, l)$$.
Write a function great_circle_distance that takes two coordinates $$(b_1, l_1)$$ en $$(b_2, l_2)$$. The function must return the great-circle distance (float) between the two given coordinates. It represents the distance between two points on a sphere, and is computed according to the following formula \[d = r \cdot \arccos(\sin(b_1) \cdot \sin(b_2) + \cos(b_1)\cdot \cos(b_2) \cdot \cos(l_1 - l_2))\] Here, $$r$$ represents the radius of the sphere. The function must consider Earth as a sphere with radius $$r = 6371\mbox{ km}$$, which expresses the distance in kilometer.
All trigonometric functions in the math module take angles expressed in radians. Since the original latitudes and longitudes are expresses in decimal degrees, they must be converted into radians. The math module contains a function that computes this conversion.
Use the function great_circle_distance to write a function close_neighbours that takes three arguments: i) a city (str), ii) a dictionary (dict) that maps the two-letter abbreviation (str) of each state onto the name (str) of its state capital, and iii) a dictionary (dict) that maps each city (str) onto its coordinate $$(b, l)$$. The function must return a set containing all state capitals (str) that are closer to the given city than its own state capital.
In the following interactive session, we assume the text files capitals.txt1 and cities.txt2 to be located in the current directory.
>>> capital = capitals('capitals.txt3')
>>> capital['TX']
'Austin'
>>> capital['NE']
'Lincoln'
>>> coordinate = coordinates('cities.txt4')
>>> coordinate['Dalhart,TX']
(36.1173, -102.6024)
>>> coordinate['Austin,TX']
(30.352, -97.7151)
>>> coordinate['Lincoln,NE']
(40.908, -96.7103)
>>> great_circle_distance((36.1173, -102.6024), (30.352, -97.7151)) # Dalhart,TX <-> Austin,TX
785.5925593169209
>>> great_circle_distance((36.1173, -102.6024), (40.908, -96.7103)) # Dalhart,TX <-> Lincoln,NE
738.9516485722722
>>> close_neighbours('Dalhart,TX', capital, coordinate)
{'Cheyenne,WY', 'Oklahoma City,OK', 'Topeka,KS', 'Santa Fe,NM', 'Lincoln,NE', 'Denver,CO'}
The small town Green River in the state Wyoming is certainly neighborly: when NASA determined in 1994 that up to six meteors might strike Jupiter, Green River's city council designated an airstrip south of town as the Greater Green River Intergalactic Spaceport. They asked NASA to broadcast the news to any fleeing Jovians and warned residents to
… prepare themselves to make welcome any refugees who might cast themselves upon our mercy.
Mayor George Eckman told the Rock Springs Rocket-Miner
I feel it is a gesture that could be made and should be made by someone on the planet Earth to fellow citizens of the solar system.
The two council members who opposed the resolution pointed out that the region already has a problem with illegal aliens and noted the local housing shortage. But the mile-long runway remains open.