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.
110 lines
2.2 KiB
110 lines
2.2 KiB
11 months ago
|
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))
|
||
|
}
|