From 6b7f79b6f0696aead620af4781b5a1a3d75f2cb5 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Mon, 9 Dec 2024 01:05:54 +0000 Subject: [PATCH] implement using custom sort function on an update struct rerun benchmarks --- day-05/benchmark | 22 +++++----- day-05/internal/one/benchmark | 4 +- day-05/internal/one/solve.go | 26 +++--------- day-05/internal/two/benchmark | 4 +- day-05/internal/two/solve.go | 48 +++------------------ day-05/internal/update/update.go | 20 +++++++++ day-05/internal/util/util.go | 72 +++++++++++++++++--------------- 7 files changed, 85 insertions(+), 111 deletions(-) create mode 100644 day-05/internal/update/update.go diff --git a/day-05/benchmark b/day-05/benchmark index 7205356..d552009 100644 --- a/day-05/benchmark +++ b/day-05/benchmark @@ -2,14 +2,14 @@ goos: linux goarch: amd64 pkg: github.com/onyx-and-iris/aoc2024/day-05 cpu: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz -BenchmarkSolve-12 1000000000 0.02016 ns/op -BenchmarkSolve-12 1000000000 0.02019 ns/op -BenchmarkSolve-12 1000000000 0.02182 ns/op -BenchmarkSolve-12 1000000000 0.01990 ns/op -BenchmarkSolve-12 1000000000 0.02056 ns/op -BenchmarkSolve-12 1000000000 0.02031 ns/op -BenchmarkSolve-12 1000000000 0.02083 ns/op -BenchmarkSolve-12 1000000000 0.02167 ns/op -BenchmarkSolve-12 1000000000 0.02048 ns/op -BenchmarkSolve-12 1000000000 0.02080 ns/op -ok github.com/onyx-and-iris/aoc2024/day-05 1.471s +BenchmarkSolve-12 1000000000 0.0008615 ns/op +BenchmarkSolve-12 1000000000 0.0008750 ns/op +BenchmarkSolve-12 1000000000 0.0008650 ns/op +BenchmarkSolve-12 1000000000 0.0009446 ns/op +BenchmarkSolve-12 1000000000 0.0009151 ns/op +BenchmarkSolve-12 1000000000 0.0008940 ns/op +BenchmarkSolve-12 1000000000 0.0008744 ns/op +BenchmarkSolve-12 1000000000 0.0008429 ns/op +BenchmarkSolve-12 1000000000 0.0008286 ns/op +BenchmarkSolve-12 1000000000 0.0008589 ns/op +ok github.com/onyx-and-iris/aoc2024/day-05 0.085s diff --git a/day-05/internal/one/benchmark b/day-05/internal/one/benchmark index 0e33e3d..0b3c3dd 100644 --- a/day-05/internal/one/benchmark +++ b/day-05/internal/one/benchmark @@ -2,5 +2,5 @@ goos: linux goarch: amd64 pkg: github.com/onyx-and-iris/aoc2024/day-05/internal/one cpu: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz -BenchmarkSolve-12 1000000000 0.007571 ns/op -ok github.com/onyx-and-iris/aoc2024/day-05/internal/one 0.052s +BenchmarkSolve-12 1000000000 0.0004326 ns/op +ok github.com/onyx-and-iris/aoc2024/day-05/internal/one 0.008s diff --git a/day-05/internal/one/solve.go b/day-05/internal/one/solve.go index 934489c..40590b4 100644 --- a/day-05/internal/one/solve.go +++ b/day-05/internal/one/solve.go @@ -9,33 +9,19 @@ import ( func Solve(buf []byte) (int, error) { r := bytes.NewReader(buf) - data, err := util.ParseLines(r) + updates, orderings, err := util.ParseLines(r) if err != nil { return 0, err } var sum int - for i, products := range data[1] { - inOrder := true - for _, product := range products { - for _, rules := range data[0] { - if !slices.Contains(rules, product) { - continue - } + for _, update := range updates { + beforeSort := slices.Clone(update.Pages) + update.Sort(orderings) - indx1, indx2 := slices.Index(products, rules[0]), slices.Index(products, rules[1]) - if indx1 != -1 && indx2 != -1 && indx2 < indx1 { - inOrder = false - break - } - } - if !inOrder { - break - } - } - if inOrder { - sum += data[1][i][len(data[1][i])/2] + if slices.Compare(beforeSort, update.Pages) == 0 { + sum += update.Pages[len(update.Pages)/2] } } diff --git a/day-05/internal/two/benchmark b/day-05/internal/two/benchmark index f2ac119..ca6850e 100644 --- a/day-05/internal/two/benchmark +++ b/day-05/internal/two/benchmark @@ -2,5 +2,5 @@ goos: linux goarch: amd64 pkg: github.com/onyx-and-iris/aoc2024/day-05/internal/two cpu: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz -BenchmarkSolve-12 1000000000 0.01270 ns/op -ok github.com/onyx-and-iris/aoc2024/day-05/internal/two 0.083s +BenchmarkSolve-12 1000000000 0.0004492 ns/op +ok github.com/onyx-and-iris/aoc2024/day-05/internal/two 0.008s diff --git a/day-05/internal/two/solve.go b/day-05/internal/two/solve.go index 046ce60..5e536bb 100644 --- a/day-05/internal/two/solve.go +++ b/day-05/internal/two/solve.go @@ -4,62 +4,26 @@ import ( "bytes" "slices" - log "github.com/sirupsen/logrus" - "github.com/onyx-and-iris/aoc2024/day-05/internal/util" ) func Solve(buf []byte) (int, error) { r := bytes.NewReader(buf) - data, err := util.ParseLines(r) + updates, orderings, err := util.ParseLines(r) if err != nil { return 0, err } var sum int - for i, products := range data[1] { - inOrder := true - for _, product := range products { - for _, rulesets := range data[0] { - if !slices.Contains(rulesets, product) { - continue - } + for _, update := range updates { + beforeSort := slices.Clone(update.Pages) + update.Sort(orderings) - indx1, indx2 := slices.Index(products, rulesets[0]), slices.Index(products, rulesets[1]) - if indx1 != -1 && indx2 != -1 && indx2 < indx1 { - inOrder = false - break - } - } - if !inOrder { - break - } - } - if !inOrder { - sum += midOfFixedOrder(data[1][i], data[0]) + if slices.Compare(beforeSort, update.Pages) != 0 { + sum += update.Pages[len(update.Pages)/2] } } return sum, nil } - -func midOfFixedOrder(products []int, rulesets [][]int) int { - log.Debugf("unordered products: %v", products) - - for { - var sorts int - for _, ruleset := range rulesets { - indx1, indx2 := slices.Index(products, ruleset[0]), slices.Index(products, ruleset[1]) - if indx1 != -1 && indx2 != -1 && indx2 < indx1 { - products[indx1], products[indx2] = products[indx2], products[indx1] - sorts++ - } - } - if sorts == 0 { - break - } - } - - return products[len(products)/2] -} diff --git a/day-05/internal/update/update.go b/day-05/internal/update/update.go new file mode 100644 index 0000000..cfd9839 --- /dev/null +++ b/day-05/internal/update/update.go @@ -0,0 +1,20 @@ +package update + +import "slices" + +type Update struct { + Pages []int +} + +func (u Update) Sort(orderings map[int][]int) { + slices.SortFunc(u.Pages, func(p, q int) int { + v, ok := orderings[p] + if ok { + if slices.Contains(v, q) { + return -1 + } + return 1 + } + return 1 + }) +} diff --git a/day-05/internal/util/util.go b/day-05/internal/util/util.go index 13fcdba..2f70512 100644 --- a/day-05/internal/util/util.go +++ b/day-05/internal/util/util.go @@ -3,47 +3,51 @@ package util import ( "bufio" "io" - "log" "strconv" "strings" + + "github.com/onyx-and-iris/aoc2024/day-05/internal/update" ) -func MustConv(s string) int { +func ParseLines(r io.Reader) ([]update.Update, map[int][]int, error) { + var updates []update.Update + orderings := make(map[int][]int, 0) + + var inUpdates bool + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + if len(line) == 0 { + inUpdates = true + continue + } + + if inUpdates { + var update update.Update + for _, n := range strings.Split(line, ",") { + update.Pages = append(update.Pages, mustConv(n)) + } + updates = append(updates, update) + } else { + left, right := func() (int, int) { + x := strings.Split(line, "|") + return mustConv(x[0]), mustConv(x[1]) + }() + orderings[left] = append(orderings[left], right) + } + } + + if err := scanner.Err(); err != nil { + return nil, nil, err + } + + return updates, orderings, nil +} + +func mustConv(s string) int { n, err := strconv.Atoi(s) if err != nil { panic(err) } return n } - -func ParseLines(r io.Reader) ([][][]int, error) { - data := make([][][]int, 2) - - filter := func(r rune) bool { - return r == '|' || r == ',' - } - - buf, err := io.ReadAll(r) - if err != nil { - log.Fatal(err) - } - parts := strings.Split(string(buf), "\n\n") - - for i, part := range parts { - scanner := bufio.NewScanner(strings.NewReader(part)) - for scanner.Scan() { - filtered := strings.FieldsFunc(scanner.Text(), filter) - var nums []int - for _, n := range filtered { - nums = append(nums, MustConv(n)) - } - data[i] = append(data[i], nums) - } - - if err := scanner.Err(); err != nil { - return nil, err - } - } - - return data, nil -}