using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace D09._1 { public class VisitedList { public Place Visited; private VisitedList Next; public VisitedList(VisitedList list) => Next = list; public bool Contains(Place place) { if (Visited?.Equals(place) ?? false) return true; return Next?.Contains(place) ?? false; } public int Count() => 1 + Next?.Count() ?? 1; } public class Place { public string Name { get; } public Place(string name) => Name = name; public HashSet<(int distance, Place neighbor)> Neighbors = new HashSet<(int distance, Place neighbor)>(); public override bool Equals(object obj) { var place = obj as Place; return place != null && Name == place.Name; } public override int GetHashCode() { return HashCode.Combine(Name); } } class Program { static (int best, int worst) TestTravelRoutes(Dictionary places, Place start = null, VisitedList visited = null, int traveled = 0) { if (visited?.Count() == places.Count) return (traveled, traveled); int best = -1, worst = -1; foreach ((int distance, Place neighbor) in start?.Neighbors ?? places.Values.Select(v => (0, v))) { if (visited?.Contains(neighbor) ?? false) continue; (int b, int w) = TestTravelRoutes(places, neighbor, new VisitedList(visited) { Visited = start }, traveled + distance); if (best == -1 || b < best) best = b; if (w > worst) worst = w; } return (best, worst); } static void Main(string[] args) { if (args.Length < 1) throw new ArgumentException(); if (File.Exists(args[0]) == false) throw new FileNotFoundException(); Dictionary places = new Dictionary(); ParseFile(args, places); (int best, int worst) = TestTravelRoutes(places); Console.WriteLine($"The best distance is : {best}"); Console.WriteLine($"The worst distance is : {worst}"); } private static void ParseFile(string[] args, Dictionary places) { using (var file = File.OpenText(args[0])) { while (true) { var line = file.ReadLine(); if (line == null) break; var spl = line.Split(" = "); var ft = spl[0].Split(" to "); string from = ft[0], to = ft[1]; int distance = int.Parse(spl[1]); places.TryGetValue(from, out var placeFrom); places.TryGetValue(to, out var placeTo); if (placeFrom == null) { placeFrom = new Place(from); places.Add(from, placeFrom); } if (placeTo == null) { placeTo = new Place(to); places.Add(to, placeTo); } placeFrom.Neighbors.Add((distance, placeTo)); placeTo.Neighbors.Add((distance, placeFrom)); } } } } }