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 }