package main import ( "fmt" "os" "strconv" "strings" ) func main() { if len(os.Args) < 2 { panic("Provide input file") } inputFile := os.Args[1] part1, part2 := solution(inputFile) fmt.Printf("(%s) Part 1: %d\n(%s) Part 2: %d\n", inputFile, part1, inputFile, part2) } type Rule struct { Left int Right int } func solution(inputFile string) (int, int) { input, err := os.Open(inputFile) if err != nil { panic(err) } defer input.Close() var rules []Rule for { var x, y int _, err := fmt.Fscanf(input, "%d|%d\n", &x, &y) if err != nil { break } rules = append(rules, Rule{Left: x, Right: y}) } // for _, rule := range rules { // fmt.Printf("%d|%d\n", rule.Left, rule.Right) // } // checking if the updates are correct var validSum, invalidSum int for { var numStr string _, err := fmt.Fscanf(input, "%s\n", &numStr) if err != nil { break } parts := strings.Split(numStr, ",") updatePages := make([]int, 0) for _, part := range parts { partInt, _ := strconv.Atoi(part) updatePages = append(updatePages, partInt) } validUpdate := true for curr := 0; curr < len(updatePages); curr++ { for check := 0; check < len(updatePages); check++ { if curr == check { continue } if curr < check { valid := isValid(rules, updatePages[curr], updatePages[check]) if !valid { fmt.Printf("Invalid %v\n", updatePages) validUpdate = false break } } else { valid := isValid(rules, updatePages[check], updatePages[curr]) if !valid { fmt.Printf("Invalid %v\n", updatePages) validUpdate = false } } } if !validUpdate { break } } if validUpdate { validSum += updatePages[len(updatePages)/2] } else { invalidSum += reorderedMid(updatePages, rules) } } return validSum, invalidSum } func reorderedMid(pages []int, rules []Rule) int { corrected := false for !corrected { for i := 0; i < len(pages); i++ { for j := 1; j < len(pages); j++ { if i == j { continue } if i < j { valid := isValid(rules, pages[i], pages[j]) if !valid { pages[i], pages[j] = pages[j], pages[i] } } else { valid := isValid(rules, pages[j], pages[i]) if !valid { pages[i], pages[j] = pages[j], pages[i] } } } } corrected = wasCorrected(pages, rules) } fmt.Printf("Corrected %v\n", pages) return pages[len(pages)/2] } func wasCorrected(pages []int, rules []Rule) bool { for i := 0; i < len(pages); i++ { for j := 1; j < len(pages); j++ { if i == j { continue } if i < j { valid := isValid(rules, pages[i], pages[j]) if !valid { return false } } else { valid := isValid(rules, pages[j], pages[i]) if !valid { return false } } } } return true } func isValid(rules []Rule, left, right int) bool { for _, rule := range rules { if rule.Left == right && rule.Right == left { return false } } return true }