2024 Day 5 Complete!
This commit is contained in:
168
2024/day05/main.go
Normal file
168
2024/day05/main.go
Normal file
@@ -0,0 +1,168 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := helpers.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
rules, updates := processInput(inp)
|
||||
var result int
|
||||
for i := range updates {
|
||||
if rules.Validate(updates[i]) {
|
||||
result = result + updates[i][len(updates[i])/2]
|
||||
}
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Printf("Valid Updates: %d\n", result)
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
rules, updates := processInput(inp)
|
||||
var result int
|
||||
for i := range updates {
|
||||
var iter int
|
||||
var wasIncorrect bool
|
||||
for !rules.Validate(updates[i]) {
|
||||
if iter > 100 {
|
||||
panic(errors.New("Naive correction won't work..."))
|
||||
}
|
||||
updates[i] = rules.Correct(updates[i])
|
||||
iter++
|
||||
wasIncorrect = true
|
||||
}
|
||||
if wasIncorrect {
|
||||
result = result + updates[i][len(updates[i])/2]
|
||||
}
|
||||
}
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Printf("Corrected Updates: %d\n", result)
|
||||
}
|
||||
|
||||
func processInput(inp []string) (*PageOrderingRules, [][]int) {
|
||||
var rawRules []string
|
||||
var strUpdates []string
|
||||
var inRules bool
|
||||
inRules = true
|
||||
for i := range inp {
|
||||
if inp[i] == "" {
|
||||
inRules = false
|
||||
continue
|
||||
}
|
||||
if inRules {
|
||||
rawRules = append(rawRules, inp[i])
|
||||
} else {
|
||||
strUpdates = append(strUpdates, inp[i])
|
||||
}
|
||||
}
|
||||
var updates [][]int
|
||||
rules := PageOrderingRules{Rules: parseOrderingRules(rawRules)}
|
||||
for i := range strUpdates {
|
||||
updates = append(updates, parseUpdate(strUpdates[i]))
|
||||
}
|
||||
|
||||
return &rules, updates
|
||||
}
|
||||
|
||||
type PageOrderingRules struct {
|
||||
Rules []Rule
|
||||
}
|
||||
|
||||
func (p *PageOrderingRules) Correct(update []int) []int {
|
||||
if p.Validate(update) {
|
||||
return update
|
||||
}
|
||||
for i := range p.Rules {
|
||||
update = p.Rules[i].Correct(update)
|
||||
}
|
||||
return update
|
||||
}
|
||||
|
||||
func (p *PageOrderingRules) Validate(update []int) bool {
|
||||
for i := range p.Rules {
|
||||
if !p.Rules[i].Validates(update) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p PageOrderingRules) String() string {
|
||||
var ret string
|
||||
for i := range p.Rules {
|
||||
ret = fmt.Sprintf("%s%s\n", ret, p.Rules[i])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
first, second int
|
||||
}
|
||||
|
||||
func (r *Rule) Validates(update []int) bool {
|
||||
for i := range update {
|
||||
if update[i] == r.first {
|
||||
for j := range update {
|
||||
if update[j] == r.second {
|
||||
return i < j
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (r *Rule) Correct(update []int) []int {
|
||||
if r.Validates(update) {
|
||||
return update
|
||||
}
|
||||
var idx, jdx int
|
||||
for i := range update {
|
||||
if update[i] == r.first {
|
||||
idx = i
|
||||
}
|
||||
if update[i] == r.second {
|
||||
jdx = i
|
||||
}
|
||||
}
|
||||
update[idx], update[jdx] = update[jdx], update[idx]
|
||||
return update
|
||||
}
|
||||
|
||||
func (r Rule) String() string {
|
||||
return fmt.Sprintf("%d|%d", r.first, r.second)
|
||||
}
|
||||
|
||||
func parseOrderingRules(inp []string) []Rule {
|
||||
var ret []Rule
|
||||
for i := range inp {
|
||||
if inp[i] == "" {
|
||||
return ret
|
||||
}
|
||||
rule := Rule{}
|
||||
fmt.Sscanf(inp[i], "%d|%d", &rule.first, &rule.second)
|
||||
ret = append(ret, rule)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func parseUpdate(inp string) []int {
|
||||
var ret []int
|
||||
pts := strings.Split(inp, ",")
|
||||
for i := range pts {
|
||||
var wrk int
|
||||
fmt.Sscanf(pts[i], "%d", &wrk)
|
||||
ret = append(ret, wrk)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user