package main import ( "fmt" "sort" "strings" "aoc/helper" ) type rules map[[2]int]struct{} type updates []update type update []int func main() { order_rules, page_updates := getOrdersAndUpdate() // part 1 sum := 0 for _, update := range page_updates { if update.validateRules(order_rules) { sum += update.getMiddleNumber() } } fmt.Printf("Summed updates: %d\n", sum) // part 2 sum = 0 for _, update := range page_updates { if update.validateRules(order_rules) { continue } update.reorderByRules(order_rules) if update.validateRules(order_rules) { sum += update.getMiddleNumber() } } fmt.Printf("Sum fixed updates: %d\n", sum) } func (u update) reorderByRules(r rules) update { sort.Slice( u, func(i, j int) bool { pair := [2]int{u[i], u[j]} if _, exists := r[pair]; exists { return true } pair = [2]int{u[j], u[i]} if _, exists := r[pair]; exists { return false } return false }, ) return u } func (u update) validateRules(r rules) bool { for i := 0; i < len(u)-1; i++ { // check if a rule exists for current page pair (this + next) pair := [2]int{u[i+1], u[i]} if _, exists := r[pair]; exists { return false } } return true } func (u update) getMiddleNumber() int { return u[len(u)/2] } func getOrdersAndUpdate() (rules, updates) { data := helper.GetLines() // parse rules rules := rules{} for data.Scan() { line := data.Text() if len(line) <= 1 { // empty line, leave the rest for the update parser break } parts := strings.Split(line, "|") page := helper.ToInt(parts[0]) after := helper.ToInt(parts[1]) rules[[2]int{page, after}] = struct{}{} } // parse updates updates := updates{} for data.Scan() { line := data.Text() parts := strings.Split(line, ",") update := update{} for _, part := range parts { update = append(update, helper.ToInt(part)) } updates = append(updates, update) } return rules, updates }