This commit is contained in:
Gareth
2024-12-05 13:39:33 +00:00
parent 235999524b
commit 88938a8627
4 changed files with 1586 additions and 4 deletions

134
2024/gareth/day05/day05.go Normal file
View File

@@ -0,0 +1,134 @@
package day05
import (
"strconv"
"strings"
)
type Rule struct {
X, Y int
}
func ParseInput(input string) ([]Rule, [][]int) {
sections := strings.Split(input, "\n\n")
ruleLines := strings.Split(strings.TrimSpace(sections[0]), "\n")
var rules []Rule
for _, ruleLine := range ruleLines {
parts := strings.Split(ruleLine, "|")
x, _ := strconv.Atoi(parts[0])
y, _ := strconv.Atoi(parts[1])
rules = append(rules, Rule{X: x, Y: y})
}
updateLines := strings.Split(strings.TrimSpace(sections[1]), "\n")
var updates [][]int
for _, updateLine := range updateLines {
parts := strings.Split(updateLine, ",")
var update []int
for _, part := range parts {
page, _ := strconv.Atoi(part)
update = append(update, page)
}
updates = append(updates, update)
}
return rules, updates
}
func ValidateUpdate(update []int, rules []Rule) bool {
indexMap := make(map[int]int)
for i, page := range update {
indexMap[page] = i
}
for _, rule := range rules {
pageX, indexX := indexMap[rule.X]
pageY, indexY := indexMap[rule.Y]
if indexX && indexY && pageX > pageY {
return false
}
}
return true
}
func FindMiddle(update []int) int {
n := len(update)
return update[n/2]
}
func SortUpdate(update []int, rules []Rule) []int {
depen := make(map[int][]int)
for _, rule := range rules {
depen[rule.Y] = append(depen[rule.Y], rule.X)
}
visited := make(map[int]bool)
var sorted []int
for _, page := range update {
if !visited[page] {
sorted = Visit(page, depen, visited, update, sorted)
}
}
return sorted
}
func Visit(page int, depen map[int][]int, visited map[int]bool, update []int, sorted []int) []int {
if visited[page] {
return sorted
}
visited[page] = true
for _, d := range depen[page] {
if contains(update, d) {
sorted = Visit(d, depen, visited, update, sorted)
}
}
sorted = append(sorted, page)
return sorted
}
func contains(slice []int, element int) bool {
for _, item := range slice {
if item == element {
return true
}
}
return false
}
func Part1(input string) int {
rules, updates := ParseInput(input)
total := 0
for _, update := range updates {
if ValidateUpdate(update, rules) {
total += FindMiddle(update)
}
}
return total
}
func Part2(input string) int {
rules, updates := ParseInput(input)
var invalidUpdates [][]int
total := 0
for _, update := range updates {
if !ValidateUpdate(update, rules) {
invalidUpdates = append(invalidUpdates, update)
}
}
for _, update := range invalidUpdates {
sortedUpdate := SortUpdate(update, rules)
total += FindMiddle(sortedUpdate)
}
return total
}

View File

@@ -0,0 +1,71 @@
package day05
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestPart1(t *testing.T) {
r := Part1(`47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47`)
assert.Equal(t, 143, r)
}
func TestPart2(t *testing.T) {
r := Part2(`47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47`)
assert.Equal(t, 123, r)
}

1377
2024/gareth/day05/input.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,13 @@
package main package main
import ( import (
"aoc2024/day03" "aoc2024/day05"
"fmt" "fmt"
"os" "os"
) )
func main() { func main() {
data, _ := os.ReadFile("day03/input.txt") data, _ := os.ReadFile("day05/input.txt")
fmt.Printf("part 1: %d\n", day03.Part1(string(data))) fmt.Printf("part 1: %d\n", day05.Part1(string(data)))
fmt.Printf("part 2: %d\n", day03.Part2(string(data))) fmt.Printf("part 2: %d\n", day05.Part2(string(data)))
} }