Solution to problem 7 in Python
This commit is contained in:
parent
7c688d4162
commit
1613813d7a
@ -60,6 +60,8 @@
|
|||||||
|
|
||||||
# In what order should the steps in your instructions be completed?
|
# In what order should the steps in your instructions be completed?
|
||||||
|
|
||||||
|
from string import ascii_uppercase
|
||||||
|
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
with open("files/P7.txt") as f:
|
with open("files/P7.txt") as f:
|
||||||
@ -76,5 +78,86 @@ def part_1() -> None:
|
|||||||
print(f"The correct order will be {order}")
|
print(f"The correct order will be {order}")
|
||||||
|
|
||||||
|
|
||||||
|
# --- Part Two ---
|
||||||
|
|
||||||
|
# As you're about to begin construction, four of the Elves offer to help. "The
|
||||||
|
# sun will set soon; it'll go faster if we work together." Now, you need to
|
||||||
|
# account for multiple people working on steps simultaneously. If multiple
|
||||||
|
# steps are available, workers should still begin them in alphabetical order.
|
||||||
|
|
||||||
|
# Each step takes 60 seconds plus an amount corresponding to its letter: A=1,
|
||||||
|
# B=2, C=3, and so on. So, step A takes 60+1=61 seconds, while step Z takes
|
||||||
|
# 60+26=86 seconds. No time is required between steps.
|
||||||
|
|
||||||
|
# To simplify things for the example, however, suppose you only have help from
|
||||||
|
# one Elf (a total of two workers) and that each step takes 60 fewer seconds
|
||||||
|
# (so that step A takes 1 second and step Z takes 26 seconds). Then, using the
|
||||||
|
# same instructions as above, this is how each second would be spent:
|
||||||
|
|
||||||
|
# Second Worker 1 Worker 2 Done
|
||||||
|
# 0 C .
|
||||||
|
# 1 C .
|
||||||
|
# 2 C .
|
||||||
|
# 3 A F C
|
||||||
|
# 4 B F CA
|
||||||
|
# 5 B F CA
|
||||||
|
# 6 D F CAB
|
||||||
|
# 7 D F CAB
|
||||||
|
# 8 D F CAB
|
||||||
|
# 9 D . CABF
|
||||||
|
# 10 E . CABFD
|
||||||
|
# 11 E . CABFD
|
||||||
|
# 12 E . CABFD
|
||||||
|
# 13 E . CABFD
|
||||||
|
# 14 E . CABFD
|
||||||
|
# 15 . . CABFDE
|
||||||
|
|
||||||
|
# Each row represents one second of time. The Second column identifies how many
|
||||||
|
# seconds have passed as of the beginning of that second. Each worker column
|
||||||
|
# shows the step that worker is currently doing (or . if they are idle). The
|
||||||
|
# Done column shows completed steps.
|
||||||
|
|
||||||
|
# Note that the order of the steps has changed; this is because steps now take
|
||||||
|
# time to finish and multiple workers can begin multiple steps simultaneously.
|
||||||
|
|
||||||
|
# In this example, it would take 15 seconds for two workers to complete these
|
||||||
|
# steps.
|
||||||
|
|
||||||
|
# With 5 workers and the 60+ second step durations described above, how long
|
||||||
|
# will it take to complete all of the steps?
|
||||||
|
|
||||||
|
|
||||||
|
def part_2() -> None:
|
||||||
|
G = nx.DiGraph()
|
||||||
|
for step in steps:
|
||||||
|
parent, child = step[5:6], step[36:37]
|
||||||
|
G.add_edge(parent, child)
|
||||||
|
|
||||||
|
n_workers = 5
|
||||||
|
|
||||||
|
# Add amount of work for each node
|
||||||
|
for node in G.nodes:
|
||||||
|
G.nodes[node]["work"] = 61 + ord(node) - ord("A")
|
||||||
|
|
||||||
|
time = 0
|
||||||
|
while G.nodes:
|
||||||
|
# Find nodes available for work
|
||||||
|
available_nodes = [node for node in G.nodes if G.in_degree(node) == 0]
|
||||||
|
# Sort available nodes: Work on nodes with least remaining work
|
||||||
|
available_nodes.sort(key=lambda node: G.nodes[node]["work"])
|
||||||
|
|
||||||
|
# Reduce remaining work for n_workers of the available nodes
|
||||||
|
for worker, node in zip(range(n_workers), available_nodes):
|
||||||
|
G.nodes[node]["work"] -= 1
|
||||||
|
# Remove finished nodes
|
||||||
|
if G.nodes[node]["work"] == 0:
|
||||||
|
G.remove_node(node)
|
||||||
|
|
||||||
|
time += 1
|
||||||
|
|
||||||
|
print(f"Finishing all the work took {time} seconds")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
part_1()
|
part_1()
|
||||||
|
part_2()
|
||||||
|
Loading…
Reference in New Issue
Block a user