WellRecord.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System.Collections.Specialized;
  2. namespace Day12;
  3. public class WellRecord
  4. {
  5. private readonly string _record;
  6. private readonly int[] _checksum;
  7. public static readonly Dictionary<string, long> MemoMap = new Dictionary<string, long>();
  8. public WellRecord(string record, int[] checksum)
  9. {
  10. _record = record;
  11. _checksum = checksum;
  12. }
  13. public long Count(int multiply)
  14. {
  15. var input = string.Join("?", Enumerable.Repeat(_record, multiply));
  16. var values = Enumerable.Repeat(_checksum, multiply).SelectMany(x => x).ToArray();
  17. Console.WriteLine($"{input} => {string.Join(", ", values)}");
  18. return CountPermuations(input, values);
  19. }
  20. private long CountPermuations(string tail, int[] values)
  21. {
  22. var key = Key(tail, values);
  23. if (MemoMap.TryGetValue(key, out long count))
  24. {
  25. return count;
  26. }
  27. if (tail == String.Empty)
  28. {
  29. // when the tail is empty and we have no runs left then that is valid, otherwise invalid
  30. return values.Length == 0 ? 1 : 0;
  31. }
  32. if (values.Length == 0)
  33. {
  34. // no remaining runs to count - if there are still # left in the tail then that is invalid, otherwise valid
  35. return tail.Contains('#') ? 0 : 1;
  36. }
  37. var dotCount = 0L;
  38. var hashCount = 0L;
  39. if (tail[0] is '.' or '?')
  40. {
  41. dotCount = CountPermuations(tail[1..], values);
  42. }
  43. if (tail[0] is '#' or '?' && tail.Length >= values[0])
  44. {
  45. var hasRunOfN = !tail[..values[0]].Contains('.');
  46. if (tail.Length > values[0] && hasRunOfN && tail[values[0]] != '#')
  47. {
  48. hashCount = CountPermuations(tail[(values[0] + 1)..], values.Skip(1).ToArray());
  49. }
  50. else if (tail.Length == values[0] && hasRunOfN)
  51. {
  52. hashCount = CountPermuations(tail[values[0]..], values.Skip(1).ToArray());
  53. }
  54. }
  55. var result = dotCount + hashCount;
  56. MemoMap[key] = result;
  57. return result;
  58. }
  59. private static string Key(string tail, int[] values)
  60. {
  61. return tail + string.Join(",", values);
  62. }
  63. }