Untitled
unknown
golang
2 years ago
2.7 kB
5
Indexable
type maps struct {
seeds []int64
sts islandMap
stf islandMap
ftw islandMap
wtl islandMap
ltt islandMap
tth islandMap
htl islandMap
}
type islandMap [][3]int64
func Run() {
lines := util.MustReadLines(5)
m := constructMaps(lines)
fmt.Printf("PART ONE: %d\n", ptOne(m))
fmt.Printf("PART TWO: %d\n", ptTwo(m))
}
func constructMaps(lines []string) maps {
return maps{
seeds: util.MustStringToInt64Slice(strings.Split(lines[0], ":")[1]),
sts: constructMap(lines, "seed-to-soil"),
stf: constructMap(lines, "soil-to-fertilizer"),
ftw: constructMap(lines, "fertilizer-to-water"),
wtl: constructMap(lines, "water-to-light"),
ltt: constructMap(lines, "light-to-temperature"),
tth: constructMap(lines, "temperature-to-humidity"),
htl: constructMap(lines, "humidity-to-location"),
}
}
func constructMap(lines []string, mapName string) islandMap {
im := islandMap{}
idx := findIndex(lines, mapName) + 1
line := lines[idx]
for line != "" {
sn := strings.Fields(line)
n := [3]int64{}
for i := 0; i < 3; i++ {
n[i] = util.MustParseInt64(sn[i])
}
im = append(im, n)
idx++
line = lines[idx]
}
return im
}
func findIndex(lines []string, s string) int {
for i, l := range lines {
if strings.HasPrefix(l, s) {
return i
}
}
return -1
}
func useMap(im islandMap, val int64) int64 {
for _, m := range im {
ss := m[1]
se := ss + m[2]
if ss <= val && val < se {
ds := m[0]
dist := val - ss
return ds + dist
}
}
return val
}
func ptOne(m maps) int64 {
ims := []islandMap{
m.sts,
m.stf,
m.ftw,
m.wtl,
m.ltt,
m.tth,
m.htl,
}
locs := []int64{}
for _, val := range m.seeds {
for _, im := range ims {
val = useMap(im, val)
}
locs = append(locs, val)
}
minVal := locs[0]
for _, l := range locs {
if l < minVal {
minVal = l
}
}
return minVal
}
func ptTwo(m maps) int64 {
ims := []islandMap{
m.sts,
m.stf,
m.ftw,
m.wtl,
m.ltt,
m.tth,
m.htl,
}
minLoc := int64(math.MaxInt64)
mu := sync.Mutex{}
wg := sync.WaitGroup{}
for i := 0; i < len(m.seeds); i += 2 {
wg.Add(1)
go func(i int) {
fmt.Printf("STARTING GOROUTINE %d, DISTANCE %d\n", i, m.seeds[i+1])
startTime := time.Now()
for seed := m.seeds[i]; seed < m.seeds[i]+m.seeds[i+1]; seed++ {
val := seed
for _, im := range ims {
val = useMap(im, val)
}
mu.Lock()
if val < minLoc {
minLoc = val
fmt.Printf("NEW MIN VALUE FOUND: %d\n", val)
}
mu.Unlock()
}
wg.Done()
endTime := time.Now().Sub(startTime)
fmt.Printf("FINISHED GOROUTINE %d, %f SECONDS\n", i, endTime.Seconds())
}(i)
}
wg.Wait()
return minLoc
}
Editor is loading...
Leave a Comment