// #define Day14 #if Day14 using System.Text.RegularExpressions; var text = File.ReadAllText("day14/input").Split("\n\n"); var start = text[0].Select(x => x).ToList(); var reg = new Regex(@"(?\w)(?\w) -> (?\w)"); var rules = reg.Matches(text[1]).Select(m => new Rule(new Pair(m.Groups["a"].Value[0], m.Groups["b"].Value[0]), m.Groups["res"].Value[0])).ToDictionary(x => x.p, x=> x.res); for (var i = 0; i < 10; i++) { var next = new List(); for (int pos = 1; pos < start.Count; pos++) { var res = rules[new Pair(start[pos - 1], start[pos])]; next.Add(start[pos - 1]); next.Add(res); } next.Add(start.Last()); start = next; } var charCountPartOne = start.GroupBy(s => s).ToDictionary(g => g.Key, g => g.LongCount()); Console.WriteLine(charCountPartOne.Values.Max() - charCountPartOne.Values.Min()); // Part two start = text[0].Select(x => x).ToList(); int maxDepth = 40; var charCountPartTwo = new Dictionary(); var save = new Dictionary>(); Dictionary Process(Pair cur, int depth) { var curKey = new AsKey(cur, depth); if (save.ContainsKey(curKey)) { return save[curKey]; } if (depth <= 0) { return new Dictionary() { {cur.a, 1} }; } var c = rules[cur]; var first = Process(new Pair(cur.a, c), depth - 1); var second = Process(new Pair(c, cur.b), depth - 1); var merged = Merge(first, second); save[curKey] = merged.ToDictionary(x => x.Key, x => x.Value); return merged; } Dictionary Merge(Dictionary a, Dictionary b) { return new List>(){a, b}.SelectMany(x => x) .ToLookup(pair => pair.Key, pair => pair.Value) .ToDictionary(group => group.Key, group => group.Sum()); } for (int pos = 1; pos < start.Count; pos++) { var countBla = Process(new Pair(start[pos - 1], start[pos]), maxDepth); charCountPartTwo = Merge(charCountPartTwo, countBla); } charCountPartTwo[start.Last()]++; Console.WriteLine(charCountPartTwo.Values.Max() - charCountPartTwo.Values.Min()); record AsKey(Pair p, int depth); record Rule(Pair p, char res); record Pair(char a, char b); #endif