Code of the Advent kind, maybe in Go this year
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
4.4 KiB

12 months ago
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)
}