Program.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. namespace D09._1
  6. {
  7. public class VisitedList
  8. {
  9. public Place Visited;
  10. private VisitedList Next;
  11. public VisitedList(VisitedList list) => Next = list;
  12. public bool Contains(Place place)
  13. {
  14. if (Visited?.Equals(place) ?? false) return true;
  15. return Next?.Contains(place) ?? false;
  16. }
  17. public int Count() => 1 + Next?.Count() ?? 1;
  18. }
  19. public class Place
  20. {
  21. public string Name { get; }
  22. public Place(string name) => Name = name;
  23. public HashSet<(int distance, Place neighbor)> Neighbors = new HashSet<(int distance, Place neighbor)>();
  24. public override bool Equals(object obj)
  25. {
  26. var place = obj as Place;
  27. return place != null &&
  28. Name == place.Name;
  29. }
  30. public override int GetHashCode()
  31. {
  32. return HashCode.Combine(Name);
  33. }
  34. }
  35. class Program
  36. {
  37. static (int best, int worst) TestTravelRoutes(Dictionary<string, Place> places, Place start = null, VisitedList visited = null, int traveled = 0)
  38. {
  39. if (visited?.Count() == places.Count)
  40. return (traveled, traveled);
  41. int best = -1, worst = -1;
  42. foreach ((int distance, Place neighbor) in start?.Neighbors ?? places.Values.Select(v => (0, v)))
  43. {
  44. if (visited?.Contains(neighbor) ?? false) continue;
  45. (int b, int w) = TestTravelRoutes(places, neighbor, new VisitedList(visited) { Visited = start }, traveled + distance);
  46. if (best == -1 || b < best) best = b;
  47. if (w > worst) worst = w;
  48. }
  49. return (best, worst);
  50. }
  51. static void Main(string[] args)
  52. {
  53. if (args.Length < 1) throw new ArgumentException();
  54. if (File.Exists(args[0]) == false) throw new FileNotFoundException();
  55. Dictionary<string, Place> places = new Dictionary<string, Place>();
  56. ParseFile(args, places);
  57. (int best, int worst) = TestTravelRoutes(places);
  58. Console.WriteLine($"The best distance is : {best}");
  59. Console.WriteLine($"The worst distance is : {worst}");
  60. }
  61. private static void ParseFile(string[] args, Dictionary<string, Place> places)
  62. {
  63. using (var file = File.OpenText(args[0]))
  64. {
  65. while (true)
  66. {
  67. var line = file.ReadLine();
  68. if (line == null) break;
  69. var spl = line.Split(" = ");
  70. var ft = spl[0].Split(" to ");
  71. string from = ft[0], to = ft[1];
  72. int distance = int.Parse(spl[1]);
  73. places.TryGetValue(from, out var placeFrom);
  74. places.TryGetValue(to, out var placeTo);
  75. if (placeFrom == null)
  76. {
  77. placeFrom = new Place(from);
  78. places.Add(from, placeFrom);
  79. }
  80. if (placeTo == null)
  81. {
  82. placeTo = new Place(to);
  83. places.Add(to, placeTo);
  84. }
  85. placeFrom.Neighbors.Add((distance, placeTo));
  86. placeTo.Neighbors.Add((distance, placeFrom));
  87. }
  88. }
  89. }
  90. }
  91. }