diff --git a/2024/day3/main.go b/2024/day3/main.go index c6245f9..a4f13d2 100644 --- a/2024/day3/main.go +++ b/2024/day3/main.go @@ -9,6 +9,28 @@ import ( "strconv" ) +type Queue[T any] struct { + items []T +} + +func (q *Queue[T]) Enqueue(item T) { + q.items = append(q.items, item) +} + +func (q *Queue[T]) Dequeue() T { + item := q.items[0] + q.items = q.items[1:] + return item +} + +func (q *Queue[T]) IsEmpty() bool { + return len(q.items) == 0 +} + +func (q *Queue[T]) Peek() T { + return q.items[0] +} + func Part1(text string) int { // Regex to match mul(x, y) mulRe := regexp.MustCompile(`(?i)mul\((\d+),(\d+)\)`) @@ -39,42 +61,32 @@ func Part2(text string) int { // Regex to match do quoted strings doRe := regexp.MustCompile("(?i)do\\(\\)") - doReMatches := doRe.FindAllStringIndex(text, -1) + doQueue := Queue[int]{} + for _, match := range doRe.FindAllStringIndex(text, -1) { + doQueue.Enqueue(match[0]) + } // Regex to match do quoted strings dontRe := regexp.MustCompile("(?i)don't\\(\\)") - dontReMatches := dontRe.FindAllStringIndex(text, -1) + dontQueue := Queue[int]{} + for _, match := range dontRe.FindAllStringIndex(text, -1) { + dontQueue.Enqueue(match[0]) + } - lastDoIndex := 0 - lastDontIndex := 0 result := 0 for _, match := range mulReMatches { // Find the last instance of do before the current match - lastDo := -1 - for i := lastDoIndex; i < len(doReMatches); i++ { - m := doReMatches[i] - if match[0] < m[0] { - break - } - - lastDo = m[0] - lastDoIndex = i + for !doQueue.IsEmpty() && doQueue.Peek() < match[0] { + _ = doQueue.Dequeue() } // Find the last instance of don't before the current match - lastDont := -1 - for i := lastDontIndex; i < len(dontReMatches); i++ { - m := dontReMatches[i] - if match[0] < m[0] { - break - } - - lastDont = m[0] - lastDontIndex = i + for !dontQueue.IsEmpty() && dontQueue.Peek() < match[0] { + _ = dontQueue.Dequeue() } // If the previous don't is after the previous do, skip this match - if lastDont > lastDo { + if !dontQueue.IsEmpty() && !doQueue.IsEmpty() && dontQueue.Peek() < doQueue.Peek() { continue }