package day15

import (
	"adventofcode2023/utils"
	_ "fmt"
	"strings"
)

type Lens struct {
	label	string
	fl		int
}

func Part1(input string) int {
	ans := 0
	seqs := strings.Split(input, ",")
	for _,seq := range seqs {
		ans += hash(seq)
	}
	
	return ans
}

func Part2(input string) int {
	Boxes := [256][]Lens{}
	cmds := strings.Split(input, ",")
	for _,cmd := range cmds {
		if cmd[len(cmd)-1] == '-' {
			label := cmd[:len(cmd)-1]
			hash := hash(label)
			nl := []Lens{}
			for _, lens := range Boxes[hash] {
				if lens.label != label {
					nl = append(nl, lens)
				}
			}
			Boxes[hash] = nl
		} else {
			tokens := strings.Split(cmd, "=")
			label := tokens[0]
			fl := utils.MustAtoi(tokens[1])
			hash := hash(label)
			nl := []Lens{}
			if len(Boxes[hash]) == 0 {
				Boxes[hash] = append(Boxes[hash], Lens{label:label, fl:fl})
			} else {
				found := false
				for _, lens := range Boxes[hash] {
					if lens.label == label {
						nl = append(nl, Lens{label:label, fl:fl})
						found = true
					} else {
						nl = append(nl, lens)
					}
				}
				Boxes[hash] = nl
				if ! found {
					Boxes[hash] = append(Boxes[hash], Lens{label:label, fl:fl})
				}
			}
		}
	}
	ans := 0
	for i, box := range Boxes {
		for j, lens := range box {
			ans += (i+1) * (j +1) * lens.fl
		}
	} 
		return ans
}

func hash(in string) int {
	result := 0
	for _, letter := range in {
		result += int(letter) 
		result = result * 17
		result = result % 256
	}
	return result
}