diff --git a/day15/dayFifteen.go b/day15/dayFifteen.go index 82cc34d..ace51b4 100644 --- a/day15/dayFifteen.go +++ b/day15/dayFifteen.go @@ -2,13 +2,18 @@ package day15 import ( "fmt" + "log" "os" + "regexp" + "slices" + "strconv" "strings" ) func Run() int { fmt.Println("hello day 15") - filename := "day15/input" + log.Println("hello day 15") + filename := "day15/example" bytes, err := os.ReadFile(filename) if err != nil { panic(fmt.Sprint("error reading file ", filename)) @@ -19,9 +24,116 @@ func Run() int { result := 0 - for _, instruction := range instructions { - result += ASCIIStringHash(instruction) + boxes := make([]Box, 256) + for i, box := range boxes { + box.Focals = make(map[string]int) + boxes[i] = box } + + for _, instructionStr := range instructions { + i := ReadInstruction(instructionStr) + box := boxes[i.Box] + box.Act(i) + boxes[i.Box] = box + + // result += ASCIIStringHash(instruction) + } + + for i, box := range boxes { + if len(box.Labels) != 0 { + log.Printf("%d box %+v final state\n", i, box) + } + result += (i + 1) * box.FocusingPower() + } + + return result +} + +type Box struct { + Labels []string + Focals map[string]int +} + +func (b *Box)Act(i Instruction) { + log.Printf("for box %+v instruction \n%s\n", b, i.String()) + switch i.Action { + case Put: + _, found := b.Focals[i.Label] + if !found { + b.Labels = append(b.Labels, i.Label) + } + b.Focals[i.Label] = i.LensFocal + + case Remove: + _, found := b.Focals[i.Label] + if !found { + return + } + index := slices.Index(b.Labels, i.Label) + delete(b.Focals, i.Label) + b.Labels = slices.Delete(b.Labels, index, index+1) + } + log.Printf("result : %+v\n", b) + return +} + +func (b *Box)FocusingPower() int { + result := 0 + for i, label := range b.Labels { + result += (i + 1) * b.Focals[label] + } + return result +} + +type Action rune + +const ( + Put Action = '=' + Remove = '-' +) + +type Instruction struct { + Label string + Box int + Action Action + LensFocal int +} + +func (i *Instruction) String() string { + operation := "" + switch i.Action { + case Put: + operation = "put into" + case Remove: + operation = "remove from" + } + return fmt.Sprintf("%s\t\t%d of focal %d %s", operation, i.Box, i.LensFocal, i.Label) +} + +func ReadInstruction(str string) Instruction { + result := Instruction{} + + re := regexp.MustCompile(`(?P