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 }