package main import ( "fmt" "io" "log" "math" "strconv" "strings" ) const ( north = iota east south west ) type pos struct { dir int x int y int } func (s *pos) TurnLeft() { s.dir++ if s.dir > west { s.dir = north } } func (s *pos) TurnRight() { s.dir-- if s.dir < north { s.dir = west } } func (s *pos) CoordsToString() string { return strconv.Itoa(s.x) + "-" + strconv.Itoa(s.y) } func (s *pos) DistanceTravelled() int { return int(math.Abs(float64(s.y)) + math.Abs(float64(s.x))) } func (s *pos) Walk(dist int) { switch s.dir { case north: s.y += dist case east: s.x += dist case south: s.y -= dist case west: s.x -= dist } } func main() { var input string var readInp string travelLog := make(map[string]int) firstRepeat := false currPos := pos{dir: north, x: 0, y: 0} travelLog[currPos.CoordsToString()]++ for { _, err := fmt.Scan(&readInp) if err != nil { if err != io.EOF { log.Fatal(err) } break } input += readInp } for _, k := range strings.Split(input, ",") { k = strings.Trim(k, " ") if k[0] == 'R' { currPos.TurnRight() } else { currPos.TurnLeft() } tDist := atoi(k[1:]) for mvI := 0; mvI < tDist; mvI++ { currPos.Walk(1) if !firstRepeat && travelLog[currPos.CoordsToString()] > 0 { fmt.Println(" First Repeated Position: " + currPos.CoordsToString()) fmt.Println(" Distance: ", currPos.DistanceTravelled()) firstRepeat = true } travelLog[currPos.CoordsToString()]++ } } fmt.Println("End Position: ", currPos.x, ",", currPos.y) fmt.Println(" Distance: ", currPos.DistanceTravelled()) } func atoi(inp string) int { var err error var i int if i, err = strconv.Atoi(inp); err != nil { log.Fatal(err.Error()) } return i }