Day 05. solutions
This commit is contained in:
parent
8b698738c5
commit
2b14d3a742
3
data.go
3
data.go
|
@ -15,3 +15,6 @@ var Day03Data string
|
|||
|
||||
//go:embed day_04/data.txt
|
||||
var Day04Data string
|
||||
|
||||
//go:embed day_05/data.txt
|
||||
var Day05Data string
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,28 @@
|
|||
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
|
|
@ -0,0 +1,123 @@
|
|||
package day_05
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Rules map[int][]int
|
||||
type Manual []int
|
||||
|
||||
// task:https://adventofcode.com/2024/day/5
|
||||
// short summary - count valid columns
|
||||
func SolveBasic(input string) int {
|
||||
manuals, rules := loadManualAndRules(input)
|
||||
|
||||
sum := 0
|
||||
for _, manual := range manuals {
|
||||
if isManualValid(manual, rules) {
|
||||
sum += manual[len(manual)/2]
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// task:https://adventofcode.com/2024/day/5#part2
|
||||
// short summary - fix and count invalid columns
|
||||
func SolveComplex(input string) int {
|
||||
manuals, rules := loadManualAndRules(input)
|
||||
|
||||
sum := 0
|
||||
for _, manual := range manuals {
|
||||
if !isManualValid(manual, rules) {
|
||||
manual = fixManual(manual, rules)
|
||||
sum += manual[len(manual)/2]
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
func fixManual(manual Manual, rules Rules) Manual {
|
||||
for {
|
||||
index := violationIndex(manual, rules)
|
||||
if index == -1 {
|
||||
return manual
|
||||
}
|
||||
violation := manual[index]
|
||||
manual = slices.Delete(manual, index, index+1)
|
||||
for i := 0; i < len(manual); i++ {
|
||||
if values, present := rules[manual[i]]; present {
|
||||
if slices.Contains(values, violation) {
|
||||
manual = slices.Insert(manual, i, violation)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
||||
func isManualValid(manual Manual, rules Rules) bool {
|
||||
return violationIndex(manual, rules) == -1
|
||||
}
|
||||
|
||||
func violationIndex(manual Manual, rules Rules) int {
|
||||
illegalValues := []int{}
|
||||
for i, num := range manual {
|
||||
if slices.Contains(illegalValues, num) {
|
||||
return i
|
||||
}
|
||||
if _, contains := rules[num]; contains {
|
||||
illegalValues = append(illegalValues, rules[num]...)
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func loadManualAndRules(input string) ([]Manual, Rules) {
|
||||
substrings := strings.Split(input, "\n\n")
|
||||
|
||||
rules := loadRules(substrings[0])
|
||||
manuals := loadManuals(substrings[1])
|
||||
|
||||
return manuals, rules
|
||||
}
|
||||
|
||||
func loadManuals(s string) []Manual {
|
||||
var manuals []Manual
|
||||
for _, line := range strings.Split(s, "\n") {
|
||||
manuals = append(manuals, loadManual(line))
|
||||
}
|
||||
return manuals
|
||||
}
|
||||
|
||||
func loadManual(line string) []int {
|
||||
var manual Manual
|
||||
for _, value := range strings.Split(line, ",") {
|
||||
manual = append(manual, must(strconv.Atoi(value)))
|
||||
}
|
||||
return manual
|
||||
}
|
||||
|
||||
func must(val int, err error) int {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func loadRules(s string) Rules {
|
||||
rules := map[int][]int{}
|
||||
for _, line := range strings.Split(s, "\n") {
|
||||
var k, v int
|
||||
_, err := fmt.Sscanf(line, "%d|%d", &k, &v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rules[v] = append(rules[v], k)
|
||||
}
|
||||
return rules
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package day_05_test
|
||||
|
||||
import (
|
||||
"advent_of_code_2024/day_05"
|
||||
_ "embed"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//go:embed example_data.txt
|
||||
var ExampleData string
|
||||
|
||||
func TestBasicSolutionExample(t *testing.T) {
|
||||
result := day_05.SolveBasic(ExampleData)
|
||||
if result != 143 {
|
||||
t.Fatalf("Expected 143 received %d", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComplexSolutionExample(t *testing.T) {
|
||||
result := day_05.SolveComplex(ExampleData)
|
||||
if result != 123 {
|
||||
t.Fatalf("Expected 123 received %d", result)
|
||||
}
|
||||
}
|
7
main.go
7
main.go
|
@ -5,6 +5,7 @@ import (
|
|||
"advent_of_code_2024/day_02"
|
||||
"advent_of_code_2024/day_03"
|
||||
"advent_of_code_2024/day_04"
|
||||
"advent_of_code_2024/day_05"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -29,7 +30,11 @@ func main() {
|
|||
case "04-basic":
|
||||
fmt.Printf("Day 04. Basic: %d\n", day_04.SolveBasic(Day04Data)) // 2560
|
||||
case "04-complex":
|
||||
fmt.Printf("Day 04. Complex: %d\n", day_04.SolveComplex(Day04Data)) // 63013756
|
||||
fmt.Printf("Day 04. Complex: %d\n", day_04.SolveComplex(Day04Data)) // 1980
|
||||
case "05-basic":
|
||||
fmt.Printf("Day 05. Basic: %d\n", day_05.SolveBasic(Day05Data)) // 2560
|
||||
case "05-complex":
|
||||
fmt.Printf("Day 05. Complex: %d\n", day_05.SolveComplex(Day05Data)) // 63013756
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue