package main import ( "fmt" "os" "strings" "strconv" ) func check(e error) { if e != nil { panic(e) } } func contains(slice []int, element int) bool { for _, value := range slice { if value == element { return true } } return false } func get_prerequisites(rules [][2]int, target int) []int { out := make([]int, 0, 10) // find rules for _, rule := range rules { if rule[1] == target && !contains(out, rule[0]) { out = append(out, rule[0]) } } return out } func main() { dat, err := os.ReadFile("data.txt") check(err) dat_str := string(dat[:len(dat) - 1]) blocks := strings.Split(dat_str, "\n\n") rules := make([][2]int, 0, 1000) for _, rule := range strings.Split(blocks[0], "\n") { str_rules := strings.Split(rule, "|") num1, err := strconv.Atoi(str_rules[0]) check(err) num2, err := strconv.Atoi(str_rules[1]) check(err) rules = append(rules, [2]int{ num1, num2 }) } orderings := make([][]int, 0, 1000) for _, line := range strings.Split(blocks[1], "\n") { str_orderings := strings.Split(line, ",") elements := make([]int, 0, len(str_orderings)) for _, elem := range str_orderings { num, err := strconv.Atoi(elem) check(err) elements = append(elements, num) } orderings = append(orderings, elements) } // check orderings acc := 0 var pre []int for _, ordering := range orderings { // check single line valid := true for i := len(ordering) - 1; i >= 0; i-- { pre = get_prerequisites(rules, ordering[i]) for _, p := range pre { if contains(ordering, p) { if !contains(ordering[:i], p) { valid = false break } } } if !valid { break } } // add middle elem to acc if valid { acc += ordering[len(ordering)/2] } } fmt.Println(acc) }