129 lines
2.1 KiB
Go
129 lines
2.1 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
inp := h.StdinToString()
|
||
|
part1(inp)
|
||
|
fmt.Println()
|
||
|
part2(inp)
|
||
|
}
|
||
|
|
||
|
func part1(input string) {
|
||
|
var res int
|
||
|
pts := strings.Split(input, ",")
|
||
|
for i := range pts {
|
||
|
res += hash(pts[i])
|
||
|
}
|
||
|
fmt.Println("# Part 1")
|
||
|
fmt.Println(res)
|
||
|
}
|
||
|
|
||
|
func part2(input string) {
|
||
|
var boxes []*Box
|
||
|
for i := 1; i <= 256; i++ {
|
||
|
boxes = append(boxes, &Box{num: i})
|
||
|
}
|
||
|
for _, v := range strings.Split(input, ",") {
|
||
|
l := NewLens(v)
|
||
|
if l.focalLength == -1 {
|
||
|
// Remove
|
||
|
boxes[l.box].Remove(l)
|
||
|
} else {
|
||
|
// Add/Replace
|
||
|
boxes[l.box].Add(l)
|
||
|
}
|
||
|
}
|
||
|
var res int
|
||
|
for i := range boxes {
|
||
|
res += boxes[i].FocusingPower()
|
||
|
}
|
||
|
fmt.Println("# Part 2")
|
||
|
fmt.Println(res)
|
||
|
}
|
||
|
|
||
|
type Box struct {
|
||
|
num int
|
||
|
lenses []*Lens
|
||
|
}
|
||
|
|
||
|
func (b *Box) Add(l *Lens) {
|
||
|
for i := range b.lenses {
|
||
|
if b.lenses[i].label == l.label {
|
||
|
b.lenses[i] = l
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
b.lenses = append(b.lenses, l)
|
||
|
}
|
||
|
func (b *Box) Remove(l *Lens) {
|
||
|
for i := range b.lenses {
|
||
|
if b.lenses[i].label == l.label {
|
||
|
b.lenses = append(b.lenses[:i], b.lenses[i+1:]...)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
func (b *Box) FocusingPower() int {
|
||
|
var res int
|
||
|
for i := range b.lenses {
|
||
|
var lensRes int
|
||
|
lensRes = b.num
|
||
|
lensRes *= i + 1
|
||
|
lensRes *= b.lenses[i].focalLength
|
||
|
res += lensRes
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
type Lens struct {
|
||
|
label string
|
||
|
focalLength int
|
||
|
box int
|
||
|
}
|
||
|
|
||
|
func NewLens(inp string) *Lens {
|
||
|
if strings.Contains(inp, "=") {
|
||
|
pts := strings.Split(inp, "=")
|
||
|
return &Lens{
|
||
|
label: pts[0],
|
||
|
focalLength: h.Atoi(pts[1]),
|
||
|
box: hash(pts[0]),
|
||
|
}
|
||
|
} else {
|
||
|
lbl := strings.TrimSuffix(inp, "-")
|
||
|
return &Lens{
|
||
|
label: lbl,
|
||
|
focalLength: -1,
|
||
|
box: hash(lbl),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func hash(inp string) int {
|
||
|
var res int
|
||
|
for _, i := range inp {
|
||
|
res += int(i)
|
||
|
res *= 17
|
||
|
res = res % 256
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
func focusingPower(lens string, boxNum int, boxes [][]string) int {
|
||
|
res := boxNum + 1
|
||
|
for i := 1; i <= len(boxes[boxNum]); i++ {
|
||
|
if boxes[boxNum][i-1] == lens {
|
||
|
res *= i
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return res
|
||
|
}
|