Explorar o código

Implement scheduler interface with priority queue

Guillaume Koenig %!s(int64=7) %!d(string=hai) anos
pai
achega
9b73efd410
Modificáronse 2 ficheiros con 86 adicións e 0 borrados
  1. 3 0
      main.go
  2. 83 0
      prioq.go

+ 3 - 0
main.go

@@ -31,6 +31,9 @@ func solve() {
31 31
 }
32 32
 
33 33
 func main() {
34
+	var pq prioq
35
+	pq.Add(Car{0, []int{}, 2, 0, 0})
36
+
34 37
 	sample := os.Args[1]
35 38
 	fileIn := sample + ".in"
36 39
 	fileOut := sample + ".out"

+ 83 - 0
prioq.go

@@ -0,0 +1,83 @@
1
+package main
2
+
3
+// Invariant: both children are bigger
4
+
5
+type prioq struct {
6
+	bintree []Car
7
+}
8
+
9
+func (pq *prioq) Add(car Car) {
10
+	pq.bintree = append(pq.bintree, car)
11
+
12
+	// Rebalance tree to respect invariant
13
+	var i = len(pq.bintree) - 1
14
+	var p = (i - 1) / 2
15
+	for p >= 0 && pq.bintree[p].Arrival > pq.bintree[i].Arrival {
16
+		pq.bintree[p], pq.bintree[i] = pq.bintree[i], pq.bintree[p]
17
+		i = p
18
+		p = (i - 1) / 2
19
+	}
20
+}
21
+
22
+func (pq *prioq) pop() Car {
23
+	if len(pq.bintree) == 0 {
24
+		panic("Trying to remove from empty queue")
25
+	}
26
+
27
+	if len(pq.bintree) == 1 {
28
+		elem := pq.bintree[0]
29
+		pq.bintree = pq.bintree[:0]
30
+		return elem
31
+	}
32
+
33
+	elem := pq.bintree[0]
34
+	// Put last element at root
35
+	pq.bintree[0] = pq.bintree[len(pq.bintree)-1]
36
+	// Remove last element
37
+	pq.bintree = pq.bintree[:len(pq.bintree)-1]
38
+
39
+	//        1                  9
40
+	//    10     9	         10     12
41
+	//  11 12   13 14  ->  11 12   13 14
42
+	// 12
43
+
44
+	// Rebalance tree to respect invariant
45
+	len := len(pq.bintree)
46
+	i, left, right := 0, 0, 0
47
+	for {
48
+		left = 2*i + 1
49
+		right = 2*i + 2
50
+		if left < len && right < len { // Two children
51
+			if pq.bintree[left].Arrival <= pq.bintree[right].Arrival {
52
+				if pq.bintree[i].Arrival <= pq.bintree[left].Arrival {
53
+					break // Inferior to both children
54
+				} else {
55
+					pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
56
+					i = left
57
+				}
58
+			} else {
59
+				if pq.bintree[i].Arrival <= pq.bintree[right].Arrival {
60
+					break // Inferior to both children
61
+				} else {
62
+					pq.bintree[i], pq.bintree[right] = pq.bintree[right], pq.bintree[i]
63
+					i = right
64
+				}
65
+			}
66
+		} else if left < len { // One child (left)
67
+			if pq.bintree[i].Arrival <= pq.bintree[left].Arrival {
68
+				break // Inferior to only child
69
+			}
70
+			pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
71
+			i = left
72
+		} else { // No child
73
+			break
74
+		}
75
+
76
+	}
77
+
78
+	return elem
79
+}
80
+
81
+func (pq *prioq) empty() bool {
82
+	return len(pq.bintree) == 0
83
+}