package day05 import ( "strconv" "strings" ) type Solver struct { instructions []Instruction stacks []Stack } type Instruction struct { count, from, to int } type Stack struct { containers []string } func (s *Stack) putAtBottom(container string) { s.containers = append([]string{container}, s.containers...) } func (s *Stack) putAtTop(container string) { s.containers = append(s.containers, container) } func (s *Stack) putNAtTop(containers []string) { s.containers = append(s.containers, containers...) } func (s *Stack) popFromTop() string { c := s.containers[len(s.containers)-1] s.containers = s.containers[:len(s.containers)-1] return c } func (s *Stack) popNFromTop(n int) []string { // a b c d; n == 2; len() = 4; indexes = len() - n, : c := s.containers[len(s.containers)-n:] s.containers = s.containers[:len(s.containers)-n] return c } func (s *Stack) peekTop() string { return s.containers[len(s.containers)-1] } func (s *Solver) ParseInput(input []string) { var containerList []string var instructionsLineIndex int for i, line := range input { if line == "" { instructionsLineIndex = i + 1 break } containerList = append(containerList, line) } stackCountLine := []byte(containerList[len(containerList)-1]) numStacks, _ := strconv.Atoi(string(stackCountLine[len(stackCountLine)-2])) s.stacks = make([]Stack, numStacks) for i := 0; i < len(containerList)-1; i++ { for _s := 0; _s < numStacks; _s += 1 { // 0 -> 1; 1 -> 5; 2 -> 9 c := string([]byte(containerList[i])[4*_s+1]) if c != " " { s.stacks[_s].putAtBottom(c) } } } for _, line := range input[instructionsLineIndex:] { tokens := strings.Split(line, " ") count, _ := strconv.Atoi(tokens[1]) from, _ := strconv.Atoi(tokens[3]) to, _ := strconv.Atoi(tokens[5]) s.instructions = append(s.instructions, Instruction{count, from, to}) } } func (s *Solver) SolvePart1() any { for _, instr := range s.instructions { for c := 0; c < instr.count; c += 1 { x := s.stacks[instr.from-1].popFromTop() s.stacks[instr.to-1].putAtTop(x) } } var r string for _, s := range s.stacks { r += s.peekTop() } return r } func (s *Solver) SolvePart2() any { for _, instr := range s.instructions { x := s.stacks[instr.from-1].popNFromTop(instr.count) s.stacks[instr.to-1].putNAtTop(x) } var r string for _, s := range s.stacks { r += s.peekTop() } return r }