aoc/2024/day-05/main.go
2024-12-05 10:59:10 +01:00

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]
}