148 lines
3.2 KiB
Go
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]
|
|
} |