-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpascalcompiler.go
More file actions
124 lines (114 loc) · 2.32 KB
/
pascalcompiler.go
File metadata and controls
124 lines (114 loc) · 2.32 KB
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
const (
BLACK = iota
RED
)
func scanInt(scanner *bufio.Scanner) int {
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
return n
}
func scanString(scanner *bufio.Scanner) string {
scanner.Scan()
s := scanner.Text()
return s
}
type Node struct {
name string
color,
pas, dcu int
imports []string
}
func visit(graph map[string]*Node, source string) {
unit := graph[source]
if (unit.dcu == -1) {
unit.color = RED
}
if (unit.dcu < unit.pas) {
unit.color = RED
}
for _, dependency := range unit.imports {
if dependency == unit.name {
continue
}
if graph[dependency].color == RED || graph[dependency].dcu > unit.dcu {
unit.color = RED
}
visit(graph, dependency)
}
}
func findCycles(graph map[string]*Node) bool {
color := make(map[string]int)
var ok bool
var visit func(source string)
visit = func(source string) {
color[source] = 1
for _, dependency := range graph[source].imports {
if color[dependency] == 1 {
ok = true
}
if color[dependency] == 0 {
visit(dependency)
}
}
color[source] = 2
}
visit("main")
return ok
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
n := scanInt(scanner)
graph := make(map[string]*Node, n)
for i := 0; i < n; i++ {
source := scanString(scanner)
k := scanInt(scanner)
imports := make([]string, 0, k)
for j := 0; j < k; j++ {
dependency := scanString(scanner)
imports = append(imports, dependency)
}
graph[source] = &Node{ source, BLACK, -1, -1, imports }
}
m := scanInt(scanner)
for i := 0; i < m; i++ {
fileName := scanString(scanner)
sourceNextension := strings.Split(fileName, ".")
source, extension := sourceNextension[0], sourceNextension[1]
timestamp := scanInt(scanner)
if (extension == "pas") {
graph[source].pas = timestamp
} else {
graph[source].dcu = timestamp
}
}
writer := bufio.NewWriter(os.Stdout)
if findCycles(graph) {
fmt.Fprintln(writer, "!CYCLE")
writer.Flush()
return
}
for i := 0; i < n; i++ {
visit(graph, "main")
}
answer := make([]string, 0)
for unit := range graph {
if graph[unit].color == RED {
answer = append(answer, unit)
}
}
sort.Strings(answer)
for i := range answer {
fmt.Fprintf(writer, "%s.pas\n", answer[i])
}
writer.Flush()
}