package main import ( "bufio" "fmt" "log" "os" "strconv" "strings" ) func main() { input := stdinToStringSlice() var verbose, pt2 bool var allDiscs []Disc if len(os.Args) > 1 { for i := range os.Args { switch os.Args[i] { case "-2": // Do part 2 pt2 = true case "-v": // Verbose mode verbose = true } } } for i := range input { pts := strings.Fields(input[i]) id := atoi(pts[1][1:]) ttl := atoi(pts[3]) curr := atoi(pts[11][0 : len(pts[11])-1]) allDiscs = append(allDiscs, *CreateDisc(id, ttl, curr)) } if pt2 { d := CreateDisc(7, 11, 0) allDiscs = append(allDiscs, *d) } var numTicks int for !AllDiscsAlign(allDiscs) { numTicks++ TickAllDiscs(allDiscs) if verbose { PrintStatus(allDiscs) } } fmt.Println("Total Ticks: ", numTicks) } func PrintStatus(d []Disc) { fmt.Print("[ ") for i := range d { fmt.Printf("(%2d/%2d) ", d[i].currPos, d[i].ttlPos) } fmt.Println("]") } func TickAllDiscs(d []Disc) { for i := range d { d[i].Tick() } } func AllDiscsAlign(d []Disc) bool { for i := range d { if (d[i].currPos+d[i].id)%d[i].ttlPos != 0 { return false } } return true } type Disc struct { id int ttlPos int currPos int startPos int numTicks int bufTicks int } func CreateDisc(id, ttl, curr int) *Disc { d := new(Disc) d.id = id d.ttlPos = ttl d.currPos = curr d.startPos = curr return d } func (d *Disc) Tick() { d.currPos = (d.currPos + 1) % d.ttlPos d.numTicks++ } func stdinToStringSlice() []string { var input []string scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { input = append(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 } func ClearScreen() { fmt.Print("\033[H\033[2J") }