|
|
|
@ -0,0 +1,113 @@
|
|
|
|
|
package day5
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"math"
|
|
|
|
|
"os"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Almanach struct {
|
|
|
|
|
SeedToSoil,
|
|
|
|
|
SoilToFert,
|
|
|
|
|
FertToWater,
|
|
|
|
|
WaterToLight,
|
|
|
|
|
LightToTemp,
|
|
|
|
|
TempToHum,
|
|
|
|
|
HumToLocation map[int]int
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func applyMap(source int, mapping map[int]int) int {
|
|
|
|
|
var result int
|
|
|
|
|
result, found := mapping[source]
|
|
|
|
|
if !found {
|
|
|
|
|
result = source
|
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a Almanach)locationForSeed(seed int) int {
|
|
|
|
|
soil := applyMap(seed, a.SeedToSoil)
|
|
|
|
|
fert := applyMap(soil, a.SoilToFert)
|
|
|
|
|
water := applyMap(fert, a.FertToWater)
|
|
|
|
|
light := applyMap(water, a.WaterToLight)
|
|
|
|
|
temp := applyMap(light, a.LightToTemp)
|
|
|
|
|
hum := applyMap(temp, a.TempToHum)
|
|
|
|
|
location := applyMap(hum, a.HumToLocation)
|
|
|
|
|
return location
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Run() int {
|
|
|
|
|
fmt.Println("the day 5")
|
|
|
|
|
inputDir := "day5/example"
|
|
|
|
|
seedToSoil := fmt.Sprint(inputDir, "/seed-to-soil")
|
|
|
|
|
soilToFert := fmt.Sprint(inputDir, "/soil-to-fertilizer")
|
|
|
|
|
fertToWater := fmt.Sprint(inputDir, "/fertilizer-to-water")
|
|
|
|
|
waterToLight := fmt.Sprint(inputDir, "/water-to-light")
|
|
|
|
|
lightToTemp := fmt.Sprint(inputDir, "/light-to-temperature")
|
|
|
|
|
tempToHum := fmt.Sprint(inputDir, "/temperature-to-humidity")
|
|
|
|
|
humToLocation := fmt.Sprint(inputDir, "/humidity-to-location")
|
|
|
|
|
|
|
|
|
|
seedsFileName := fmt.Sprint(inputDir, "/seeds")
|
|
|
|
|
seedsBytes, err := os.ReadFile(seedsFileName)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(fmt.Sprint("error reading seeds file ", seedsFileName))
|
|
|
|
|
}
|
|
|
|
|
seedsLine := string(seedsBytes)
|
|
|
|
|
var seeds []int
|
|
|
|
|
for _, seedStr := range strings.Fields(seedsLine) {
|
|
|
|
|
seed, err := strconv.Atoi(seedStr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(fmt.Sprint("can't read seeds ", seedStr))
|
|
|
|
|
}
|
|
|
|
|
seeds = append(seeds, seed)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
almanach := Almanach{
|
|
|
|
|
SeedToSoil: ReadMap(seedToSoil),
|
|
|
|
|
SoilToFert: ReadMap(soilToFert),
|
|
|
|
|
FertToWater: ReadMap(fertToWater),
|
|
|
|
|
WaterToLight: ReadMap(waterToLight),
|
|
|
|
|
LightToTemp: ReadMap(lightToTemp),
|
|
|
|
|
TempToHum: ReadMap(tempToHum),
|
|
|
|
|
HumToLocation: ReadMap(humToLocation),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result := math.MaxInt
|
|
|
|
|
for _, seed := range seeds {
|
|
|
|
|
location := almanach.locationForSeed(seed)
|
|
|
|
|
if location < result {
|
|
|
|
|
result = location
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ReadMap(filename string) map[int]int {
|
|
|
|
|
result := make(map[int]int)
|
|
|
|
|
bytes, err := os.ReadFile(filename)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(fmt.Sprintf("error reading file %s", filename))
|
|
|
|
|
}
|
|
|
|
|
text := string(bytes)
|
|
|
|
|
text = strings.TrimSpace(text)
|
|
|
|
|
for _, line := range strings.Split(text, "\n") {
|
|
|
|
|
nums := strings.Fields(line)
|
|
|
|
|
if len(nums) != 3 {
|
|
|
|
|
panic(fmt.Sprint("error, map line doesn't have 3 nums: ", line, nums))
|
|
|
|
|
}
|
|
|
|
|
destinaitonStart, err1 := strconv.Atoi(nums[0])
|
|
|
|
|
sourceStart, err2 := strconv.Atoi(nums[1])
|
|
|
|
|
rangeLength, err3 := strconv.Atoi(nums[2])
|
|
|
|
|
if err1 != nil || err2 != nil || err3 != nil {
|
|
|
|
|
panic(fmt.Sprint("error converting one of the numbers: ", nums))
|
|
|
|
|
}
|
|
|
|
|
for i := 0; i < rangeLength; i++ {
|
|
|
|
|
result[sourceStart+i] = destinaitonStart + i
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|