77 lines
3.4 KiB
C#
77 lines
3.4 KiB
C#
namespace AdventOfCode.Solutions._2023
|
|
{
|
|
public partial class Day12 : IChallange
|
|
{
|
|
public int Year => 2023;
|
|
public int Day => 12;
|
|
|
|
private readonly InputReader _inputReader;
|
|
|
|
public Day12(InputReader inputReader)
|
|
{
|
|
_inputReader = inputReader;
|
|
_inputReader.SetInput(this);
|
|
}
|
|
|
|
public async Task<string> GetSolutionPart1()
|
|
{
|
|
long total = 0;
|
|
await foreach(string line in _inputReader.ReadAsStringLine())
|
|
{
|
|
string[] splitted = line.Split(' ');
|
|
int[] groups = splitted[1].Split(',').Select(int.Parse).ToArray();
|
|
|
|
long possiblies = Possibilities([], splitted[0], groups, 0, 0, 0);
|
|
total += possiblies;
|
|
}
|
|
return total.ToString();
|
|
}
|
|
|
|
public async Task<string> GetSolutionPart2()
|
|
{
|
|
long total = 0;
|
|
await foreach (string line in _inputReader.ReadAsStringLine())
|
|
{
|
|
string[] splitted = line.Split(' ');
|
|
var joinedLine = string.Join("?", [splitted[0], splitted[0], splitted[0], splitted[0], splitted[0]]);
|
|
int[] groups = splitted[1].Split(',').Select(int.Parse).ToArray();
|
|
int[] groupsTotal = groups.Concat(groups).Concat(groups).Concat(groups).Concat(groups).ToArray();
|
|
|
|
long possiblies = Possibilities([], joinedLine, groupsTotal, 0, 0, 0);
|
|
total += possiblies;
|
|
}
|
|
return total.ToString();
|
|
}
|
|
|
|
private static long Possibilities(Dictionary<(int, int, int), long> capturedCache, string stringToValidate, int[] captureGroups, int stringIndex, int groupIndex, int currentCaptureLength)
|
|
{
|
|
if (capturedCache.TryGetValue((stringIndex, groupIndex, currentCaptureLength), out var possibilities))
|
|
return possibilities;
|
|
|
|
if (stringIndex == stringToValidate.Length) // End of string
|
|
return groupIndex == captureGroups.Length || (groupIndex == captureGroups.Length - 1 && captureGroups[groupIndex] == currentCaptureLength) ? 1 : 0;
|
|
possibilities = 0L;
|
|
|
|
if (stringToValidate[stringIndex] is '.' or '?') // Assuming '?' is '.'
|
|
{
|
|
if (currentCaptureLength == 0) // Start a capture
|
|
{
|
|
possibilities += Possibilities(capturedCache, stringToValidate, captureGroups, stringIndex + 1, groupIndex, 0); // Not in capture. Skip to next char
|
|
}
|
|
else if (currentCaptureLength == captureGroups[groupIndex]) // After a capture
|
|
{
|
|
possibilities += Possibilities(capturedCache, stringToValidate, captureGroups, stringIndex + 1, groupIndex + 1, 0); // Captured group. Go to next group
|
|
}
|
|
}
|
|
|
|
if (stringToValidate[stringIndex] is '#' or '?' && groupIndex < captureGroups.Length && currentCaptureLength < captureGroups[groupIndex]) // Assuming '?' is '#'
|
|
{
|
|
possibilities += Possibilities(capturedCache, stringToValidate, captureGroups, stringIndex + 1, groupIndex, currentCaptureLength + 1); // In capture
|
|
}
|
|
|
|
// Add the capture to the capture cache
|
|
capturedCache[(stringIndex, groupIndex, currentCaptureLength)] = possibilities;
|
|
return possibilities;
|
|
}
|
|
}
|
|
} |