github.com/agrigoryan/aoc_2023_go@v0.0.0-20231216221323-4ace361ec685/day5/d5p2.go (about) 1 package day5 2 3 import ( 4 "fmt" 5 "log" 6 "math" 7 "strconv" 8 "strings" 9 10 "github.com/agrigoryan/aoc_2023_go/aocutils" 11 ) 12 13 func d5p2(input string) int { 14 lines := strings.Split(input, "\n") 15 16 toNumbersMapper := aocutils.Mapper(func(str string) int { 17 res, err := strconv.Atoi(str) 18 if err != nil { 19 log.Fatal("failed to map to numbers") 20 } 21 return res 22 }) 23 24 seedRanges := toNumbersMapper(strings.Split(strings.Split(lines[0], ": ")[1], " ")) 25 26 lines = lines[1:] 27 28 var activeMapping *mapping 29 for _, line := range lines { 30 if len(strings.TrimSpace(line)) == 0 { 31 if activeMapping != nil { 32 mappings[activeMapping.srcCode] = *activeMapping 33 activeMapping = nil 34 } 35 continue 36 } 37 if activeMapping == nil { 38 // reading a new mapping details 39 parts := strings.Split(strings.Split(line, " ")[0], "-") 40 activeMapping = &mapping{ 41 srcCode: parts[0], 42 dstCode: parts[2], 43 } 44 } else { 45 // parsing new mapping rule here 46 numbers := toNumbersMapper(strings.Split(line, " ")) 47 activeMapping.rules = append(activeMapping.rules, mappingRule{ 48 src: numbers[1], 49 dst: numbers[0], 50 count: numbers[2], 51 }) 52 } 53 } 54 if activeMapping != nil { 55 mappings[activeMapping.srcCode] = *activeMapping 56 } 57 58 rangeMinimums := make(chan int, len(seedRanges)/2) 59 60 for i := 0; i < len(seedRanges); i += 2 { 61 rangeStart := seedRanges[i] 62 rangeEnd := rangeStart + seedRanges[i+1] 63 go func() { 64 fmt.Println(rangeStart, rangeEnd) 65 var minLocation int = math.MaxInt 66 for seed := rangeStart; seed < rangeEnd; seed++ { 67 location := doMappings("seed", "location", seed) 68 if location < minLocation { 69 minLocation = location 70 } 71 } 72 rangeMinimums <- minLocation 73 }() 74 } 75 76 totalMin := math.MaxInt 77 resultsRead := 0 78 for rangeMin := range rangeMinimums { 79 if rangeMin < totalMin { 80 totalMin = rangeMin 81 } 82 resultsRead += 1 83 if resultsRead == len(seedRanges)/2 { 84 break 85 } 86 } 87 88 fmt.Println(totalMin) 89 return totalMin 90 }