diff --git a/advent-of-code-2021.csproj b/advent-of-code-2021.csproj
index c6122e5..00dd4ba 100644
--- a/advent-of-code-2021.csproj
+++ b/advent-of-code-2021.csproj
@@ -57,6 +57,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/inputs/14.txt b/inputs/14.txt
new file mode 100644
index 0000000..30b0a84
--- /dev/null
+++ b/inputs/14.txt
@@ -0,0 +1,102 @@
+OKSBBKHFBPVNOBKHBPCO
+
+CB -> P
+VH -> S
+CF -> P
+OV -> B
+CH -> N
+PB -> F
+KF -> O
+BC -> K
+FB -> F
+SN -> F
+FV -> B
+PN -> K
+SF -> V
+FN -> F
+SS -> K
+VP -> F
+VB -> B
+OS -> N
+HP -> O
+NF -> S
+SK -> H
+OO -> S
+PF -> C
+CC -> P
+BP -> F
+OB -> C
+CS -> N
+BV -> F
+VV -> B
+HO -> F
+KN -> P
+VC -> K
+KK -> N
+BO -> V
+NH -> O
+HC -> S
+SB -> F
+NN -> V
+OF -> V
+FK -> S
+OP -> S
+NS -> C
+HV -> O
+PC -> C
+FO -> H
+OH -> F
+BF -> S
+SO -> O
+HB -> P
+NK -> H
+NV -> C
+NB -> B
+FF -> B
+BH -> C
+SV -> B
+BK -> K
+NO -> C
+VN -> P
+FC -> B
+PH -> V
+HH -> C
+VO -> O
+SP -> P
+VK -> N
+CP -> H
+SC -> C
+KV -> H
+CO -> C
+OK -> V
+ON -> C
+KS -> S
+NP -> O
+CK -> C
+BS -> F
+VS -> B
+KH -> O
+KC -> C
+KB -> N
+OC -> F
+PP -> S
+HK -> H
+BN -> S
+KO -> K
+NC -> B
+PK -> K
+CV -> H
+PO -> O
+BB -> C
+HS -> F
+SH -> K
+CN -> S
+HN -> S
+KP -> O
+FP -> H
+HF -> F
+PS -> B
+FH -> K
+PV -> O
+FS -> N
+VF -> V
\ No newline at end of file
diff --git a/src/14.cs b/src/14.cs
new file mode 100644
index 0000000..6820f6d
--- /dev/null
+++ b/src/14.cs
@@ -0,0 +1,109 @@
+using System.Text;
+
+namespace aoc2021;
+
+internal class Day14 : Day
+{
+ internal override void Go()
+ {
+ var lines = Util.ReadAllLines("inputs/14.txt");
+
+ string template = string.Empty;
+ Dictionary rules = new();
+ foreach (var line in lines)
+ {
+ if (string.IsNullOrEmpty(template))
+ {
+ template = line;
+ }
+ else if (!string.IsNullOrEmpty(line))
+ {
+ var pair = line.Split(" -> ");
+ rules.Add(pair[0], pair[1][0]);
+ }
+ }
+
+ Part1(template, rules);
+ Part2(template, rules);
+ }
+
+ private static void Part1(string template, Dictionary rules)
+ {
+ using var t = new Timer();
+
+ string curr = template;
+
+ for (int i = 0; i < 10; i++)
+ {
+ StringBuilder sb = new();
+ for (int j = 0; j < curr.Length - 1; j++)
+ {
+ sb.Append(curr[j]);
+ sb.Append(rules[curr[j..(j + 2)]]);
+ }
+ sb.Append(curr[curr.Length - 1]);
+ curr = sb.ToString();
+ }
+
+ Dictionary frequency = new();
+ foreach (var c in curr)
+ {
+ if (!frequency.ContainsKey(c))
+ {
+ frequency.Add(c, 0);
+ }
+
+ frequency[c]++;
+ }
+ var least = frequency.MinBy(x => x.Value);
+ var most = frequency.MaxBy(x => x.Value);
+
+ Logger.Log($"part1: {most.Value - least.Value}");
+ }
+
+ private static void Part2(string template, Dictionary rules)
+ {
+ using var t = new Timer();
+
+ Dictionary pairs = new();
+ Dictionary frequencies = new();
+ foreach (var pair in rules)
+ {
+ pairs.Add(pair.Key, 0);
+ if (!frequencies.ContainsKey(pair.Key[0]))
+ {
+ frequencies.Add(pair.Key[0], 0);
+ }
+ if (!frequencies.ContainsKey(pair.Key[1]))
+ {
+ frequencies.Add(pair.Key[1], 0);
+ }
+ }
+ for (int i = 0; i < template.Length - 1; i++)
+ {
+ var pair = template[i..(i + 2)];
+ pairs[pair]++;
+ frequencies[template[i]]++;
+ }
+ frequencies[template[^1]]++;
+
+ for (int round = 0; round < 40; round++)
+ {
+ foreach (var pair in pairs.Where(x => x.Value > 0).ToList())
+ {
+ pairs[pair.Key] -= pair.Value;
+ frequencies[rules[pair.Key]] += pair.Value;
+
+ var np1 = $"{pair.Key[0]}{rules[pair.Key]}";
+ var np2 = $"{rules[pair.Key]}{pair.Key[1]}";
+ pairs[np1] += pair.Value;
+ pairs[np2] += pair.Value;
+ }
+ }
+
+ var least = frequencies.MinBy(x => x.Value);
+ var most = frequencies.MaxBy(x => x.Value);
+
+ Logger.Log($"part2: {most.Value - least.Value}");
+ }
+}
diff --git a/src/main.cs b/src/main.cs
index 024ffcb..1be32a1 100644
--- a/src/main.cs
+++ b/src/main.cs
@@ -31,7 +31,8 @@ else
"10" => new Day10(),
"11" => new Day11(),
"12" => new Day12(),
- _ => new Day13(),
+ "13" => new Day13(),
+ _ => new Day14(),
};
day.Go();
}