diff --git a/05/main.go b/05/main.go new file mode 100644 index 0000000..7453627 --- /dev/null +++ b/05/main.go @@ -0,0 +1,145 @@ +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) +} diff --git a/go.mod b/go.mod index a3f7ee9..be9315c 100644 --- a/go.mod +++ b/go.mod @@ -1 +1,3 @@ module git.yetaga.in/alazyreader/AdventOfCode2023 + +go 1.21.4