package main // getload returns the load of all boulders for a single image func getload(raw []string) int { load := 0 for _, line := range raw { for i, r := range line { if r == 'O' { load += (i + 1) } } } return load } // spacesToRight determines the number of spaces right of a boulder func spacesToRight(i int, line string) int { num := 0 outer: for i += 1; i < len(line); i++ { switch line[i] { case '.': num++ case '#', 'O': break outer } } return num } // rollRight rolls a boulder right until there's no space func rollRight(line string) string { for i := len(line) - 1; i >= 0; i-- { if line[i] == 'O' { n := spacesToRight(i, line) if n == 0 { continue } line = replaceAtIndex(line, '.', i) line = replaceAtIndex(line, 'O', i+n) } } return line } // one returns the load of all boulders after a single image transposition+roll func one(lines []string) int { image := newImg(len(lines)) copy(image.raw, lines) for i, line := range image.transposed() { image.raw[i] = rollRight(line) } return getload(image.raw) }