Advertisement
mgla

Advent of Code 2023 - Day 12

Dec 12th, 2023
2,224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.93 KB | None | 0 0
  1. var input = File.ReadAllLines("input.txt");
  2.  
  3. var part1 = 0L;
  4. var part2 = 0L;
  5. var cache = new Dictionary<string, long>();
  6.  
  7. foreach (var line in input.Select(l => l.Split(' ')))
  8. {
  9.     var springs = line[0];
  10.     var groups = line[1].Split(',').Select(int.Parse).ToList();
  11.    
  12.     part1 += Calculate(springs, groups);
  13.  
  14.     springs = string.Join('?', Enumerable.Repeat(springs, 5));
  15.     groups = Enumerable.Repeat(groups, 5).SelectMany(g => g).ToList();
  16.  
  17.     part2 += Calculate(springs, groups);
  18. }
  19.  
  20. Console.WriteLine($"Part1: {part1}");
  21. Console.WriteLine($"Part2: {part2}");
  22. return;
  23.  
  24. long Calculate(string springs, List<int> groups)
  25. {
  26.     var key = $"{springs},{string.Join(',', groups)}";  // Cache key: spring pattern + group lengths
  27.  
  28.     if (cache.TryGetValue(key, out var value))
  29.     {
  30.         return value;
  31.     }
  32.    
  33.     value = GetCount(springs, groups);
  34.     cache[key] = value;
  35.  
  36.     return value;
  37. }
  38.  
  39. long GetCount(string springs, List<int> groups)
  40. {
  41.     while (true)
  42.     {
  43.         if (groups.Count == 0)
  44.         {
  45.             return springs.Contains('#') ? 0 : 1; // No more groups to match: if there are no springs left, we have a match
  46.         }
  47.  
  48.         if (string.IsNullOrEmpty(springs))
  49.         {
  50.             return 0; // No more springs to match, although we still have groups to match
  51.         }
  52.  
  53.         if (springs.StartsWith('.'))
  54.         {
  55.             springs = springs.Trim('.'); // Remove all dots from the beginning
  56.             continue;
  57.         }
  58.  
  59.         if (springs.StartsWith('?'))
  60.         {
  61.             return Calculate("." + springs[1..], groups) + Calculate("#" + springs[1..], groups); // Try both options recursively
  62.         }
  63.  
  64.         if (springs.StartsWith('#')) // Start of a group
  65.         {
  66.             if (groups.Count == 0)
  67.             {
  68.                 return 0; // No more groups to match, although we still have a spring in the input
  69.             }
  70.  
  71.             if (springs.Length < groups[0])
  72.             {
  73.                 return 0; // Not enough characters to match the group
  74.             }
  75.  
  76.             if (springs[..groups[0]].Contains('.'))
  77.             {
  78.                 return 0; // Group cannot contain dots for the given length
  79.             }
  80.  
  81.             if (groups.Count > 1)
  82.             {
  83.                 if (springs.Length < groups[0] + 1 || springs[groups[0]] == '#')
  84.                 {
  85.                     return 0; // Group cannot be followed by a spring, and there must be enough characters left
  86.                 }
  87.  
  88.                 springs = springs[(groups[0] + 1)..]; // Skip the character after the group - it's either a dot or a question mark
  89.                 groups = groups[1..];
  90.                 continue;
  91.             }
  92.  
  93.             springs = springs[groups[0]..]; // Last group, no need to check the character after the group
  94.             groups = groups[1..];
  95.             continue;
  96.         }
  97.  
  98.         throw new Exception("Invalid input");
  99.     }
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement