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 }