-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
106 lines (93 loc) · 1.98 KB
/
main.go
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
package main
import (
"io"
"github.com/teivah/go-aoc"
)
func fs1(input io.Reader) int {
groups := aoc.StringGroups(aoc.ReaderToStrings(input))
before, after := dep(groups[0])
res := 0
for _, line := range groups[1] {
res += correctOrder(before, after, line)
}
return res
}
func dep(lines []string) (map[int]map[int]bool, map[int]map[int]bool) {
before := make(map[int]map[int]bool)
after := make(map[int]map[int]bool)
for _, line := range lines {
del := aoc.NewDelimiter(line, "|")
src := del.GetInt(0)
dst := del.GetInt(1)
aoc.InnerMapGet(before, src)[dst] = true
aoc.InnerMapGet(after, dst)[src] = true
}
return before, after
}
func correctOrder(before, after map[int]map[int]bool, line string) int {
del := aoc.NewDelimiter(line, ",")
ints := del.GetInts()
for i := 0; i < len(ints); i++ {
for j := i + 1; j < len(ints); j++ {
x := ints[i]
y := ints[j]
if m, ok := before[y]; ok && m[x] {
return 0
}
if m, ok := after[x]; ok && m[y] {
return 0
}
}
}
return ints[len(ints)/2]
}
func fs2(input io.Reader) int {
groups := aoc.StringGroups(aoc.ReaderToStrings(input))
before, after := dep(groups[0])
res := 0
for _, line := range groups[1] {
res += incorrectOrder(before, after, line)
}
return res
}
func incorrectOrder(before, after map[int]map[int]bool, line string) int {
del := aoc.NewDelimiter(line, ",")
ints := del.GetInts()
invalid := false
outer:
for i := 0; i < len(ints); i++ {
for j := i + 1; j < len(ints); j++ {
x := ints[i]
y := ints[j]
if m, ok := before[y]; ok && m[x] {
invalid = true
break outer
}
if m, ok := after[x]; ok && m[y] {
invalid = true
break outer
}
}
}
if !invalid {
return 0
}
for _, v := range ints {
countBefore := 0
countAfter := 0
for _, x := range ints {
if x == v {
continue
}
if before[v][x] {
countBefore++
} else if after[v][x] {
countAfter++
}
}
if countBefore == countAfter {
return v
}
}
panic("not valid")
}