package main import ( "os" "fmt" "strings" "strconv" ) type input []string func parse(f string) (seq input) { seq = make(input, 0) for _, step := range strings.Split(f, ",") { step = strings.TrimSpace(step) seq = append(seq, step) } return } func hash(in string) (hash uint8) { hash = 0 for _, byt := range []byte(in) { hash += byt hash *= 17 } return } func part1(seq input) (sum uint) { for _, step := range seq { sum += uint(hash(step)) } return } type lens struct { label string focal uint64 } func lens_find_label(arr []lens, label string) (pos int) { for pos, val := range arr{ if val.label == label { return pos } } return -1 } func part2(seq input) (sum uint64) { boxes := [256][]lens{} for i := 0; i < 256; i++ { boxes[i] = make([]lens, 0) } for _, step := range seq { var label string var op byte var off int if strings.Index(step, "=") >= 0 { off = strings.Index(step, "=") label = step[:off] op = step[off] } else if strings.Index(step, "-") >= 0 { off = strings.Index(step, "-") label = step[:off] op = step[off] } box := &boxes[hash(label)] pos := lens_find_label(*box, label) switch op { case '=': focal, _ := strconv.ParseUint(step[off + 1:], 0, 64) newlens := lens{ label: label, focal: focal, } if pos >= 0 { (*box)[pos] = newlens } else { *box = append(*box, newlens) } case '-': if pos >= 0 { *box = append((*box)[:pos], (*box)[pos + 1:]...) } } } sum = 0 for box_i, box := range boxes { for lens_i, lens := range box { fmt.Println(box_i + 1, ":", lens_i + 1, lens.label, lens.focal) sum += uint64(1 + box_i) * uint64(1 + lens_i) * lens.focal } } return } func main() { file, _ := os.ReadFile(os.Args[1]) f := string(file) in := parse(f) fmt.Println(part1(in)) fmt.Println(part2(in)) }