diff --git a/advent-of-code-2021.csproj b/advent-of-code-2021.csproj
index 8c40388..da056ec 100644
--- a/advent-of-code-2021.csproj
+++ b/advent-of-code-2021.csproj
@@ -72,6 +72,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/inputs/20.txt b/inputs/20.txt
new file mode 100644
index 0000000..2e2b2bd
--- /dev/null
+++ b/inputs/20.txt
@@ -0,0 +1,102 @@
+###.#####..###..###.....##.##.#..#.#######..#...####.....#.#.###..##.#....####.#...##.#.#..##.###..######.#.#.#.##..#...##..###....####.##.##..#.#..##...##.#..#..#...#..#....###.####.######..#..#..#..#..........#.####...#..####.##.....#.#..#..#..####.##..#...####..#....#...##.#####...##.#.##.#..#....###....###..#...#....###.#....#..##....#..#..#..#..#.......###..##..##..####...###..#.....######.#.#.#.####.####.#####.....#..#...#.#.###...#...#.##.##.....#....#..##.###..#.##.#.##..#.#......####.#....#..#.#...
+
+...#.####...#...#..#####..#.#.##........###..#.....##..####.###.#####......#.##.#..###.#####..#..###
+#...#.#....####.##.#...###..##...#.###...###...#..#.##.#.###..#.#.##..#.####.#..#..#.####.##.#..#...
+....#.##..##.#####.#...#########..#.#.####....#..#.#..##.##.###.#.####.##.###.##...#.######..#.#.#..
+..#.##.###.##..#.###..#.#..#.#..###..........#..#..###.#.......###.##.#.#..#####.##.###.###.###..#.#
+##...#...#.###.#####..#.#####.#..##.#.##.#..#.##.#..#...##...####.#.#..#....#########.#.##...####.##
+###.##...#.###...#.####...#.#.##..##......##..#.###..#####..##...##.##..##..##.##...#.#.#..#.#..##..
+.#.#####....#...#...#..##..##..#....#..##..##.##..#..#.##..#.#.###..##..###..#...#....##.##...##.###
+.##.#..#####.##.#.#..#..#.#####.....##.####.....#######.#.####.####..#.#.###.#....###.#...##..#.#.##
+#.#.#..###..###.#.###..###...##.##.#....##.#.###..######....##.##......##.#..#..######.###.##..###..
+#..######..##..####..#.#....#...#.#.###....###....#.#..##.###.#..#.#..#.##.#....#....#....##..##....
+.##....#...###...##..#...#....##.####..#.##..#.....#....####.#..#...##.#..###.#.#.####....##.#...###
+##.#######...###...........##.###..##..######..###..#.##.###..#.##...#.####...#....###.#..#.##.###.#
+.#..#..#..#...###....#.#..#.####.#.#....###...#.#...#..##.##..#...###.#.#.....#.#.#.###....###.#...#
+###..##.####..####.#.##..#..#.######.#.#####....#..#.#......#........#.#..##.#.####...###.#..#.##..#
+.##.#.####.#.##.###..#..#....#####.#.....#..#....###.....#.#..######..#..#....#.##....####.###.#.##.
+.#..#.....##....#.#.#...######...####.#####..#.#.#.##.#..#####.#.#.#.##..#..##.##.......##..#.#.##..
+###..##...####....##.#...#..##.##.###.#......##...##.....#.#.#.....#.###.##..####..##.####.#.###.###
+..#...#...####.....####.#.#.#..##..##..#....##.##.###.#.#####.#..##.##.##...##..#.###..#.#...##....#
+.#.##.#..####.#.#..##...#......###.#..##.##.........####.###.#..##.####..#.#.#.#.###...#.#...##.##.#
+##.#..#...##.##.##.#...###.....##.#####.#.#.##...#.#.###..#.##..#.##...#...#..#..#..####..##..###..#
+...#####.##..##.###.#.#..###......#..##..#..#######.#.#.......##.#.#.###.##.#.#.####...##.#..#....##
+#.#...########.##.#.#..####.###.####.##.#####..##.###.#.#.###...#....##..#..###.#.....#.###.##.....#
+.#.##.##.##...#####..##..##.###.######.......#.#.#....##.###..###..##.###.#.#..#..#..####...#..#.#..
+##.###.###....########....#.#...###..#.##.#....###..#.#.....###..#.#..#.##.#.......######.#.#.##....
+##.#.##..#....#.#..##.#.###.##...####.....#...#.#######....#..#.#.#.#.#..#.#.#.##.####..#..#...###..
+.#.######.##.#..#..###.#.###..#.#.#..#...#..##.#######.#...#...#..####.#....###...#.###.##...##....#
+.#.##.#.#.#..#..#.####.##..####..#..###.#.##..#..##........#.#.#.#########.#..####..#..#.##.##....#.
+..###.#..##.##.##...###.##...##.##.##.#.##.###.#####.##..#####.##..######..####.##.#.##..#.....##...
+##..####..#.##....##.#..##..#.#.#..#.##.....#..#....#.#.###.##.##.####.##....#.#.##......#....#.....
+..#.......#.#....##.#.#.###..####..###..#.#.####.....#...#..##.#..#..#...######...........##..##...#
+...#.#...#....##.#....##.##.##.#.#..#.##.#.###.#.#.#.#.#######.#.##.##..#..##.#.....#..##..#.##.#...
+.#.#..#..#..##..#....#.#..#....##....#.###.###...#..#...####.###.....#.##.#..###.....##..#.#.##..#..
+.#....##..##..#..#...##.##.#.##..#.##.#.#...#####..#....##...##...#...####.###.#..#####.#..##..#..##
+###.#####.#.#...#.#.#######.#.....#####.#...#..#.##.###...#..#..#.#..##..#.#...###.##.#..##..###.#.#
+.#####.###.#######..#.#......#.##.#.##.#.#...##....##.#.#.#...#..#....##...#..#...#...###....#..#.##
+###...##.##.##.##..####.##.######.#.######.##..#.#...##...#....####...#..##....#..#..#####....#.#..#
+#...###.#.#.###...####...##.#.#..###..#######.##.####..#.####..##.#.##.###.######.........###.#.#.##
+####.###.#.#.#.####...#..#..######.#..####..##.#.###...#.#.#.##....#..#.#.##.#..#....#...##.##..###.
+#...#..##.#...#..##..##.####.#..###.##.#...#.#.#...##.##.#.#....##...###.#...#...#..#.#.#.##.##....#
+...#...###...#..######.#.####.#.#..####.....#.####..###.#.######..##.......##.#...#..##..#.###..###.
+.##.##.##..#..###.#...##..#.#.#..##..###.#.###.#.#.##.....#.#.###....#.#..##.##..##.###.###.####..##
+###.###....####..#..#.##.#.#..#.####..##.##.#..##..##.#.#.#.##..###...#.#.##.#..##.##..#.#..##.##.##
+##...####.##.##...#.###...##..#.##..#.##...####..###.....#.##.#.##.#.#....###.........#.#.#..###.###
+.#..##.###..##.#..#.#####......#..#####.#.###...###.#....##...#####..###.####.###..##.#.#...#...#.#.
+..#...#..####....#..#......#.##...######.##.###.##.##.##.#......#####.#..##.#...##...###..###...####
+..#..###.####.####.####.###..##...#########....######..#....##.###...#.#........##...##...#..##..###
+.##..#......###.#...##.#..#.#..####.###.#.###..##.##.#...###.#.....##..#..#.#.#..#......#.####.##.#.
+###..##.#.#.###..#....#.##.###.........#.##...#.###...##...#.##....#.#.#.#..###....###.###..#.##...#
+###.#..##.#...####..##..##.#...#.##..#..##.####.#..#.#.#..#.##....#..#......###....####......#.#...#
+.#######...###...###.##.#.#..#.....##...#...#.####..##.#.##..#.#...#..###........##..##.#.##..#.....
+..####.#####...##..##.###.##.#..#..##...#.#....##.#.#...##...###...##.#....###.#.##....#.....#.#.#.#
+...#.......#..#.###.....##.#.......#...#..##....#####.##.###.....##....##.#....#.#.##.#.#.#..####.#.
+.#..#.#..#...#.#.#..#..#..###..#####..###.#.#.####.##..#.#....####.##...#...#....##..##.##...###.#.#
+.#.##..#######..#.......#.###..#.#.###.#..##.##......##.####.##.###......#.###.#.#...#...##.....##..
+#..####.....#..#...###.#.###..#...#.###.#...###...##.##....##.##..#.###.###.###.#.##...####.#.##.##.
+.###.....#####.##.#...####..#.##..###########..#...######.......###.......####.###....#.###.....###.
+.#.####..#..#.##...#.#######.#.###....#.###.#..#.#.#..##.#.#.#..#.#.#.....#..#..###..##..#....####.#
+.#####..#..#....#.###.#.###...#.###..#.#.##.#....#.####...##....##.#####.####.##..#.#.#####..####.##
+#...##....###..###...##...#..#......#..#.##..####..##.#.#......#..##.#..##..###.##..###...#..####.##
+....####.####..........#...#..####..#.....#....##.####.#.##..#..#....##...#.#...##.#.#..##.##.##...#
+.....#.#...#...#.###..#..#.#....#....#..#.###.##.#.##.##..#.#.....#.###....####.#....#.....#.#..#.##
+#...#.##..#.#..##.#.....#.#.#.#..#.####..#...#.#.#...##.....#.#####..##..##..###.##.#....#.....#....
+.####.##..##.......##.####..##......##...#.#.###..#.....##.#..#.##.#.#.#.###.......###.##.#.........
+#.###.#.#.###.#.#.#..##.#..#.######..#...#....#..###.##.#...#.#.#.#.####....##..###.###....#.#.###..
+.#.#..#.....####.#####..##..####....###....#....##.##......##..#.#.#...#.#...##.##.##.######.#.#.###
+###..#.#..###..#..##..###.....#####.#.#...#.##......#.#.#........#.#...#.....##..##...#.#....#.#..#.
+##....#####...#.#..###.####...#...##....##..#.#...#...##.##...##........#.#....#####..#.....####..#.
+.#..#.#####.#...#.#.#..###.##...##...##..##......##.#.###...#.#..#.#####.#.#..##...##..##...###.....
+.##..#..##..#.###..####.....##.#..##.#.#...##.#########..#..###..#.##.#.#..#.#.#.###.###..####..##.#
+##..#..#...#..##...#.#.##...#....##..#.#.##.....##.#####.##..##....#.#......#.###.....#.###.....#...
+#.#.#..#..##...#.##.##.###.###......#...###....#.#..##..#.##..#..#.##.#####...#...###.#####..#...###
+...#..##.######.#..#..##..#..##..#....#.#.#..#...#.##....##.#.##.##....###.#.######..#..###...##.#..
+###...######..#.##.##.#.#.###.#.#.#...###.##...##.#.##.#.#.#..#....####...###.#..##.##.#.##..#..#..#
+#.##..###.######..#..#.##.##.#.##..##..#.##..#.##..##.######.#.#....#.#...#...##..#.#.##.#.#...#.#.#
+..##.#.#...###.##.....#.#.#.#.#####..###.#..##..##.#.#..##.#.###..#..#.##....#....##...#######.#.#.#
+.#.###.....#..#.#.....#..#.....#....#....##..###.##.##.#.#####....#.####.....##....#.####.#.##...##.
+#.####.##..#..#....###.#.......####..##.##..##...#...#..##..##.#...#.#..#..#.##.##.#..########..####
+.###.#.#..#######...#.#.###.#.#.##.....#.#..##.#..##..#.#....##..##..##..##.#.#.#..#.#..#.#...#..#..
+###.#.#.#....#.#..#..###..#..#.####.#.#....#.#####..#.####.#.##.#######.##...###.#...#..#.####..###.
+.#.....###.##.##..#..###...####....####...#..#...###..##...##.###.###..#.##.#.#.####.....##.#.......
+.#..##.#.#...##.#..........##.####.#.###..##....#.....#.####........#.#.#.##.##.##.#...##..#..###...
+#.#.###.###..#.##..#.##..##...#..#.......####...#.#..#...##.#.##...#..##.###.####.#......#.......###
+..###..#..####.#.#...#..###..#.#.#...#####..#..#####..#.......#.#..#.###..#..#.##.######.###.#.#..#.
+#.###.##.#..#...##.#.##.##..###.#.#.#..#.....#..##..#...#.#####.#.#.#.........#.#####.#..#####...#.#
+#..#.#...#####.#.##.##.#..##..###.##.#...##..#.##.#..#.###.#.##.#.#..##.###.###..#.#..#..#...##.##.#
+#...##.###..#.#...##.##...##..#..#.#.##.#.#..####..#####...##.##.####...#.###.#.##...##...#.##.##.##
+#.##..###..###.#...#.....#...##...#..##.##.#..##...###.#.....#.##.......#####.#####....#.###.#######
+..#...##.#..####...###..#.##...#.##.#.....##..##...#.#..#.#.#.##.......#...#.###..#....##.######....
+###.#..###..##.#........##.#.#.#..#....##.#...#....#.###..##.##.##.###..####.#####.....##...#..#.##.
+.####.##.....##............##.#...##.###...#.##..########.#..###......##..##.##..##..#.###....#.##..
+##.##.##.#..#...########.####.####.#.#.###..#...#.#.###..##.#.#.####.#..#.#.....#..#..##.#..##.##...
+##.##.#..#.....##.#####..#........####.#.#.##....#..#..#....###....#.......#.###.##.##...#..###..###
+##...#..#...#.#...##.#..###..###....#.#.......#...##.....#...#..#.#..###.##.##..###..#.#########.##.
+.#######...##.#..##.#####.....#....###.####.#.#.#..##.#.#..##...##.##.#.###.#.#....###.##.#.###.#..#
+..##.##..##.##.#.#..#.#..#.##..####..###..#######..#..#.#.#...###...#.###.#...#.###.##....##..#.###.
+#.......#...#.##...#.#...##....#.#....##.#.###.#.#...#...#######...###.#.#.##....###.#.##.#...##.##.
+##.##.#..##....#.######..##...#.##.#...#.#.####..####.##...####.#.#.#.##.#....###..##.#######..#..#.
+.....##....#.##.##.#.##....#.#.##.##......####.##..##.#....#..#.##.###.#..#....##.#..#.#.#.#.##...#.
+.#.#..#...#..#..#.....#####...#####..##.#.##.#.#....##..##............#.##...######..#.###..#...#..#
+#.#####.##.#.#.....#...#..#.#.#....#....#..##.#..#..#....####.#...#.##.####.#.##.#...#.#.#.#..#...##
\ No newline at end of file
diff --git a/src/20.cs b/src/20.cs
new file mode 100644
index 0000000..ad95c30
--- /dev/null
+++ b/src/20.cs
@@ -0,0 +1,114 @@
+namespace aoc2021;
+
+internal class Day20 : Day
+{
+ internal override void Go()
+ {
+ var lines = Util.ReadAllLines("inputs/20.txt");
+ string key = lines.ElementAt(0);
+ var grid = new List>(lines.ElementAt(2).Length);
+ for (int i = 2; i < lines.Count(); i++)
+ {
+ var line = lines.ElementAt(i);
+ var row = new List(line.Length);
+ grid.Add(row);
+ line.ForEach(ch => row.Add(ch switch
+ {
+ '#' => 1,
+ _ => 0,
+ }));
+ }
+
+ Part1(grid, key);
+ Part2(grid, key);
+ }
+
+ private static void Part1(List> grid, string key)
+ {
+ int numLit = grid.Sum(row => row.Count(col => col == 1));
+
+ using var t = new Timer();
+
+ (grid, numLit) = Enhance(grid, key);
+ (grid, numLit) = Enhance(grid, key);
+
+ t.Stop();
+
+ Logger.Log($"<+black>> part1: #lit=<+white>{numLit}");
+ }
+
+ private static void Part2(List> grid, string key)
+ {
+ using var t = new Timer();
+
+ int numLit = 0;
+ for (int i = 0; i < 50; i++)
+ {
+ (grid, numLit) = Enhance(grid, key);
+ }
+
+ t.Stop();
+ Logger.Log($"<+black>> part2: #lit=<+white>{numLit}");
+ }
+
+ private static bool IsValidIdx(int len, int idx) => idx >= 0 && idx < len;
+
+ private static (List> grid, int numLit) Enhance(List> grid, string key)
+ {
+ var newSize = grid.Count + 2;
+ var emptyRow = Enumerable.Range(0, newSize).Select(_ => (byte)0);
+ var outImg = new List>(newSize);
+ for (int rowIdx = 0; rowIdx < newSize; rowIdx++)
+ {
+ outImg.Add(new List(emptyRow));
+ }
+
+ var def = key[0] == '#' && grid.Count % 4 != 0 ? '1' : '0';
+ int numLit = 0;
+
+ for (int row = - 1; row < grid.Count + 1; row++)
+ {
+ for (int col = - 1; col < grid.Count + 1; col++)
+ {
+ var num = Enumerable.Range(0, 9).Select(_ => def).ToArray();
+ if (IsValidIdx(grid.Count, row - 1))
+ {
+ if (IsValidIdx(grid.Count, col - 1))
+ num[0] = (char)(grid[row - 1][col - 1] + '0');
+ if (IsValidIdx(grid.Count, col))
+ num[1] = (char)(grid[row - 1][col] + '0');
+ if (IsValidIdx(grid.Count, col + 1))
+ num[2] = (char)(grid[row - 1][col + 1] + '0');
+ }
+ if (IsValidIdx(grid.Count, row))
+ {
+ if (IsValidIdx(grid.Count, col - 1))
+ num[3] = (char)(grid[row][col - 1] + '0');
+ if (IsValidIdx(grid.Count, col))
+ num[4] = (char)(grid[row][col] + '0');
+ if (IsValidIdx(grid.Count, col + 1))
+ num[5] = (char)(grid[row][col + 1] + '0');
+ }
+ if (IsValidIdx(grid.Count, row + 1))
+ {
+ if (IsValidIdx(grid.Count, col - 1))
+ num[6] = (char)(grid[row + 1][col - 1] + '0');
+ if (IsValidIdx(grid.Count, col))
+ num[7] = (char)(grid[row + 1][col] + '0');
+ if (IsValidIdx(grid.Count, col + 1))
+ num[8] = (char)(grid[row + 1][col + 1] + '0');
+ }
+
+ var keyIdx = Convert.ToInt32(new string(num), 2);
+ var ch = (byte)(key[keyIdx] == '#' ? 1 : 0);
+ outImg[row + 1][col + 1] = ch;
+ if (ch == 1)
+ {
+ numLit++;
+ }
+ }
+ }
+
+ return (outImg, numLit);
+ }
+}
diff --git a/src/main.cs b/src/main.cs
index 3c43b1a..e82507d 100644
--- a/src/main.cs
+++ b/src/main.cs
@@ -36,7 +36,8 @@ else
"15" => new Day15(),
"16" => new Day16(),
"17"=> new Day17(),
- _ => new Day18(),
+ "18" => new Day18(),
+ _ => new Day20(),
};
day.Go();
}