#pragma warning disable using System.Collections; var input = File.ReadAllLines("../../../../Input.in"); var enhancement = new BitArray(input.First().ToCharArray().Select(c => c == '#').ToArray()); var inputImage = new HashSet<(int, int)>(); var initFrame = new FrameState { minX = 0, minY = 0, maxX = input[2].Length, maxY = input.Length - 2 }; for (int row = 2; row < input.Length; row++) { var line = input[row]; for (int col = 0; col < line.Length; col++) { if (line[col] == '#') { inputImage.Add((col, row - 2)); } } } var (img, frame) = (inputImage, initFrame); for (int i = 0; i < 2; i++) { (img, frame) = Step(img, frame); } Console.WriteLine("After 2 enhancements " + img.Count + " pixels are lit"); (img, frame) = (inputImage, initFrame); for (int i = 0; i < 50; i++) { (img, frame) = Step(img, frame); } Console.WriteLine("After 50 enhancements " + img.Count + " pixels are lit"); bool EnhancePix(HashSet<(int, int)> img, (int x, int y) coordinates, FrameState frame) { int key = 0; for (int row = coordinates.y - 1; row <= coordinates.y + 1; row++) { for (int col = coordinates.x - 1; col <= coordinates.x + 1; col++) { key <<= 1; bool litBecauseOutside = frame.LitOutside && (col < frame.minX || col > frame.maxX || row < frame.minY || row > frame.maxY); if (litBecauseOutside || img.Contains((col, row))) { key += 1; } } } return enhancement[key]; } (HashSet<(int, int)>, FrameState) Step(HashSet<(int, int)> inputImage, FrameState frame) { var outputImage = new HashSet<(int, int)>(); for (var x = frame.minX - 1; x <= frame.maxX + 1; x++) { for (var y = frame.minY - 1; y <= frame.maxY + 1; y++) { if (!outputImage.Contains((x, y)) && EnhancePix(inputImage, (x, y), frame)) { outputImage.Add((x, y)); } } } var newFrame = new FrameState { // enhancement[0] = do we turn on the frame, which is all off? // enhancement[511] = do we turn off the frame, which is all on? LitOutside = frame.LitOutside ? enhancement[511] : enhancement[0], minX = frame.minX - 1, minY = frame.minY - 1, maxX = frame.maxX + 1, maxY = frame.maxY + 1, }; return (outputImage, newFrame); } struct FrameState { public bool LitOutside = false; public int minX = int.MaxValue; public int minY = int.MaxValue; public int maxX = int.MinValue; public int maxY = int.MinValue; }