package main import ( "bufio" "fmt" "os" "strconv" "strings" "time" ) func must[T, Q any](f func(T) (Q, error), t T) Q { q, err := f(t) if err != nil { panic(err) } return q } func iter[T, Q any](f func(T) Q, t []T) []Q { r := make([]Q, len(t)) for i := 0; i < len(t); i++ { r[i] = f(t[i]) } return r } func main() { start := time.Now() partOne() duration := time.Since(start) partTwo() duration2 := time.Since(start) fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) } func makeScanner(test bool) *bufio.Scanner { var f *os.File if test { f, _ = os.Open("inputs/testinput") } else { f, _ = os.Open("inputs/input") } reader := bufio.NewReader(f) return bufio.NewScanner(reader) } func partOne() { scanner := makeScanner(false) seeds := [][]int{} scanner.Scan() line := scanner.Text() _, seedList, _ := strings.Cut(line, ": ") for _, s := range strings.Split(seedList, " ") { seeds = append(seeds, []int{must(strconv.Atoi, s)}) } scanner.Scan() // discard empty line state := 1 for scanner.Scan() { line := scanner.Text() if line == "" { for i, s := range seeds { if len(s) == state { seeds[i] = append(seeds[i], s[state-1]) } } state++ continue } if line[len(line)-1] == ':' { continue } // destination, source, length m := iter( func(s string) int { return must(strconv.Atoi, s) }, strings.Split(line, " "), ) for i, s := range seeds { if len(s) == state && m[1] <= s[state-1] && m[1]+m[2] > s[state-1] { seeds[i] = append(seeds[i], s[state-1]-m[1]+m[0]) } } } lowest := seeds[0][len(seeds[0])-1] for _, s := range seeds { if s[len(s)-1] < lowest { lowest = s[len(s)-1] } } fmt.Println(lowest) } func partTwo() { scanner := makeScanner(true) seeds := [][]int{} scanner.Scan() line := scanner.Text() _, seedRanges, _ := strings.Cut(line, ": ") r := strings.Split(seedRanges, " ") for i := 0; i <= len(r); i += i + 2 { rng := must(strconv.Atoi, r[i+1]) for j := 0; j < rng; j++ { // this is too slow! seeds = append(seeds, []int{must(strconv.Atoi, r[i]) + j}) } } scanner.Scan() // discard empty line state := 1 for scanner.Scan() { line := scanner.Text() if line == "" { for i, s := range seeds { if len(s) == state { seeds[i] = append(seeds[i], s[state-1]) } } state++ continue } if line[len(line)-1] == ':' { continue } // destination, source, length m := iter( func(s string) int { return must(strconv.Atoi, s) }, strings.Split(line, " "), ) for i, s := range seeds { if len(s) == state && m[1] <= s[state-1] && m[1]+m[2] > s[state-1] { seeds[i] = append(seeds[i], s[state-1]-m[1]+m[0]) } } } lowest := seeds[0][len(seeds[0])-1] for _, s := range seeds { if s[len(s)-1] < lowest { lowest = s[len(s)-1] } } fmt.Println(lowest) }