package main import ( "math" "sync" ) var wg sync.WaitGroup var mu sync.Mutex const UNLIMITED = -1 // bound represents the lower and upper limits of a single range type bound struct { lower, upper int } // newBound returns a bound type func newBound(lower, upper int) bound { return bound{lower: lower, upper: upper} } // nextTransform recursively calculates each new set of seed ranges for each set of data in dataMap func nextTransform(i int, in []bound) []bound { if i == len(identifiers) { return in } q := newQueue(UNLIMITED, in) in = make([]bound, 0) for !q.isEmpty() { r := q.dequeue() hasOverlap := func() bool { for _, data := range dataMap[identifiers[i]] { start := max(r.lower, data.source) end := min(r.upper, data.source+data.offset) if isOverlapping(start, end) { // add new seed range in = append(in, newBound(data.transform(start, end))) // append unmatched portions of seed range back into queue if start > r.lower { q.enqueue(newBound(r.lower, start-1)) } if r.upper > end { q.enqueue(newBound(end, r.upper-1)) } return true } } return false }() // there was no overlap, add the seed range as is if !hasOverlap { in = append(in, r) } } return nextTransform(i+1, in) } // two returns the lowest location for any seed in seedRanges func two(lines []string) int { var seedRanges = []bound{} for i := 0; i < len(seeds); i += 2 { wg.Add(1) go func(i int) { defer wg.Done() mu.Lock() seedRanges = append(seedRanges, nextTransform(0, []bound{newBound(seeds[i], seeds[i]+seeds[i+1]-1)})...) mu.Unlock() }(i) } wg.Wait() lowest := math.MaxInt for _, r := range seedRanges { if r.lower < lowest { lowest = r.lower } } return lowest }