Program.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. namespace D17._1
  6. {
  7. public class ContainerList
  8. {
  9. public int Id { get; }
  10. public int Volume;
  11. public ContainerList Next;
  12. public ContainerList(int id) => Id = id;
  13. public bool Contains(int id)
  14. {
  15. var cur = this;
  16. bool found = false;
  17. while (cur != null && found == false)
  18. {
  19. if (cur.Id == id)
  20. found = true;
  21. cur = cur.Next;
  22. }
  23. return found;
  24. }
  25. public int Count() => 1 + (Next?.Count() ?? 0);
  26. public override int GetHashCode() => (Id > 0 ? 1 << Id : 0) + (Next?.GetHashCode() ?? 0);
  27. public override bool Equals(object obj) => obj is ContainerList list && list.GetHashCode() == GetHashCode();
  28. }
  29. class Program
  30. {
  31. static void TestCombinations(List<int> containers, HashSet<(ContainerList, int)> found, ContainerList containerComb = null, int totalVolume = 0, int it = 0)
  32. {
  33. if (found.Contains((containerComb, totalVolume))) return;
  34. found.Add((containerComb, totalVolume));
  35. if (totalVolume >= 150) return;
  36. for (int i = it; i < containers.Count; i++)
  37. {
  38. if (containerComb != null && containerComb.Contains(i)) continue;
  39. int volume = containers[i];
  40. TestCombinations(containers, found, new ContainerList(i) { Next = containerComb, Volume = volume }, totalVolume + volume, it + 1);
  41. }
  42. }
  43. static void Main(string[] args)
  44. {
  45. List<int> containers = new List<int>();
  46. HashSet<(ContainerList, int volume)> found = new HashSet<(ContainerList, int)>();
  47. ParseFile(args[0], containers);
  48. TestCombinations(containers, found);
  49. var validCombinations = found.Where(f => f.volume == 150);
  50. Console.WriteLine($"The part 1 answer is : {validCombinations.Count()}");
  51. int[] combn = new int[containers.Count];
  52. int mincount = CountAllComb(validCombinations, combn);
  53. Console.WriteLine($"The part 2 answer is : {combn[mincount]}");
  54. }
  55. private static int CountAllComb(IEnumerable<(ContainerList, int volume)> validCombinations, int[] combn)
  56. {
  57. int mincount = combn.Length;
  58. foreach (var comb in validCombinations)
  59. {
  60. var count = comb.Item1.Count();
  61. combn[count]++;
  62. if (count < mincount) mincount = count;
  63. }
  64. return mincount;
  65. }
  66. private static void ParseFile(string arg, List<int> containers)
  67. {
  68. using (var file = File.OpenText(arg))
  69. {
  70. while (true)
  71. {
  72. var line = file.ReadLine();
  73. if (line == null) break;
  74. containers.Add(int.Parse(line));
  75. }
  76. }
  77. }
  78. }
  79. }