const int EXAMPLE_VALUE_1 = 2; const int EXAMPLE_VALUE_2 = 4; StreamReader inputFile; string input; Console.Write("Use (p)rod or (e)xample? > "); if (Console.ReadKey().Key == ConsoleKey.E) { Console.WriteLine($"\nUsing example data, value should be of {EXAMPLE_VALUE_1} and {EXAMPLE_VALUE_2}"); inputFile = File.OpenText("example.txt"); } else { Console.WriteLine("\nUsing production data"); inputFile = File.OpenText("input.txt"); } input = inputFile.ReadToEnd(); string[] reports = input.Split("\n"); List invalidReports = []; Console.WriteLine($"{reports.Length} reports will be processed"); int validReports = 0; static bool validateReport(List levels) { bool shouldBeIncreasing = levels[0] < levels[1]; bool hasIgnoredZeroIndex = false; int lastNumber = levels[0]; foreach(var level in levels) { if (levels.IndexOf(level) == 0 && !hasIgnoredZeroIndex) { hasIgnoredZeroIndex = true; continue; } if (lastNumber >= level && shouldBeIncreasing || lastNumber <= level && !shouldBeIncreasing) return false; if (Math.Abs(lastNumber - level) > 3) return false; lastNumber = level; } return true; } // Part 1 foreach(var report in reports) { string[] levelsAsString = report.Split(" "); List levels = []; foreach(var levelAsString in levelsAsString) { levels.Add(int.Parse(levelAsString)); } if (validateReport(levels)) validReports++; else { invalidReports.Add(report); } } Console.WriteLine($"Part 1: {validReports} valid reports!"); // Part 2 foreach(var report in invalidReports) { string[] levelsAsString = report.Split(" "); List levels = []; foreach(var levelAsString in levelsAsString) { levels.Add(int.Parse(levelAsString)); } for(var i = 0; i < levels.ToArray().Length; i++) { List manipulatedLevels = new(levels); manipulatedLevels.RemoveAt(i); if(validateReport(manipulatedLevels)) { validReports++; break; } } } Console.WriteLine($"Part 2: {validReports} valid reports!");