From c70d4a74cfbbb5fc41c17ace6f1040241d666434 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Tue, 7 Jan 2025 17:22:03 +0000 Subject: [PATCH] run loop logic in separate goroutines. use bool channel + waitgroups to collect results --- day-04/internal/one/solve.go | 39 ++++++++++++++------ day-04/internal/two/matrix.go | 2 +- day-04/internal/two/solve.go | 67 ++++++++++++++++++++++------------- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/day-04/internal/one/solve.go b/day-04/internal/one/solve.go index fe8a460..773425c 100644 --- a/day-04/internal/one/solve.go +++ b/day-04/internal/one/solve.go @@ -2,6 +2,7 @@ package one import ( "bytes" + "sync" log "github.com/sirupsen/logrus" ) @@ -13,37 +14,53 @@ func Solve(buf []byte) (int, error) { return 0, err } - var sum int + wg := sync.WaitGroup{} + sumChan := make(chan bool) for i := 0; i < len(graph.data); i++ { for j := 0; j < len(graph.data[i]); j++ { - current := newPoint(j, i) - if graph.valueAt(current) == 'X' { - for _, n := range neighbours(current) { - if checkNeighbours(graph, n, "MAS") { - sum++ + wg.Add(1) + go func() { + defer wg.Done() + + current := newPoint(j, i) + if graph.valueAt(current) == 'X' { + for _, n := range neighbours(current) { + sumChan <- checkNeighbours(n, "MAS", graph) } } - } + }() + } + } + + go func() { + wg.Wait() + close(sumChan) + }() + + var sum int + for val := range sumChan { + if val { + sum++ } } return sum, nil } -func checkNeighbours(graph *graph, n point, word string) bool { +func checkNeighbours(n point, word string, g *graph) bool { if len(word) == 0 { log.Debug("we found a full XMAS") return true } - if graph.isOutOfBounds(n) { + if g.isOutOfBounds(n) { return false } - if graph.valueAt(n) != rune(word[0]) { + if g.valueAt(n) != rune(word[0]) { return false } - return checkNeighbours(graph, neighbours(n)[n.direction], word[1:]) + return checkNeighbours(neighbours(n)[n.direction], word[1:], g) } diff --git a/day-04/internal/two/matrix.go b/day-04/internal/two/matrix.go index f0480f0..c8afa86 100644 --- a/day-04/internal/two/matrix.go +++ b/day-04/internal/two/matrix.go @@ -37,7 +37,7 @@ func (m *matrix) rotate() *matrix { return &temp } -func (m *matrix) validate() bool { +func (m *matrix) isValid() bool { golden := &matrix{ {'M', -1, 'M'}, {-1, 'A', -1}, diff --git a/day-04/internal/two/solve.go b/day-04/internal/two/solve.go index 6b0ef88..2fd1351 100644 --- a/day-04/internal/two/solve.go +++ b/day-04/internal/two/solve.go @@ -3,6 +3,7 @@ package two import ( "bytes" "slices" + "sync" ) func Solve(buf []byte) (int, error) { @@ -12,40 +13,56 @@ func Solve(buf []byte) (int, error) { return 0, err } - var sum int + wg := sync.WaitGroup{} + sumChan := make(chan bool) for i := 0; i < len(graph.data); i++ { for j := 0; j < len(graph.data[i]); j++ { - current := newPoint(j, i) - if graph.valueAt(current) == 'A' { - if func() bool { - for _, n := range neighbours(current) { - if graph.isOutOfBounds(n) { - return true - } + wg.Add(1) + go func() { + defer wg.Done() - if !slices.Contains([]rune{'M', 'S'}, graph.valueAt(n)) { - return true + current := newPoint(j, i) + if graph.valueAt(current) == 'A' { + if func() bool { + for _, n := range neighbours(current) { + if graph.isOutOfBounds(n) { + return true + } + + if !slices.Contains([]rune{'M', 'S'}, graph.valueAt(n)) { + return true + } } + return false + }() { + return } - return false - }() { - continue - } - ns := neighbours(current) - matrix := newMatrix( - graph.valueAt(current), - graph.valueAt(ns[NW]), - graph.valueAt(ns[NE]), - graph.valueAt(ns[SE]), - graph.valueAt(ns[SW]), - ) + ns := neighbours(current) + matrix := newMatrix( + graph.valueAt(current), + graph.valueAt(ns[NW]), + graph.valueAt(ns[NE]), + graph.valueAt(ns[SE]), + graph.valueAt(ns[SW]), + ) - if matrix.validate() { - sum++ + sumChan <- matrix.isValid() } - } + }() + } + } + + go func() { + wg.Wait() + close(sumChan) + }() + + var sum int + for val := range sumChan { + if val { + sum++ } }