119 lines
1.8 KiB
Go
119 lines
1.8 KiB
Go
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")
|
|
}
|