Files
adventofcode/2024/go/day05/day05.go
2024-12-05 16:47:12 +00:00

148 lines
3.2 KiB
Go

package day05
import (
"adventofcode2024/utils"
_ "sort"
"strings"
"fmt"
)
func Part1(input string) int {
num := 0
rules := make(map[int][]int)
sections := strings.Split(input, "\n\n")
rules_str := strings.Split(sections[0], "\n")
updates_str := strings.Split(sections[1], "\n")
updates := make([][]int, len(updates_str))
for _, rule := range rules_str {
fields := strings.Split(rule, "|")
// Convert the fields to integers
val1 := utils.MustAtoi(fields[0])
val2 := utils.MustAtoi(fields[1])
rules[val1] = append(rules[val1], val2)
}
for i, update := range updates_str {
fields := strings.Split(update, ",")
for _, field := range fields {
updates[i] = append(updates[i], utils.MustAtoi(field))
}
}
for _, update := range updates {
good := true
reverseSlice(update)
fmt.Printf("rules: %v\n", rules)
fmt.Printf("update: %v\n", update)
for i, page := range update {
for _, rule := range rules[page] {
if contains(update[i+1:], rule) {
good = false
break
}
}
if !good {
break
}
}
if good {
fmt.Printf("good: %v\n", update)
num += update[len(update)/2]
}
}
return num
}
func Part2(input string) int {
num := 0
rules := make(map[int][]int)
sections := strings.Split(input, "\n\n")
rules_str := strings.Split(sections[0], "\n")
updates_str := strings.Split(sections[1], "\n")
updates := make([][]int, len(updates_str))
for _, rule := range rules_str {
fields := strings.Split(rule, "|")
// Convert the fields to integers
val1 := utils.MustAtoi(fields[0])
val2 := utils.MustAtoi(fields[1])
rules[val1] = append(rules[val1], val2)
}
for i, update := range updates_str {
fields := strings.Split(update, ",")
for _, field := range fields {
updates[i] = append(updates[i], utils.MustAtoi(field))
}
}
for _, update := range updates {
reverseSlice(update)
if !isGood(update, rules) {
fmt.Printf("not good: %v\n", update)
makeGood(update, rules)
fmt.Printf("good: %v\n", update)
num += update[len(update)/2]
}
}
return num
}
func contains(slice []int, x int) bool {
for _, value := range slice {
if value == x {
return true
}
}
return false
}
func location(slice []int, x int) int {
for i, value := range slice {
if value == x {
return i
}
}
return -1
}
func reverseSlice(slice []int) {
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
slice[i], slice[j] = slice[j], slice[i]
}
}
func isGood(update []int, rules map[int][]int) bool {
good := true
for i, page := range update {
for _, rule := range rules[page] {
if contains(update[i+1:], rule) {
good = false
break
}
}
if !good {
return good
}
}
return good
}
func makeGood(update []int, rules map[int][]int) []int {
for i, page := range update {
for _, rule := range rules[page] {
loc := location(update[i+1:], rule)
if loc != -1 {
swap(update, loc+i+1, i)
makeGood(update, rules)
}
}
}
return update
}
func swap(slice []int, i, j int) {
if i < 0 || i >= len(slice) || j < 0 || j >= len(slice) {
panic("Index out of range")
}
slice[i], slice[j] = slice[j], slice[i]
}