82 lines
1.3 KiB
Go
82 lines
1.3 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
inp := StdinToString()
|
||
|
pts := strings.Split(inp, "\t")
|
||
|
var bnks []int
|
||
|
for i := range pts {
|
||
|
bnks = append(bnks, Atoi(pts[i]))
|
||
|
}
|
||
|
process(bnks)
|
||
|
}
|
||
|
|
||
|
func process(bnks []int) {
|
||
|
var states []string
|
||
|
var dupe bool
|
||
|
var dupeIdx int
|
||
|
for !dupe {
|
||
|
balance(bnks)
|
||
|
newBnks := fmt.Sprint(bnks)
|
||
|
for i := range states {
|
||
|
if states[i] == newBnks {
|
||
|
dupeIdx = i
|
||
|
dupe = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
states = append(states, newBnks)
|
||
|
if dupe {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
fmt.Println("= Part 1 =")
|
||
|
fmt.Println("Duplicate at step:", len(states))
|
||
|
fmt.Println("= Part 2 =")
|
||
|
fmt.Println("Loop size:", len(states)-dupeIdx-1)
|
||
|
}
|
||
|
|
||
|
func balance(bnks []int) {
|
||
|
var max int
|
||
|
for i := range bnks {
|
||
|
if bnks[i] > bnks[max] {
|
||
|
max = i
|
||
|
}
|
||
|
}
|
||
|
// bnks[max] should be the highest, let's redistribute it
|
||
|
var dist, idx int
|
||
|
dist, bnks[max], idx = bnks[max], 0, (max+1)%len(bnks)
|
||
|
for dist > 0 {
|
||
|
bnks[idx]++
|
||
|
idx = (idx + 1) % len(bnks)
|
||
|
dist--
|
||
|
}
|
||
|
// Should be balanced now
|
||
|
}
|
||
|
|
||
|
func StdinToString() string {
|
||
|
var input string
|
||
|
scanner := bufio.NewScanner(os.Stdin)
|
||
|
for scanner.Scan() {
|
||
|
input = scanner.Text()
|
||
|
}
|
||
|
return input
|
||
|
}
|
||
|
|
||
|
func Atoi(i string) int {
|
||
|
var ret int
|
||
|
var err error
|
||
|
if ret, err = strconv.Atoi(i); err != nil {
|
||
|
log.Fatal("Invalid Atoi")
|
||
|
}
|
||
|
return ret
|
||
|
}
|