Solution to problem 6 in Python

This commit is contained in:
David Doblas Jiménez 2022-03-10 10:11:20 +01:00
parent 4e8696a16e
commit faaba83daf
2 changed files with 104 additions and 6 deletions

View File

@ -30,6 +30,11 @@ force_grid_wrap = 0
use_parentheses = true use_parentheses = true
line_length = 79 line_length = 79
[tool.mypy]
pretty = true
show_traceback = true
allow_redefinition = true
[tool.black] [tool.black]
line-length = 79 line-length = 79
target-version = ['py38'] target-version = ['py38']
@ -53,8 +58,3 @@ exclude = '''
# the root of the project # the root of the project
) )
''' '''
[tool.mypy]
pretty = true
show-traceback = true
allow-redefinition = true

View File

@ -70,6 +70,7 @@
from collections import defaultdict from collections import defaultdict
from typing import Dict, List, Optional
with open("files/P6.txt") as f: with open("files/P6.txt") as f:
orbits = [line for line in f.read().strip().split()] orbits = [line for line in f.read().strip().split()]
@ -90,8 +91,105 @@ def part_1():
total_orbits = count_orbits(universe, "COM", 0, 0) 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__": if __name__ == "__main__":
part_1() part_1()
part_2()