diff --git a/AdvendOfCode.Runner/Program.cs b/AdvendOfCode.Runner/Program.cs index dee3346..1289619 100644 --- a/AdvendOfCode.Runner/Program.cs +++ b/AdvendOfCode.Runner/Program.cs @@ -7,9 +7,9 @@ InputReader inputReader = new() //IsDebug = true }; -inputReader.SetInputByChallange(14); +inputReader.SetInputByChallange(12); -IChallange challange = new Day14(inputReader); +IChallange challange = new Day12(inputReader); Console.WriteLine($"Part 1: {await challange.GetSolutionPart1()}"); diff --git a/AdventOfCode.Solutions/2023/Day 12/Day12.cs b/AdventOfCode.Solutions/2023/Day 12/Day12.cs index ae9aa42..15624ca 100644 --- a/AdventOfCode.Solutions/2023/Day 12/Day12.cs +++ b/AdventOfCode.Solutions/2023/Day 12/Day12.cs @@ -1,4 +1,5 @@ using AdventOfCode.Core; +using System.Linq; using System.Text.RegularExpressions; namespace AdventOfCode.Solutions._2023 @@ -15,7 +16,11 @@ namespace AdventOfCode.Solutions._2023 string[] splitted = line.Split(' '); int[] groups = splitted[1].Split(',').Select(int.Parse).ToArray(); - total += Possibilities(splitted[0], groups); + Console.Write(splitted[0]); + long possiblies = Possibilities2(splitted[0], groups, 0, 0); + Console.WriteLine($": {possiblies}"); + total += possiblies; + //total += Possibilities(splitted[0], groups); } return total.ToString(); } @@ -30,7 +35,11 @@ namespace AdventOfCode.Solutions._2023 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); + //total += Possibilities(splitted[0], groups); + Console.Write(joinedLine + " " + string.Join(",", new[] { splitted[1], splitted[1], splitted[1], splitted[1], splitted[1] })); + long possiblies = Possibilities2(joinedLine, groupsTotal, 0, 0); + Console.WriteLine($": {possiblies}"); + total += possiblies; } return total.ToString(); } @@ -59,80 +68,92 @@ namespace AdventOfCode.Solutions._2023 return 0; } - private long Possibilities2(string lineToValidate, int[] groups, int readIndex, int groupIndex, int captureSize) + private long Possibilities2(string lineToValidate, int[] groups, int readIndex, int captureSize) { - // if group index is 0 there are no captures and not captures ruynning - if (groupIndex > 0) + // if group index is 0 there are no captures and not captures running + if (readIndex < lineToValidate.Length) { - int[] splitGroups = lineToValidate.Split('.', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Length).ToArray(); + int[] splitGroups = lineToValidate[..readIndex].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 + if (groups.Length < splitGroups.Length) { - 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; + // we have more groups than expected + return 0; } - + if (lineToValidate.Length - readIndex < groups.Skip(splitGroups.Length).Sum() + groups.Length - splitGroups.Length - 1) + { + // there is not enough space to even fit the groups so reject + return 0; + } + + // validate everything, including fixed groups + for (int i = 0; i < splitGroups.Length - 1; i++) + { + // all except the last must match + if (splitGroups[i] != groups[i]) + { + return 0; // group lengths do not match, reject + } + } + + // the last one is allowed to be smaller than the expected groups size + if (splitGroups.Any() && splitGroups[^1] > groups[splitGroups.Length - 1]) + { + // if the last group is larger than allowed the line is invalid + return 0; + } } if (!lineToValidate.Contains('?')) // no more variations { int[] splitGroups = lineToValidate.Split('.', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Length).ToArray(); + if (splitGroups.Length != groups.Length) + { + // group amount does not match + return 0; + } + 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 + // valid 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] == '.') { + captureSize = 0; readIndex++; continue; } if (lineToValidate[charIndex] == '#') { - total += Possibilities2(lineToValidate, groups, readIndex + 1, groupIndex + 1, captureSize + 1); - break; + captureSize++; + readIndex++; + continue; } 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); + total += Possibilities2(regex.Replace(lineToValidate, "#", 1), groups, readIndex + 1, captureSize + 1); + total += Possibilities2(regex.Replace(lineToValidate, ".", 1), groups, readIndex + 1, captureSize); return total; } } - return 0; + return Possibilities2(lineToValidate, groups, readIndex + 1, captureSize); } [GeneratedRegex("#+")] diff --git a/AdventOfCode.Solutions/day-00-input.txt b/AdventOfCode.Solutions/day-00-input.txt index b92d1a3..c5bec3a 100644 --- a/AdventOfCode.Solutions/day-00-input.txt +++ b/AdventOfCode.Solutions/day-00-input.txt @@ -1,10 +1,6 @@ -O....#.... -O.OO#....# -.....##... -OO.#O....O -.O.....O#. -O.#..O.#.# -..O..#O..O -.......O.. -#....###.. -#OO..#.... \ No newline at end of file +???.### 1,1,3 +.??..??...?##. 1,1,3 +?#?#?#?#?#?#?#? 1,3,1,6 +????.#...#... 4,1,1 +????.######..#####. 1,6,5 +?###???????? 3,2,1 \ No newline at end of file