Files
adventofcode/2023/go/day05/day05.go
2023-12-06 13:17:46 +00:00

197 lines
4.7 KiB
Go

package day05
import (
_ "regexp"
"strings"
"fmt"
"adventofcode2023/utils"
)
type Map struct {
dest_range_start uint64
src_range_start uint64
range_len uint64
}
type Almanac struct {
seed2soil []Map
soil2fert []Map
fert2water []Map
water2light []Map
light2temp []Map
temp2humid []Map
humid2loc []Map
}
type SeedMap struct {
seed uint64
range_len uint64
}
func Part1(input string) uint64 {
seeds, almanac, _ := parseInput1(input)
fmt.Println(seeds)
fmt.Println(almanac)
minLoc := uint64(utils.MaxInt)
for _, seed := range seeds {
soil := lookup_dest(seed, almanac.seed2soil)
fert := lookup_dest(soil, almanac.soil2fert)
water := lookup_dest(fert, almanac.fert2water)
light := lookup_dest(water, almanac.water2light)
temp := lookup_dest(light, almanac.light2temp)
humid := lookup_dest(temp, almanac.temp2humid)
loc := lookup_dest(humid, almanac.humid2loc)
if loc < minLoc {
minLoc = loc
}
fmt.Println(loc)
}
return minLoc
}
func Part2(input string) int {
seedsmap, almanac, _ := parseInput2(input)
minLoc := uint64(utils.MaxInt)
for _, seedmap := range seedsmap {
for i := seedmap.seed;i<seedmap.seed+seedmap.range_len;i++ {
soil := lookup_dest(i, almanac.seed2soil)
fert := lookup_dest(soil, almanac.soil2fert)
water := lookup_dest(fert, almanac.fert2water)
light := lookup_dest(water, almanac.water2light)
temp := lookup_dest(light, almanac.light2temp)
humid := lookup_dest(temp, almanac.temp2humid)
loc := lookup_dest(humid, almanac.humid2loc)
if loc < minLoc {
minLoc = loc
}
}
fmt.Println(minLoc)
}
//
// fmt.Println(minSeedMap)
// minLoc = utils.MaxInt
// for i:=minSeedMap.seed;i<minSeedMap.seed+minSeedMap.range_len;i++ {
// soil := lookup_dest(i, almanac.seed2soil)
// fert := lookup_dest(soil, almanac.soil2fert)
// water := lookup_dest(fert, almanac.fert2water)
// light := lookup_dest(water, almanac.water2light)
// temp := lookup_dest(light, almanac.light2temp)
// humid := lookup_dest(temp, almanac.temp2humid)
// loc := lookup_dest(humid, almanac.humid2loc)
// if loc < minLoc {
// minLoc = loc
// }
// }
return int(minLoc)
}
func lookup_dest(entity uint64, data []Map) uint64 {
for _, dataMap := range data {
if entity >= dataMap.src_range_start && entity <= dataMap.src_range_start + dataMap.range_len {
return dataMap.dest_range_start + entity - dataMap.src_range_start
}
}
return entity
}
func lookup_src(entity uint64, data []Map) uint64 {
for _, dataMap := range data {
if entity >= dataMap.dest_range_start && entity <= dataMap.dest_range_start + dataMap.range_len {
return dataMap.src_range_start + entity - dataMap.dest_range_start
}
}
return entity
}
func parseInput1(input string) ([]uint64, Almanac, error) {
var almanac Almanac
var seeds []uint64
lines := strings.Split(input, "\n")
seedLine := string(lines[0])
tokens := strings.Fields(seedLine)
for _, token := range tokens[1:] {
seeds = append(seeds, uint64(utils.MustAtoi(token)))
}
blocks := strings.Split(input, "\n\n")
for i, block := range blocks {
lines := strings.Split(block, "\n")
switch i {
case 0:
continue
case 1:
almanac.seed2soil = getMap(lines[1:])
case 2:
almanac.soil2fert = getMap(lines[1:])
case 3:
almanac.fert2water = getMap(lines[1:])
case 4:
almanac.water2light = getMap(lines[1:])
case 5:
almanac.light2temp = getMap(lines[1:])
case 6:
almanac.temp2humid = getMap(lines[1:])
case 7:
almanac.humid2loc = getMap(lines[1:])
}
}
return seeds, almanac, nil
}
func parseInput2(input string) ([]SeedMap, Almanac, error) {
var almanac Almanac
var seeds []SeedMap
lines := strings.Split(input, "\n")
seedLine := string(lines[0])
tokens := strings.Fields(seedLine)
for i:=1;i<len(tokens);i=i+2 {
seedStart := uint64(utils.MustAtoi(tokens[i]))
seedRange := uint64(utils.MustAtoi(tokens[i+1]))
seeds = append(seeds, SeedMap{seedStart, seedRange})
}
blocks := strings.Split(input, "\n\n")
for i, block := range blocks {
lines := strings.Split(block, "\n")
switch i {
case 0:
continue
case 1:
almanac.seed2soil = getMap(lines[1:])
case 2:
almanac.soil2fert = getMap(lines[1:])
case 3:
almanac.fert2water = getMap(lines[1:])
case 4:
almanac.water2light = getMap(lines[1:])
case 5:
almanac.light2temp = getMap(lines[1:])
case 6:
almanac.temp2humid = getMap(lines[1:])
case 7:
almanac.humid2loc = getMap(lines[1:])
}
}
return seeds, almanac, nil
}
func getMap(input []string) []Map {
var out []Map
for _, line := range input {
tokens := strings.Fields(line)
out = append(out, Map{uint64(utils.MustAtoi(tokens[0])), uint64(utils.MustAtoi(tokens[1])),uint64(utils.MustAtoi(tokens[2]))})
}
return out
}