143 lines
2.9 KiB
Go
143 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var rules [][2]int
|
|
var pages [][]int
|
|
|
|
func main() {
|
|
file, err := os.Open("./input.txt")
|
|
if err != nil {
|
|
log.Fatalf("failed to open file: %s\n", err)
|
|
}
|
|
defer file.Close()
|
|
s := bufio.NewScanner(file)
|
|
|
|
stage := 0
|
|
|
|
for s.Scan() {
|
|
text := s.Text()
|
|
if stage == 0 {
|
|
if text == "" {
|
|
stage++
|
|
continue
|
|
}
|
|
ints := strings.Split(text, "|")
|
|
l, err := strconv.Atoi(ints[0])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
r, err := strconv.Atoi(ints[1])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
rule := [2]int{l, r}
|
|
rules = append(rules, rule)
|
|
} else {
|
|
nums := strings.Split(text, ",")
|
|
var list []int
|
|
for _, n := range nums {
|
|
int, err := strconv.Atoi(n)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
list = append(list, int)
|
|
}
|
|
pages = append(pages, list)
|
|
}
|
|
}
|
|
|
|
total1 := 0
|
|
total2 := 0
|
|
|
|
for _, page := range pages {
|
|
pageValid := checkPagesValid(rules, page)
|
|
if !pageValid {
|
|
// this is the ugliest solution ever, but it works!
|
|
newpage := orderPage(rules, page)
|
|
for x := 0; x < 100; x++ {
|
|
newpage = orderPage(rules, page)
|
|
}
|
|
size := len(newpage)
|
|
middle := ((size - 1) / 2)
|
|
total2 += newpage[middle]
|
|
} else {
|
|
size := len(page)
|
|
middle := ((size - 1) / 2)
|
|
total1 += page[middle]
|
|
}
|
|
}
|
|
|
|
fmt.Println("result part1:", total1)
|
|
fmt.Println("result part2:", total2)
|
|
}
|
|
|
|
func orderPage(rules [][2]int, page []int) []int {
|
|
var newPage []int = page
|
|
|
|
for page_idx, num := range page {
|
|
for _, rule := range rules {
|
|
// check if any ints on the left of the current index match, if so it is invalid
|
|
if rule[0] == num {
|
|
// fmt.Println("found in left rule...", page_idx)
|
|
for i := page_idx - 1; i >= 0; i-- {
|
|
if page[i] == rule[1] {
|
|
swap(&newPage, i, page_idx)
|
|
}
|
|
}
|
|
}
|
|
// check if any ints on the right of the current index match, if so it is invalid
|
|
if rule[1] == num {
|
|
for i := page_idx; i < len(page); i++ {
|
|
if page[i] == rule[0] {
|
|
swap(&newPage, i, page_idx)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return newPage
|
|
}
|
|
|
|
func checkPagesValid(rules [][2]int, page []int) bool {
|
|
for page_idx, num := range page {
|
|
for _, rule := range rules {
|
|
// check if any ints on the left of the current index match, if so it is invalid
|
|
if rule[0] == num {
|
|
// fmt.Println("found in left rule...", page_idx)
|
|
for i := page_idx - 1; i >= 0; i-- {
|
|
if page[i] == rule[1] {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
// check if any ints on the right of the current index match, if so it is invalid
|
|
if rule[1] == num {
|
|
for i := page_idx; i < len(page); i++ {
|
|
if page[i] == rule[0] {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
func swap(arr *[]int, a, b int) {
|
|
// Check if indices are within the bounds of the slice
|
|
if a < 0 || b < 0 || a >= len(*arr) || b >= len(*arr) {
|
|
panic("Index out of bounds")
|
|
}
|
|
|
|
// Swap the elements at indices a and b
|
|
(*arr)[a], (*arr)[b] = (*arr)[b], (*arr)[a]
|
|
}
|