package main import ( "bufio" "fmt" "os" "strings" "strconv" ) type maprange struct { src uint64 dst uint64 } type mapdir struct { src string dst string } type mapval struct { cunt uint64 rnge maprange } type mapping struct { dir mapdir val []mapval } func main() { f, _ := os.Open(os.Args[1]) s := bufio.NewScanner(f) var maps []mapping var init_seeds []uint64 inmap := false var curmap mapping for s.Scan() { line := s.Text() switch { case strings.HasPrefix(line, "seeds: "): thing := strings.Split(line[7:], " ") for _, v := range thing { val, _ := strconv.ParseUint(v, 0, 64) init_seeds = append(init_seeds, val) } case strings.HasSuffix(line, " map:"): if inmap { maps = append(maps, curmap) } curmap = mapping{} inmap = true split1 := strings.Index(line, "-to-") split2 := strings.Index(line, " ") src := line[:split1] dst := line[split1 + 4:split2] curmap.dir.src = src curmap.dir.dst = dst case strings.Count(line, " ") >= 2 && inmap: thing := strings.Split(line, " ") var val mapval val.rnge.dst, _ = strconv.ParseUint(thing[0], 0, 64) val.rnge.src, _ = strconv.ParseUint(thing[1], 0, 64) val.cunt, _ = strconv.ParseUint(thing[2], 0, 64) curmap.val = append(curmap.val, val) } } if inmap { maps = append(maps, curmap) } seeds := append(make([]uint64, 0, len(init_seeds)), init_seeds...) currency := "seed" for currency != "location" { var map_cur mapping map_found := false for _, v := range maps { if v.dir.src == currency { map_cur = v map_found = true break } } if !map_found { break } currency = map_cur.dir.dst for i, v := range seeds { for _, x := range map_cur.val { tmp := v - x.rnge.src if tmp > 0 && tmp < x.cunt { v += x.rnge.dst - x.rnge.src break } } seeds[i] = v } } minloc := seeds[0] for _, v := range seeds[1:] { if v < minloc { minloc = v } } fmt.Println(minloc) seedrnge := make([]maprange, 0) for i, _ := range init_seeds { if i % 2 == 1 { continue } var rnge maprange rnge.src = init_seeds[i + 0] rnge.dst = rnge.src + init_seeds[i + 1] seedrnge = append(seedrnge, rnge) } currency = "seed" for currency != "location" { var map_cur mapping map_found := false for _, v := range maps { if v.dir.src == currency { map_cur = v map_found = true break } } if !map_found { break } currency = map_cur.dir.dst newseedrnge := make([]maprange, 0) for _, v := range seedrnge { for _, x := range map_cur.val { src := x.rnge.src end := x.rnge.src + x.cunt if src <= v.src && v.src < end && src <= v.dst && v.dst < end { newseedrnge = append(newseedrnge, maprange{ src: v.src + x.rnge.dst - x.rnge.src, dst: v.dst + x.rnge.dst - x.rnge.src, }) v.src = v.dst } else if src <= v.src && v.src < end { newseedrnge = append(newseedrnge, maprange{ src: v.src + x.rnge.dst - x.rnge.src, dst: x.rnge.dst + x.cunt, }) v.src = end } else if src <= v.dst && v.dst < end { newseedrnge = append(newseedrnge, maprange{ src: x.rnge.dst, dst: v.dst + x.rnge.dst - x.rnge.src, }) v.dst = src } if v.src == v.dst { break } } if v.src != v.dst { newseedrnge = append(newseedrnge, v) } } seedrnge = newseedrnge } minrnge := seedrnge[0].src for _, v := range seedrnge[1:] { if v.src < minrnge { minrnge = v.src } } fmt.Println(minrnge) }