using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; namespace Advent24 { internal class Day2 { private static Boolean ReportIsSafe(String[] levelsArray, Int32? levelIndexToSkip = null) { Int32 currentLevel; Int32? previousLevel = null; Int32 differenceInLevels = 0; Boolean? isIncreasing = null; Boolean reportIsSafe = true; Int32 currentLevelIndex = 0; foreach (var level in levelsArray) { Console.WriteLine("{0:s} {1:d}", " level = ", level); // if there is no elementIndexToSkip, assume sentinel value -1 // so that it never matches the currentElementIndex if((levelIndexToSkip ?? -1) == currentLevelIndex) { // assume current element doesn't exist, so the previous // element should remain what it was Console.WriteLine("{0:s} {1:d}", " currentLevelIndex (skipped) = ", currentLevelIndex); // if (currentLevelIndex != 0) Console.ReadKey(); // increment the currentElementIndex and short-circuit the loop currentLevelIndex++; continue; } currentLevel = System.Convert.ToInt32(level); if (currentLevel > (previousLevel ?? 0)) { // first time, so can't tell trend if (!previousLevel.HasValue) isIncreasing = null; else if ((!isIncreasing) ?? false) { // level was decreasing but is now increasing, so report is unsafe reportIsSafe = false; break; } else isIncreasing = true; differenceInLevels = currentLevel - (previousLevel ?? 0); } else if (currentLevel < (previousLevel ?? 0)) { // first time, so can't tell trend if (!previousLevel.HasValue) isIncreasing = null; else if (isIncreasing ?? false) { // level was increasing but is now decreasing, so report is unsafe reportIsSafe = false; break; } else isIncreasing = false; differenceInLevels = (previousLevel ?? 0) - currentLevel; } else if (previousLevel.HasValue) { // both currentLevel and previousLevel are equal, so report is unsafe reportIsSafe = false; break; } Console.WriteLine("{0:s} {1:d}", " differenceInLevels = ", differenceInLevels); Console.WriteLine("{0:s} {1:d}", " isIncreasing = ", isIncreasing); // control reaches this line if currentLevel = previousLevel // or if it was previously increasing/decreasing and is also // currently increasing/decreasing // confirm that it isn't first time, so a difference in levels is conceptually valid if (previousLevel.HasValue) { // difference in levels is outside the safe band, so report is unsafe if (differenceInLevels < 1 || differenceInLevels > 3) { reportIsSafe = false; break; } } // control reaches this line if report has not been proven unsafe yet // updating previousLevel in preparation for the next iteration previousLevel = currentLevel; // incrementing the current-element-number indicator currentLevelIndex++; } return reportIsSafe; } public Day2() { string fileData = System.IO.File.ReadAllText(@"..\..\..\inputd2.txt"); var reportsArray = fileData.Split('\n', StringSplitOptions.RemoveEmptyEntries); Int32 numberOfSafeReports = 0; foreach (var report in reportsArray) { if (System.String.IsNullOrEmpty(report)) continue; Console.WriteLine("{0:s} {1:d}", "report = ", report); var levelsArray = report.Split(' '); Int32 numberOfLevels = levelsArray.Length; Boolean reportIsSafe = false; // iterate through each index to check subreports // for safety for (Int32 i = 0; i < numberOfLevels; i++) { // check if the current subreport is safe reportIsSafe = ReportIsSafe(levelsArray, i); // if any subreport is safe, the report is safe, // so we don't need to check any of the other // subreports and can break if (reportIsSafe) break; } // check full report for safety if report is still not proven safe if (!reportIsSafe) { reportIsSafe = ReportIsSafe(levelsArray); } Console.WriteLine("{0:s} {1:d}", " reportIsSafe = ", reportIsSafe); // if report has not been proven unsafe, then it must be safe if (reportIsSafe) numberOfSafeReports++; } Console.WriteLine("{0:s} {1:d}", "numberOfSafeReports = ", numberOfSafeReports); // to make sure the console window doesn't disappear Console.ReadLine(); } } }