/// <summary>
        /// Builds an <see cref="IPath"/> instance based on the provided <paramref name="railwaySystem"/> and <paramref name="townsNames"/>.
        /// </summary>
        /// <param name="railwaySystem">An instance of <see cref="RailwaySystem"/>.</param>
        /// <param name="townsNames">An <see cref="string"/> array with the sequence of towns that constitutes the <see cref="IPath"/>.</param>
        /// <returns>An instance of <see cref="IPath"/>.</returns>
        public IPath Build(IRailwaySystem railwaySystem, params string[] townsNames)
        {
            var path = new Path();

            foreach (var townName in townsNames)
            {
                path.AddStop(railwaySystem.GetTownByName(townName));
            }
            return(path);
        }
Exemple #2
0
        /// <summary>
        /// Finds the shortest possible <see cref="ITrip"/> between two <see cref="ITown"/>s.
        /// </summary>
        /// <param name="railwaySystem">An instance of <see cref="IRailwaySystem"/>.</param>
        /// <param name="from">The <see cref="ITown"/> from where the trip begins.</param>
        /// <param name="to">The <see cref="ITown"/> to where the trip ends.</param>
        /// <exception cref="InvalidRouteException">Thrown whenever no <see cref="ITrip"/> between the two <see cref="ITown"/>s exists.</exception>
        /// <returns>The instance of the shortest <see cref="ITrip"/> found.</returns>
        public ITrip FindShortest(IRailwaySystem railwaySystem, ITown from, ITown to)
        {
            var shortestPath = new Dictionary <ITown, Route>();
            var distances    = new Dictionary <ITown, int>();
            var actualTowns  = railwaySystem.GetTowns() as List <ITown> ?? railwaySystem.GetTowns().ToList();

            foreach (var town in actualTowns)
            {
                distances[town] = town.Equals(from) ? 0 : int.MaxValue;
            }
            if (from.CloneIfEquals(to, out var clonedFrom, $"{from.Name}_"))
            {
                actualTowns.Add(clonedFrom);
                distances[to]         = int.MaxValue;
                distances[clonedFrom] = 0;
            }

            while (actualTowns.Count != 0)
            {
                // This is bad. Should use a Binary Heap instead, but .NET doesn't have one by default like Java's Priority Queue.
                var actualShortest = actualTowns.OrderBy(t => distances[t]).First();
                actualTowns.Remove(actualShortest);

                if (distances[actualShortest] == int.MaxValue)
                {
                    break;
                }

                if (actualShortest.Equals(to))
                {
                    var path = new Trip(from);
                    while (shortestPath.ContainsKey(actualShortest))
                    {
                        path.AddRoute(shortestPath[actualShortest]);
                        actualShortest = shortestPath[actualShortest].From;
                    }

                    return(path);
                }

                foreach (var route in actualShortest.Routes)
                {
                    var actualDistance = distances[actualShortest] + route.Distance;
                    if (actualDistance >= distances[route.To])
                    {
                        continue;
                    }
                    distances[route.To]    = actualDistance;
                    shortestPath[route.To] = route;
                }
            }

            throw new InvalidRouteException($"There's no such route from '{from}' to '{to}'.");
        }
Exemple #3
0
        /// <summary>
        /// Writes the expected program outputs to the stdout.
        /// </summary>
        /// <param name="railwaySystem">An instance of <see cref="IRailwaySystem"/>.</param>
        private static void WriteOutput(IRailwaySystem railwaySystem)
        {
            var tripService = new TripService();
            var pathBuilder = new PathBuilder();

            Console.WriteLine();
            SafeWriteOutput(1, () => tripService.ResolveDistance(pathBuilder.Build(railwaySystem, "A", "B", "C")).ToString());
            SafeWriteOutput(2, () => tripService.ResolveDistance(pathBuilder.Build(railwaySystem, "A", "D")).ToString());
            SafeWriteOutput(3, () => tripService.ResolveDistance(pathBuilder.Build(railwaySystem, "A", "D", "C")).ToString());
            SafeWriteOutput(4, () => tripService.ResolveDistance(pathBuilder.Build(railwaySystem, "A", "E", "B", "C", "D")).ToString());
            SafeWriteOutput(5, () => tripService.ResolveDistance(pathBuilder.Build(railwaySystem, "A", "E", "D")).ToString());
            Console.WriteLine($"Output #6: {tripService.Search(railwaySystem.GetTownByName("C"), railwaySystem.GetTownByName("C"), trip => trip.Stops > 3).Count()}");
            Console.WriteLine($"Output #7: {tripService.Search(railwaySystem.GetTownByName("A"), railwaySystem.GetTownByName("C"), trip => trip.Stops > 4, trip => trip.Stops == 4).Count()}");
            SafeWriteOutput(8, () => tripService.FindShortest(railwaySystem, railwaySystem.GetTownByName("A"), railwaySystem.GetTownByName("C")).TotalDistance.ToString());
            SafeWriteOutput(9, () => tripService.FindShortest(railwaySystem, railwaySystem.GetTownByName("B"), railwaySystem.GetTownByName("B")).TotalDistance.ToString());
            Console.WriteLine($"Output #10: {tripService.Search(railwaySystem.GetTownByName("C"), railwaySystem.GetTownByName("C"), trip => trip.TotalDistance >= 30).Count()}");
            Console.WriteLine();
        }