Solution to problem 6 in Python
This commit is contained in:
parent
4e8696a16e
commit
faaba83daf
@ -30,6 +30,11 @@ force_grid_wrap = 0
|
||||
use_parentheses = true
|
||||
line_length = 79
|
||||
|
||||
[tool.mypy]
|
||||
pretty = true
|
||||
show_traceback = true
|
||||
allow_redefinition = true
|
||||
|
||||
[tool.black]
|
||||
line-length = 79
|
||||
target-version = ['py38']
|
||||
@ -53,8 +58,3 @@ exclude = '''
|
||||
# the root of the project
|
||||
)
|
||||
'''
|
||||
|
||||
[tool.mypy]
|
||||
pretty = true
|
||||
show-traceback = true
|
||||
allow-redefinition = true
|
||||
|
@ -70,6 +70,7 @@
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
with open("files/P6.txt") as f:
|
||||
orbits = [line for line in f.read().strip().split()]
|
||||
@ -90,8 +91,105 @@ def part_1():
|
||||
|
||||
total_orbits = count_orbits(universe, "COM", 0, 0)
|
||||
|
||||
print(f"There are {total_orbits} in our universe")
|
||||
print(f"There are {total_orbits} orbits in our universe")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# Now, you just need to figure out how many orbital transfers you (YOU) need to\
|
||||
# take to get to Santa (SAN).
|
||||
|
||||
# You start at the object YOU are orbiting; your destination is the object SAN
|
||||
# is orbiting. An orbital transfer lets you move from any object to an object
|
||||
# orbiting or orbited by that object.
|
||||
|
||||
# For example, suppose you have the following map:
|
||||
|
||||
# COM)B
|
||||
# B)C
|
||||
# C)D
|
||||
# D)E
|
||||
# E)F
|
||||
# B)G
|
||||
# G)H
|
||||
# D)I
|
||||
# E)J
|
||||
# J)K
|
||||
# K)L
|
||||
# K)YOU
|
||||
# I)SAN
|
||||
|
||||
# Visually, the above map of orbits looks like this:
|
||||
|
||||
# YOU
|
||||
# /
|
||||
# G - H J - K - L
|
||||
# / /
|
||||
# COM - B - C - D - E - F
|
||||
# \
|
||||
# I - SAN
|
||||
|
||||
# In this example, YOU are in orbit around K, and SAN is in orbit around I.
|
||||
# To move from K to I, a minimum of 4 orbital transfers are required:
|
||||
|
||||
# K to J
|
||||
# J to E
|
||||
# E to D
|
||||
# D to I
|
||||
|
||||
# Afterward, the map of orbits looks like this:
|
||||
|
||||
# G - H J - K - L
|
||||
# / /
|
||||
# COM - B - C - D - E - F
|
||||
# \
|
||||
# I - SAN
|
||||
# \
|
||||
# YOU
|
||||
|
||||
# What is the minimum number of orbital transfers required to move from the
|
||||
# object YOU are orbiting to the object SAN is orbiting? (Between the objects
|
||||
# they are orbiting - not between YOU and SAN.)
|
||||
|
||||
|
||||
def get_all_orbits(node: str, universe: Dict[str, str]) -> List[str]:
|
||||
orbits = []
|
||||
while node in universe:
|
||||
node = universe[node]
|
||||
orbits.append(node)
|
||||
return orbits
|
||||
|
||||
|
||||
def common_orbit(node_a: List[str], node_b: List[str]) -> Optional[str]:
|
||||
for orbit in node_a:
|
||||
if orbit in node_b:
|
||||
return orbit
|
||||
return None
|
||||
|
||||
|
||||
def distance_from(node_a: List[str], node_b: Optional[str]) -> int:
|
||||
transfers = 0
|
||||
for v in node_a:
|
||||
if v == node_b:
|
||||
return transfers
|
||||
transfers += 1
|
||||
return transfers
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
universe = {}
|
||||
for orbit in orbits:
|
||||
planet, satellite = orbit.split(")")
|
||||
universe[satellite] = planet
|
||||
|
||||
you = get_all_orbits("YOU", universe)
|
||||
san = get_all_orbits("SAN", universe)
|
||||
_common = common_orbit(you, san)
|
||||
transfers = distance_from(you, _common) + distance_from(san, _common)
|
||||
|
||||
print(f"There will be at least {transfers} orbital transfers")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
||||
|
Loading…
Reference in New Issue
Block a user