Skip to main content
Source Link
Peter Dongan
  • 2.3k
  • 1
  • 16
  • 27

Best route: 7, 5, 6, 2, 10, 4

Tastiness metric: 2.8945153290979557

Total distance travelled: 33.51165531060739

Total tastiness: 97

I computed the distances between each node once and stored the results in a two dimensional array [to, from].

I used a simple approach to traversal by treating decimal integers as expressions of the routes and just iterating through them from 0 to 98765432, skipping any with repeated digits, and adding a leading 0 where appropriate. (0 = node ten.)


using System.Drawing;

var crawler = new TacoCrawler();
crawler.ShowBestCrawl();


public class TacoCrawler
{
    readonly int[] _tastinessArray;
    readonly double[,] _distances;

    int _bestTotalTastiness = 0;
    double _bestMetric = 0;
    string _bestRoute = "";
    double _bestRouteDistance = 0;


    public TacoCrawler()
    {
        _tastinessArray = InitializeTastinesses();
        _distances = InitializeDistances();
    }


    public void ShowBestCrawl()
    {
        var startedAt = DateTime.Now;
        for (var n = 0; n < 100000000; n++) // Iterate through every route expressed as a number with up to eight digits. Filter out any with the same digit twice.
        {
            var routeString = n.ToString();

            if (!CheckForRepeatedDigits(routeString))
            {
                ComputeTastiness(routeString);

                if (n < 10000000 && !routeString.Contains('0'))  // If the route doesn't contain 0 (node 10) and includes fewer than 8 nodes, also check starting from 0 .
                {
                    routeString = "0" + routeString;
                    ComputeTastiness(routeString);
                }
            }
        }

        var finishedAt = DateTime.Now;
        var timeTaken = finishedAt - startedAt;

        Console.WriteLine("Best route: " + PrettifyRouteString(_bestRoute));
        Console.WriteLine("Tastiness metric: " + _bestMetric.ToString());
        Console.WriteLine("Total distance travelled: " + _bestRouteDistance.ToString());
        Console.WriteLine("Total tastiness: " + _bestTotalTastiness.ToString());
        Console.WriteLine("Computation time (s): " + timeTaken.Seconds);

    }


    static double GetDistanceBetweenPoints(Point p1, Point p2)
    {
        return Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y));
    }

    // Check if the string contains more than one instance of any character.
    static bool CheckForRepeatedDigits(string iString)
    {
        for (var j = 0; j < iString.Length - 1; j++)
        {
            if (iString[(j + 1)..].Contains(iString[j]))
            {
                return true;
            }
        }
        return false;

    }

    static string PrettifyRouteString(string route)
    {
        var prettyRoute = route[..1];
        for (var i = 1; i < route.Length; i++)
        {
            prettyRoute += ", " + route[i];
        }
        prettyRoute = prettyRoute.Replace("0", "10");
        return prettyRoute;
    }

    // Compute the distances between each node and store the results in a 2d array [from,to]. An additional element in the to category is used to store the distance between the node and the origin.
    static double[,] InitializeDistances()
    {

        var locations = InitializeLocations();

        var distances = new double[10, 11];
        for (var from = 0; from < 10; from++)
        {
            for (var to = 0; to < 10; to++)
            {
                distances[from, to] = GetDistanceBetweenPoints(locations[from], locations[to]);
            }
            distances[from, 10] = GetDistanceBetweenPoints(locations[from], new Point(0, 0));
        }
        return distances;
    }

    static int[] InitializeTastinesses()
    {
        var tastinessArray = new int[]
        {
        18, // 10 = 0
        7,
        17,
        8,
        30,
        12,
        15,
        5,
        12,
        3
        };
        return tastinessArray;
    }

    static Point[] InitializeLocations()
    {
        var locationArray = new Point[]
        {
        new Point(14, 13),
        new Point(2, 8),
        new Point(15, 3),
        new Point(6, 6),
        new Point(20, 15),
        new Point(11, 2),
        new Point(14, 1),
        new Point(7, 3),
        new Point(1, 12),
        new Point(3, 6)
        };
        return locationArray;
    }

    void ComputeTastiness(string routeString)
    {
        // Get the distance to and tastiness of the first node.
        var firstNode = int.Parse(routeString[0].ToString());
        int currentRouteTotalTastiness = _tastinessArray[firstNode];
        double currentRouteDistance = _distances[firstNode, 10];

        // Get the distance to and tastiness of every subsequent node
        for (var i = 0; i < routeString.Length - 1; i++)
        {
            var from = int.Parse(routeString[i].ToString());
            var to = int.Parse(routeString[i + 1].ToString());
            currentRouteDistance += _distances[from, to];
            currentRouteTotalTastiness += _tastinessArray[to];
        }

        var totalTastinessMetric = currentRouteTotalTastiness / currentRouteDistance;

        if (totalTastinessMetric > _bestMetric)
        {
            _bestMetric = totalTastinessMetric;
            _bestRoute = routeString;
            _bestRouteDistance = currentRouteDistance;
            _bestTotalTastiness = currentRouteTotalTastiness;
        }
    }

}