WellRecord.cs 2.3 KB

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