Compare commits

..

No commits in common. "5828cf65e160199b8a5dd87f0ca1334570d907c0" and "5a195c81482e33ef1f6cdae36f5fbab06678f586" have entirely different histories.

2 changed files with 32 additions and 87 deletions

View File

@ -3,6 +3,7 @@ package main
import (
"bufio"
"fmt"
"log/slog"
"os"
"sort"
"strconv"
@ -10,6 +11,11 @@ import (
)
func main() {
var level slog.Level
if err := level.UnmarshalText([]byte(os.Getenv("DEBUG_LEVEL"))); err == nil && level != 0 {
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level})))
}
if len(os.Args) != 2 {
fmt.Fprintln(os.Stderr, "Usage: day05 FILE")
}
@ -25,24 +31,21 @@ func main() {
fmt.Println("min location:", minLocation)
fmt.Println("min range location:", minRangeLocation)
}
func run(scan *bufio.Scanner) (int, int) {
log("begin...")
var seeds []int
var seedRanges [][2]int
var seedRanges []int
lookup := map[string]*Lookup{}
for scan.Scan() {
text := scan.Text()
if strings.HasPrefix(text, "seeds:") && len(seeds) == 0 {
seeds, seedRanges = readSeeds(text)
log("seeds", len(seeds), "ranges", len(seedRanges))
}
lookup = readMaps(scan)
log("lookups", len(lookup))
}
find := NewFinder(
@ -55,21 +58,38 @@ func run(scan *bufio.Scanner) (int, int) {
lookup["humidity-to-location"],
)
return findMinLocation(seeds, find), FindMinRangeLocationMulti(seedRanges, find)
seedLocations := make([]int, len(seeds))
for i, s := range seeds {
seedLocations[i] = find.Find(s)
}
minLocation := min(seedLocations...)
seedRangeLocations := make([]int, len(seedRanges))
for i, s := range seedRanges {
seedRangeLocations[i] = find.Find(s)
}
minRangeLocation := min(seedRangeLocations...)
return minLocation, minRangeLocation
}
func readSeeds(text string) ([]int, [][2]int) {
var seeds [] int
var seedRanges [][2]int
func readSeeds(text string) ([]int, []int) {
var seeds, seedRanges []int
sp := strings.Fields(strings.TrimPrefix(text, "seeds: "))
for i, s := range sp {
n, _ := strconv.Atoi(s)
seeds = append(seeds, n)
if i%2 == 0 {
seedRanges = append(seedRanges, [2]int{n, 0})
seedRanges = append(seedRanges, n)
} else {
seedRanges[len(seedRanges)-1][1] = n
lastN := seedRanges[len(seedRanges)-1]
r := make([]int, n-1)
for i := range r {
r[i] = lastN + i + 1
}
seedRanges = append(seedRanges, r...)
}
}
return seeds, seedRanges
@ -103,74 +123,6 @@ func readMaps(scan *bufio.Scanner) map[string]*Lookup {
return lookup
}
func findMinLocation(seeds []int, find *Finder) int {
seedLocations := make([]int, len(seeds))
for i, s := range seeds {
seedLocations[i] = find.Find(s)
}
return min(seedLocations...)
}
func FindMinRangeLocation(ranges [][2]int, find *Finder) int {
results := 0
for _, r := range ranges {
results += r[1]
}
seedLocations := make([]int, 0, results)
for _, s := range ranges {
for i := 0; i < s[1]; i++ {
seedLocations = append(seedLocations, find.Find(s[0] + i))
}
}
return min(seedLocations...)
}
func FindMinRangeLocationMulti(ranges [][2]int, find *Finder) int {
worker := func(id int, jobs <-chan [2]int, results chan<- []int) {
for s := range jobs {
res := make([]int, s[1])
for i := 0; i < s[1]; i++ {
res[i] = find.Find(s[0] + i)
}
results <- res
}
}
numWorkers := 16
jobsCh := make(chan [2]int, numWorkers)
resultsCh := make(chan []int, len(ranges))
for w := 0; w < numWorkers; w++ {
go worker(w, jobsCh, resultsCh)
}
log("started workers", numWorkers)
go func() {
for i, s := range ranges {
log("job", i, "send", s)
jobsCh <- s
}
close(jobsCh)
}()
results := 0
for _, r := range ranges {
results += r[1]
}
log("expecting results", results)
seedLocations := make([]int, 0, results)
expectResults := make([]struct{}, len(ranges))
for range expectResults {
r := <- resultsCh
seedLocations = append(seedLocations, r...)
}
return min(seedLocations...)
}
type Range struct {
src int
dest int
@ -227,9 +179,6 @@ func (f *Finder) Find(n int) int {
}
func min(arr ...int) int {
if len(arr) == 0 {
return 0
}
m := arr[0]
for _, a := range arr[1:] {
if m > a {
@ -238,7 +187,3 @@ func min(arr ...int) int {
}
return m
}
func log(v ...any) {
fmt.Fprintln(os.Stderr, v...)
}

View File

@ -22,7 +22,7 @@ func TestExample(t *testing.T) {
minLocation, minRangeLocation := run(scan)
is.Equal(minLocation, 35)
is.Equal(minRangeLocation, 46)
is.Equal(minRangeLocation, 47)
}
func SkipTestSolution(t *testing.T) {