Advent-of-Code-2023/day5/dayFive.go

114 lines
2.8 KiB
Go

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
}