Last active
October 20, 2024 16:44
-
-
Save TimelessP/f1124f7c1556d0b614c4871757287885 to your computer and use it in GitHub Desktop.
Final Bearing challenge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
"Final Bearing" is AI reasoning, mathematics and geometry challenge created by Timeless Prototype (@TimelessP on X) - a citizen scientist under a pseudonym. | |
Challenge Author: @TimelessP (on X) | |
Challenge Date: 2024-09-19 22:07:32 | |
Challenge Description: (see the prompt example below) | |
Gist URL: https://gist.github.com/TimelessP/f1124f7c1556d0b614c4871757287885 | |
--- | |
Solution Metadata | |
Solution Author: [Your Name Here] | |
Solution Date: [YYYY-MM-DD] | |
Solution Version: [v1.0] | |
--- | |
Prompt Example: | |
A starting prompt to explain the goal, but, most importantly, a solution function must pass the given unit tests: | |
Okay, let's step it up. I need a python function written as per the following requirements: A function that takes parameters start_lat_deg, start_lon_deg (as floats), start_bearing_deg, and the final parameter is a fraction of 1.0, where 1.0 is the full distance around the great circle of a sphere to travel. So, 0.25 takes you a quarter of the way around the great circle. The function will calculate the bearing at the destination as you've travelled in that direction around the great circle. The end_bearing, end_lat, end_lon will be returned. Assume it's a perfect sphere, and polar north and magnetic north are in the same position (i.e. we want a simple sphere model here to find the final bearing at the destination). | |
""" | |
import math | |
def great_circle_navigation_perfect(start_lat_deg, start_lon_deg, start_bearing_deg, fraction): | |
""" | |
Computes the final latitude, longitude, and bearing after travelling a certain fraction | |
around a great circle of a perfect sphere from a starting point with a given initial bearing. | |
Parameters: | |
start_lat_deg (float): Starting latitude in degrees (-90.0 to 90.0), positive north. | |
start_lon_deg (float): Starting longitude in degrees (-180.0 to 180.0), positive east. | |
start_bearing_deg (float): Initial bearing in degrees (0.0 to 360.0), measured clockwise from north. | |
fraction (float): Fraction of the great circle to travel (from 0.0 to 1.0). | |
A fraction of 1.0 corresponds to a full circumnavigation. | |
Returns: | |
(float, float, float): Tuple containing the final latitude, longitude, and bearing in degrees. | |
The latitude is between -90.0 and 90.0 degrees. | |
The longitude is between -180.0 and 180.0 degrees. | |
The bearing is between 0.0 and 360.0 degrees. | |
""" | |
# TODO: Write the solution code here. | |
return end_lat_deg, end_long_deg, end_bearing_deg | |
def test_great_circle_navigation(): | |
""" | |
Unit tests to check if the function is performing as expected. | |
""" | |
# Helper function for almost equal comparison. | |
def almost_equal(val1, val2, tol=1e-4): | |
return math.isclose(val1, val2, abs_tol=tol) | |
# Test Case 1: Start at 0, 0 with a bearing of 0, travelling 25% around the circle. | |
result1 = great_circle_navigation_perfect(0, 0, 0, 0.25) | |
print(f"1. expected (90, 0, 0), actual {result1=}") | |
assert almost_equal(result1[0], 90.0) and almost_equal(result1[1], 0.0) and almost_equal(result1[2], 0.0), "Test Case 1 Failed" | |
# Test Case 2: Start at 0, 0 with a bearing of 45, travelling 25% around the circle. | |
result2 = great_circle_navigation_perfect(0, 0, 45.0, 0.25) | |
print(f"2. expected (45, 90, 90), actual {result2=}") | |
assert almost_equal(result2[0], 45.0) and almost_equal(result2[1], 90.0) and almost_equal(result2[2], 90.0), "Test Case 2 Failed" | |
# Test Case 3: Start at 0, 0 with a bearing of 45, travelling 75% around the circle. | |
result3 = great_circle_navigation_perfect(0, 0, 45.0, 0.75) | |
print(f"3. expected (-45, -90, 90), actual {result3=}") | |
assert almost_equal(result3[0], -45.0) and almost_equal(result3[1], -90.0) and almost_equal(result3[2], 90.0), "Test Case 3 Failed" | |
# Test Case 4: Start at 0, 0 with a bearing of 45, travelling halfway around the circle. | |
expected_bearing = (45 + 90) % 360 # Final bearing should be 45 + 90 = 135 degrees | |
result4 = great_circle_navigation_perfect(0, 0, 45.0, 0.5) | |
print(f"4. expected (0, 180, 135), actual {result4=}") | |
assert almost_equal(result4[0], 0.0) and (almost_equal(result4[1], 180.0) or almost_equal(result4[1], -180.0)) and almost_equal(result4[2], expected_bearing), "Test Case 4 Failed" | |
# Test Case 5: Start at 0, 0 with a bearing of 45, travelling all the way around the circle. | |
result5 = great_circle_navigation_perfect(0, 0, 45.0, 1.0) | |
print(f"5. expected (0, 0, 45), actual {result5=}") | |
assert almost_equal(result5[0], 0.0) and almost_equal(result5[1], 0.0) and almost_equal(result5[2], 45.0), "Test Case 5 Failed" | |
print("All test cases passed! Please double check that the unit tests were not modified in the process.") | |
if __name__ == "__main__": | |
# Run the tests | |
test_great_circle_navigation() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment