110 lines
1.9 KiB
Go
110 lines
1.9 KiB
Go
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
|
|
}
|