141 lines
5.2 KiB
C#
141 lines
5.2 KiB
C#
using AdventOfCode.Core;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace AdventOfCode.Solutions._2023
|
|
{
|
|
public partial class Day12(InputReader reader) : IChallange
|
|
{
|
|
private InputReader _inputReader = reader;
|
|
|
|
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();
|
|
|
|
total += Possibilities(splitted[0], groups);
|
|
}
|
|
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("?", new[] { 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();
|
|
|
|
total += Possibilities2(joinedLine, groupsTotal, 0, 0, 0);
|
|
}
|
|
return total.ToString();
|
|
}
|
|
|
|
private long Possibilities(string lineToValidate, int[] groups)
|
|
{
|
|
long total = 0;
|
|
if (lineToValidate.Contains('?'))
|
|
{
|
|
var regex = new Regex(Regex.Escape("?"));
|
|
total += Possibilities(regex.Replace(lineToValidate, ".", 1), groups);
|
|
total += Possibilities(regex.Replace(lineToValidate, "#", 1), groups);
|
|
|
|
return total;
|
|
}
|
|
|
|
MatchCollection matches = GroupMatch().Matches(lineToValidate);
|
|
|
|
if (matches.Count == groups.Length &&
|
|
groups.Where((g, i) => matches[i].Length == g).Count() == groups.Length)
|
|
{
|
|
//Console.WriteLine($"{lineToValidate} is valid");
|
|
return 1;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
private long Possibilities2(string lineToValidate, int[] groups, int readIndex, int groupIndex, int captureSize)
|
|
{
|
|
// if group index is 0 there are no captures and not captures ruynning
|
|
if (groupIndex > 0)
|
|
{
|
|
int[] splitGroups = lineToValidate.Split('.', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Length).ToArray();
|
|
|
|
// something to validate!
|
|
if (readIndex < lineToValidate.Length && // not reached the end
|
|
lineToValidate[readIndex] == '.' && // possible end of capture
|
|
captureSize > 0) // in capture mode but with a . caputure has ended
|
|
{
|
|
for (int i = 0; i < groupIndex; i++)
|
|
{
|
|
if (splitGroups[i] != groups[i])
|
|
{
|
|
Console.WriteLine($"{lineToValidate} is invalid");
|
|
return 0; // group lengths do not match, reject
|
|
}
|
|
}
|
|
|
|
// valid so far
|
|
// reset the capture size
|
|
groupIndex++;
|
|
captureSize = 0;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
if (!lineToValidate.Contains('?')) // no more variations
|
|
{
|
|
int[] splitGroups = lineToValidate.Split('.', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Length).ToArray();
|
|
for (int i = 0; i < groups.Length; i++)
|
|
{
|
|
if (splitGroups[i] != groups[i])
|
|
{
|
|
Console.WriteLine($"{lineToValidate} is invalid");
|
|
return 0; // group lengths do not match, reject
|
|
}
|
|
}
|
|
|
|
// not invalid combos so valid
|
|
return 1;
|
|
}
|
|
|
|
//if (lineToValidate[readIndex] is '.' )
|
|
|
|
long total = 0;
|
|
//go search for # or ?
|
|
for (int charIndex = readIndex; charIndex < lineToValidate.Length; charIndex++)
|
|
{
|
|
if (lineToValidate[charIndex] == '.')
|
|
{
|
|
readIndex++;
|
|
continue;
|
|
}
|
|
|
|
if (lineToValidate[charIndex] == '#')
|
|
{
|
|
total += Possibilities2(lineToValidate, groups, readIndex + 1, groupIndex + 1, captureSize + 1);
|
|
break;
|
|
}
|
|
|
|
if (lineToValidate[charIndex] == '?')
|
|
{
|
|
var regex = new Regex(Regex.Escape("?"));
|
|
total += Possibilities2(regex.Replace(lineToValidate, ".", 1), groups, readIndex + 1, groupIndex, captureSize);
|
|
total += Possibilities2(regex.Replace(lineToValidate, "#", 1), groups, readIndex + 1, groupIndex, captureSize + 1);
|
|
return total;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
[GeneratedRegex("#+")]
|
|
private static partial Regex GroupMatch();
|
|
}
|
|
} |