naive brute force doesn't work for day 5 part 2 of course...
This commit is contained in:
		
							
								
								
									
										145
									
								
								05/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								05/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user