114 lines
1.8 KiB
Go
114 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"slices"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println(doTheThing("example.txt"))
|
|
fmt.Println(doTheThing("data.txt"))
|
|
}
|
|
|
|
func fill[T any](s []T, value T) {
|
|
for i := range s {
|
|
s[i] = value
|
|
}
|
|
}
|
|
|
|
func doTheThing(fileName string) (resultPart1, resultPart2 int) {
|
|
fp, err := os.Open(fileName)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
scanner := bufio.NewScanner(fp)
|
|
forbiddenAfter := readForbiddenAfter(scanner)
|
|
seen := make([]bool, 100)
|
|
forbidden := make([]bool, 100)
|
|
|
|
for scanner.Scan() {
|
|
seq := readLine(strings.TrimSpace(scanner.Text()))
|
|
fill(seen, false)
|
|
fill(forbidden, false)
|
|
|
|
ok := true
|
|
|
|
for _, n := range seq {
|
|
if seen[n] {
|
|
continue
|
|
}
|
|
|
|
if forbidden[n] {
|
|
ok = false
|
|
break
|
|
}
|
|
|
|
for _, f := range forbiddenAfter[n] {
|
|
forbidden[f] = true
|
|
}
|
|
|
|
seen[n] = true
|
|
}
|
|
|
|
if ok {
|
|
resultPart1 += seq[len(seq)/2]
|
|
} else {
|
|
sort.Slice(seq, func(i, j int) bool {
|
|
return slices.Index(forbiddenAfter[seq[j]], seq[i]) != -1
|
|
})
|
|
resultPart2 += seq[len(seq)/2]
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func readLine(s string) (line []int) {
|
|
split := strings.Split(s, ",")
|
|
line = make([]int, len(split))
|
|
for i, num := range split {
|
|
n, err := strconv.Atoi(num)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
line[i] = n
|
|
}
|
|
return
|
|
}
|
|
|
|
func readForbiddenAfter(scanner *bufio.Scanner) (forbiddenAfter map[int][]int) {
|
|
forbiddenAfter = make(map[int][]int)
|
|
|
|
for scanner.Scan() {
|
|
line := strings.TrimSpace(scanner.Text())
|
|
if len(line) == 0 {
|
|
return
|
|
}
|
|
|
|
split := strings.Split(line, "|")
|
|
if len(split) != 2 {
|
|
panic("Not enough data for ordering")
|
|
}
|
|
|
|
a, err := strconv.Atoi(split[0])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
b, err := strconv.Atoi(split[1])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
forbiddenAfter[b] = append(forbiddenAfter[b], a)
|
|
}
|
|
|
|
return
|
|
}
|