-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSolution.cs
61 lines (49 loc) · 1.95 KB
/
Solution.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace AdventOfCode2020.Day19
{
internal class Solution
{
private readonly IDictionary<string, string> _rules;
private readonly IReadOnlyCollection<string> _messages;
public Solution(IEnumerable<string> input)
{
_rules = input
.TakeWhile(x => !string.IsNullOrWhiteSpace(x))
.Select(line => line.Split(": "))
.ToDictionary(x => x[0], x => x[1]);
_messages = input.Skip(_rules.Count + 1).ToList();
}
public int PartOne()
{
var pattern = CreatePattern("0", _rules);
return _messages.Count(x => Regex.IsMatch(x, pattern));
}
public int PartTwo()
{
var newRules = _rules.ToDictionary(x => x.Key, x => x.Value);
newRules["8"] = "42 | 42 8";
newRules["11"] = "42 31 | 42 11 31";
var pattern = CreatePattern("0", newRules);
return _messages.Count(x => Regex.IsMatch(x, pattern));
}
private static string CreatePattern(string rule, IDictionary<string, string> rules) =>
$"^{CreatePattern(rule, rules, 0)}$";
private static string CreatePattern(string rule, IDictionary<string, string> rules, int nestingLevel)
{
const string singleCharacterPattern = "^\"(?<character>[a-z])\"$";
if (nestingLevel > 25)
return "";
var subRule = rules[rule];
if (Regex.IsMatch(subRule, singleCharacterPattern))
{
return Regex.Replace(subRule, singleCharacterPattern, match => match.Groups["character"].Value);
}
var parts = subRule.Split(" ")
.Select(x => x == "|" ? x : CreatePattern(x, rules, nestingLevel + 1));
return $"({string.Concat(parts)})";
}
}
}