Program.cs 3.6 KB

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