-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday07.nim
59 lines (44 loc) · 1.59 KB
/
day07.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import strscans, heapqueue, tables
let input = "./inputs/07.txt"
var
predecessors = initTable[char, set[char]]()
successors = initTable[char, set[char]]()
availableAtStart = initHeapQueue[char]()
for line in input.lines:
var before, after: string
if line.scanf("Step $w must be finished before step $w can begin.", before, after):
let (a, b) = (after[0], before[0])
if not predecessors.hasKey(a): predecessors[a] = {}
if not successors.hasKey(b): successors[b] = {}
predecessors[a].incl b
successors[b].incl a
for letter in {'A' .. 'Z'}:
if not predecessors.hasKey(letter):
availableAtStart.push letter
proc solve(workers: int): (string, int) =
var
remainingPredecessors = predecessors
availableLetters = availableAtStart
availableWorkers = workers
workingQueue = initHeapQueue[(int, char)]()
proc processingTime(x: char): int =
if availableWorkers == 1: 0 else: ord(x) - 4
proc getBusy(time = 0) =
while availableLetters.len > 0 and availableWorkers > 0:
dec availableWorkers
let currentLetter = availableLetters.pop
workingQueue.push (time + currentLetter.processingTime, currentLetter)
getBusy()
while workingQueue.len > 0:
let (currentTime, letter) = workingQueue.pop
inc availableWorkers
result[0].add letter
result[1] = currentTime
if not successors.hasKey(letter): break
for s in successors[letter]:
remainingPredecessors[s].excl letter
if remainingPredecessors[s].card == 0:
availableLetters.push s
getBusy(currentTime)
echo solve(workers = 1)[0]
echo solve(workers = 5)[1]