2021aoc/Day14.cs

66 lines
2.2 KiB
C#

// #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(@"(?<a>\w)(?<b>\w) -> (?<res>\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<char>();
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<char, long>();
var save = new Dictionary<AsKey, Dictionary<char, long>>();
Dictionary<char, long> Process(Pair cur, int depth) {
var curKey = new AsKey(cur, depth);
if (save.ContainsKey(curKey)) {
return save[curKey];
}
if (depth <= 0) {
return new Dictionary<char, long>() { {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<char, long> Merge(Dictionary<char, long> a, Dictionary<char, long> b) {
return new List<Dictionary<char, long>>(){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