DEV Community

Discussion on: Daily Challenge #6 - Grandma and her friends

Collapse
 
margo1993 profile image
margo1993
package utils

import (
    "errors"
    "math"
)

type CityDistance struct {
    City string
    Distance float64
}

func VisitFriend(friendsToVisit []string, friendsCities [][]string, cityDistances []CityDistance) (int, error) {
    totalDistance := 0.0

    var lastCityName string
    for _, friend := range friendsToVisit {
        friendCity, e := findFriendCity(friend, friendsCities)

        if e != nil {
            return 0, e
        }

        if lastCityName == "" {
            distanceToCity, e := findDistanceToCity(friendCity, cityDistances)

            if e != nil {
                return 0, e
            }

            totalDistance += distanceToCity
        } else {
            distanceBetweenCities, e := findDistanceBetweenCities(lastCityName, friendCity, cityDistances)

            if e != nil {
                return 0, e
            }

            totalDistance += distanceBetweenCities
        }

        lastCityName = friendCity
    }
    distanceBackToHome, _ := findDistanceToCity(lastCityName, cityDistances)

    totalDistance += distanceBackToHome
    return int(math.Floor(totalDistance)), nil
}

func findDistanceToCity(city string, cityDistances []CityDistance) (float64, error) {
    for _, cityDistance := range cityDistances {
        cityName := cityDistance.City
        distance := cityDistance.Distance

        if cityName == city {
            return distance, nil
        }
    }

    return 0, errors.New("Didn't find city")
}

func findDistanceBetweenCities(fromCity string, toCity string, cityDistances []CityDistance) (float64, error) {
    totalDistance := 0.0

    lastDistance := 0.0;
    for _, cityDistance := range cityDistances {
        city := cityDistance.City
        distance := cityDistance.Distance

        if lastDistance > 0 {
            totalDistance += math.Sqrt((lastDistance * lastDistance) + (distance * distance))
        }

        if (city == fromCity || city == toCity) && lastDistance > 0 {
            return totalDistance, nil
        }

        if (city == fromCity || city == toCity) || lastDistance > 0 {
            lastDistance = distance
        }
    }

    return 0, errors.New("Didn't find city")
}

func findFriendCity(friend string, friendCities [][]string) (string, error) {
    for _, friendCity := range friendCities {
        if friend == friendCity[0] {
            return friendCity[1], nil
        }
    }

    return "", errors.New("Didn't found city for friend!")
}