diff --git a/2024/day05/main.go b/2024/day05/main.go new file mode 100644 index 0000000..dca1adb --- /dev/null +++ b/2024/day05/main.go @@ -0,0 +1,160 @@ +package main + +import ( + "fmt" + "log" + "os" + "slices" + "strings" + + "github.com/kfarnung/advent-of-code/2024/lib" +) + +type constraint struct { + first int64 + second int64 +} + +func part1(input string) int64 { + constraints, err := parseConstraints(input) + if err != nil { + log.Fatal(err) + } + + pageLists, err := parsePageList(input) + if err != nil { + log.Fatal(err) + } + + sum := int64(0) + for _, pages := range pageLists { + meetsAllConstraints := true + for _, constraint := range constraints { + firstIndex := slices.Index(pages, constraint.first) + secondIndex := slices.Index(pages, constraint.second) + + if firstIndex == -1 || secondIndex == -1 { + continue + } + + if secondIndex < firstIndex { + meetsAllConstraints = false + break + } + } + + if meetsAllConstraints { + sum += pages[len(pages)/2] + } + } + + return sum +} + +func part2(input string) int64 { + constraints, err := parseConstraints(input) + if err != nil { + log.Fatal(err) + } + + pageLists, err := parsePageList(input) + if err != nil { + log.Fatal(err) + } + + sum := int64(0) + for _, pages := range pageLists { + meetsAllConstraints := true + didSwap := true + for didSwap { + didSwap = false + for _, constraint := range constraints { + firstIndex := slices.Index(pages, constraint.first) + secondIndex := slices.Index(pages, constraint.second) + + if firstIndex == -1 || secondIndex == -1 { + continue + } + + if secondIndex < firstIndex { + meetsAllConstraints = false + + temp := pages[firstIndex] + pages[firstIndex] = pages[secondIndex] + pages[secondIndex] = temp + + didSwap = true + } + } + } + + if !meetsAllConstraints { + sum += pages[len(pages)/2] + } + } + + return sum +} + +func parseConstraints(input string) ([]constraint, error) { + var constraints []constraint + for _, line := range lib.SplitLines(input) { + if line == "" { + break + } + + split := strings.Split(line, "|") + first, err := lib.ParseInt[int64](split[0]) + if err != nil { + return nil, err + } + + second, err := lib.ParseInt[int64](split[1]) + if err != nil { + return nil, err + } + + constraints = append(constraints, constraint{first, second}) + } + + return constraints, nil +} + +func parsePageList(input string) ([][]int64, error) { + var pages [][]int64 + foundBreak := false + for _, line := range lib.SplitLines(input) { + if line == "" { + foundBreak = true + continue + } else if !foundBreak { + continue + } + + split := strings.Split(line, ",") + var page []int64 + for _, s := range split { + val, err := lib.ParseInt[int64](s) + if err != nil { + return nil, err + } + + page = append(page, val) + } + + pages = append(pages, page) + } + + return pages, nil +} + +func main() { + name := os.Args[1] + content, err := lib.LoadFileContent(name) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Part 1: %d\n", part1(content)) + fmt.Printf("Part 2: %d\n", part2(content)) +} diff --git a/2024/day05/main_test.go b/2024/day05/main_test.go new file mode 100644 index 0000000..73bdf36 --- /dev/null +++ b/2024/day05/main_test.go @@ -0,0 +1,63 @@ +package main + +import ( + "strings" + "testing" + + "github.com/kfarnung/advent-of-code/2024/lib" + "github.com/stretchr/testify/assert" +) + +var input = strings.Join([]string{ + "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", + "", +}, "\n") + +func TestPart1(t *testing.T) { + assert.Equal(t, int64(143), part1(input)) + + inputContent, err := lib.GetInputContent() + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, int64(6041), part1(inputContent)) +} + +func TestPart2(t *testing.T) { + assert.Equal(t, int64(123), part2(input)) + + inputContent, err := lib.GetInputContent() + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, int64(4884), part2(inputContent)) +} diff --git a/private b/private index 8bf14ce..46d333a 160000 --- a/private +++ b/private @@ -1 +1 @@ -Subproject commit 8bf14ce03e2342ecfa0730e5537304ab70e163de +Subproject commit 46d333ab8c3b7037734c44cd2bb8fc07f9bc2593