Created
June 6, 2021 15:33
-
-
Save toritsejuFO/c4a5060113b04150440ded962b6d36a6 to your computer and use it in GitHub Desktop.
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
def transform_to_lower(road_map): | |
'''Helper function to transform map to lower case''' | |
road_map_lower_cased = {} | |
for key in road_map.keys(): | |
road_map_lower_cased[key.lower()] = [subKey.lower() for subKey in road_map[key]] | |
return road_map_lower_cased | |
def pop(previous_points): | |
'''Helper function | |
A wrapper to ensure we only pop from when | |
previous points when there is a value to pop | |
''' | |
if previous_points and len(previous_points) > 0: | |
previous_points.pop() | |
def is_cyclic(initial_point, current_point, current_iteration, road_map, previous_points): | |
'''Helper function to perform cyclic check recursively''' | |
# Keep track of results of inner cyclic checks | |
result = [] | |
# If the current point we are, is a point we've been to before, | |
# and it isn't our starting point, then we're going in a smaller inner cycle. | |
# In this case return true because we've discovered a cycle, though an inner one. | |
if current_point in previous_points and current_point != initial_point: | |
pop(previous_points) | |
return True | |
# Keep track of previous points passed (track previous paths taken) | |
if current_iteration != 0: | |
previous_points.append(current_point) | |
# Return true if we get back back to our initial points | |
if (initial_point == current_point) and (current_iteration != 0): | |
pop(previous_points) | |
return True | |
else: # Check if any inner path is cyclic | |
for point in road_map[current_point]: | |
if point in road_map.keys(): | |
result.append(is_cyclic(initial_point, point, current_iteration + 1, road_map, previous_points)) | |
if True in result: | |
pop(previous_points) | |
return True | |
else: | |
pop(previous_points) | |
return False | |
def is_there_cycle(road_map): | |
'''Main Function | |
This solution uses recursion to meet the requirements. | |
The solution also tries to behave wisely as to the requirements. | |
It returns true on the first cyclic path it finds, thereby | |
avoiding having to go through all paths first before confirming | |
it's findings. | |
''' | |
# Validate map | |
if road_map == None or type(road_map) != dict or len(road_map.keys()) < 1: | |
return False | |
# Transform to lowercase first to avoid key indexing errors | |
road_map_lower_cased = transform_to_lower(road_map) | |
for point in road_map_lower_cased.keys(): | |
if is_cyclic(point, point, 0, road_map_lower_cased, []): | |
return True | |
return False | |
if __name__ == '__main__': | |
road_map = { | |
'A': ['B', 'C'], | |
'B': ['A'], | |
'C': ['B'] | |
} | |
answer = is_there_cycle(road_map) | |
print(answer) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello @toritsejuFO, congratulations 🎉 your solution has been selected as one of the winning for in Week 9 of #AlgorithmFridays. Your solution is clean and passed all the test cases.
You will be contacted within 24 - 48 hours to receive your award.