123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package main
- import (
- "fmt"
- "log"
- "os"
- "strconv"
- "strings"
- )
- func readInput(path string) []string {
- data, err := os.ReadFile(path)
- if err != nil {
- log.Fatal(err)
- }
- parts := strings.Split(string(data), ",")
- if len(parts) == 0 {
- log.Fatal("Bad input!")
- }
- for i := range parts {
- parts[i] = strings.TrimRight(parts[i], "\n")
- }
- return parts
- }
- const (
- Max = 256
- )
- func hash(text string) int {
- var current int
- for i := range text {
- current += int(text[i])
- current = current * 17 % Max
- }
- return current
- }
- func part1(steps []string) int {
- var result int
- for i := range steps {
- result += hash(steps[i])
- }
- return result
- }
- type Lens struct {
- label string
- power int
- }
- func lensFromString(text string) Lens {
- parts := strings.Split(text, "=")
- if len(parts) != 2 {
- log.Fatalf("Problem reading step %s", text)
- }
- lens := Lens{label: parts[0]}
- n, err := strconv.Atoi(parts[1])
- if err != nil {
- log.Fatalf("Problem converting number %s: %s", parts[1], err)
- }
- lens.power = n
- return lens
- }
- func addLens(box []Lens, lens Lens) []Lens {
- found := false
- for i := range box {
- if box[i].label == lens.label {
- box[i] = lens
- found = true
- break
- }
- }
- if !found {
- box = append(box, lens)
- }
- return box
- }
- func getBoxes(steps []string) [][]Lens {
- lenses := make([][]Lens, 256)
- for i := range steps {
- if strings.Contains(steps[i], "=") {
- lens := lensFromString(steps[i])
- boxIndex := hash(lens.label)
- lenses[boxIndex] = addLens(lenses[boxIndex], lens)
- } else {
- label := strings.TrimRight(steps[i], "-")
- boxIndex := hash(label)
- for i := range lenses[boxIndex] {
- if lenses[boxIndex][i].label == label {
- lenses[boxIndex] = append(lenses[boxIndex][:i], lenses[boxIndex][i+1:]...)
- break
- }
- }
- }
- }
- return lenses
- }
- func part2(steps []string) int {
- var result int
- lenses := getBoxes(steps)
- for i := range lenses {
- for j := range lenses[i] {
- result += (i + 1) * (j + 1) * lenses[i][j].power
- }
- }
- return result
- }
- func main() {
- if len(os.Args) < 2 {
- log.Fatal("You need to specify a file!")
- }
- steps := readInput(os.Args[1])
- fmt.Println("Part1:", part1(steps))
- fmt.Println("Part2:", part2(steps))
- }
|