From d17a28ccb0103875ac414f4d450d68ea73867882 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Tue, 3 Dec 2024 03:39:53 -0600 Subject: [PATCH] feat: solved day 2 part 2...damn that was a rough day 2 --- 02/RedNosedReports.Tests/ReportTests.cs | 10 ++++ 02/RedNosedReports/Report.cs | 70 ++++++++++++++++++++----- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/02/RedNosedReports.Tests/ReportTests.cs b/02/RedNosedReports.Tests/ReportTests.cs index 172f0ce..7cc8731 100644 --- a/02/RedNosedReports.Tests/ReportTests.cs +++ b/02/RedNosedReports.Tests/ReportTests.cs @@ -74,10 +74,16 @@ public class ReportTests var reportOne = new Report([1, 3, 2, 4, 5]); var reportTwo = new Report([8, 6, 4, 4, 1]); var reportThree = new Report([19, 21, 24, 27, 24]); + var reportFour = new Report([6, 6, 9, 10, 11, 13]); + var reportFive = new Report([41, 43, 44, 45, 47, 49]); + var reportSix = new Report([43, 41, 43, 44, 45, 47, 49]); await Assert.That(reportOne.IsSafeWithProblemDampener()).IsEqualTo(true); await Assert.That(reportTwo.IsSafeWithProblemDampener()).IsEqualTo(true); await Assert.That(reportThree.IsSafeWithProblemDampener()).IsEqualTo(true); + await Assert.That(reportFour.IsSafeWithProblemDampener()).IsEqualTo(true); + await Assert.That(reportFive.IsSafeWithProblemDampener()).IsEqualTo(true); + await Assert.That(reportSix.IsSafeWithProblemDampener()).IsEqualTo(true); } [Test] @@ -95,8 +101,12 @@ public class ReportTests { var reportOne = new Report([1, 2, 7, 8, 9]); var reportTwo = new Report([9, 7, 6, 2, 1]); + var reportThree = new Report([28, 28, 31, 34, 36, 37, 40, 45]); + var reportFour = new Report([13, 15, 18, 23, 26, 33]); await Assert.That(reportOne.IsSafeWithProblemDampener()).IsEqualTo(false); await Assert.That(reportTwo.IsSafeWithProblemDampener()).IsEqualTo(false); + await Assert.That(reportThree.IsSafeWithProblemDampener()).IsEqualTo(false); + await Assert.That(reportFour.IsSafeWithProblemDampener()).IsEqualTo(false); } } \ No newline at end of file diff --git a/02/RedNosedReports/Report.cs b/02/RedNosedReports/Report.cs index b892cf1..9e5e30e 100644 --- a/02/RedNosedReports/Report.cs +++ b/02/RedNosedReports/Report.cs @@ -4,11 +4,19 @@ class Report(List levels) { private readonly List _levels = levels; + public string GetDebugOutput() + { + return $"{string.Join(' ', _levels)} {IsSafe()} {IsSafeWithProblemDampener()}"; + } + public bool IsSafe() { for (var i = 0; i < _levels.Count - 1; i++) { - if (CheckIfSafe(_levels[i], _levels[i + 1]) is false) + var current = _levels[i]; + var next = _levels[i + 1]; + + if (HasExceededLimits(current, next) || HasChangedDirection(current, next)) { return false; } @@ -24,9 +32,37 @@ class Report(List levels) var nextIndex = currentIndex + 1; var current = _levels[currentIndex]; var next = _levels[nextIndex]; + var directionChanged = HasChangedDirection(current, next); - if (CheckIfSafe(current, next) is false) + // problem dampener permits us to try to make + // levels work after removing one of them. + // so when we encounter a violation...either direction + // of levels change or levels change so much that they exceed + // the limits we are going to attempt to see if + // the levels will work if we remove one of the levels in + // the current pair. + if (HasExceededLimits(current, next) || directionChanged) { + // specific edge case where direction changes + // on the second pair of levels after the first + // pair is a valid. + // i.e. 43, 41, 43, 44, 45, 47, 49 + // in this case we should attempt to make levels + // work by removing first element so that we can + // essentially reset what the valid direction is. + if (directionChanged && currentIndex is 1) + { + var levelsWithoutFirstElement = _levels.ToList(); + levelsWithoutFirstElement.RemoveAt(0); + var isSafeWithoutFirstElement = new Report(levelsWithoutFirstElement).IsSafe(); + + if (isSafeWithoutFirstElement) + { + return true; + } + } + + // check if levels work without the current level var levelsWithoutCurrent = _levels.ToList(); levelsWithoutCurrent.RemoveAt(currentIndex); var isSafeWithoutCurrent = new Report(levelsWithoutCurrent).IsSafe(); @@ -36,6 +72,7 @@ class Report(List levels) return true; } + // check if levels work without the next level var levelsWithoutNext = _levels.ToList(); levelsWithoutNext.RemoveAt(nextIndex); var isSafeWithoutNext = new Report(levelsWithoutNext).IsSafe(); @@ -45,6 +82,9 @@ class Report(List levels) return true; } + // if won't work with all levels + // or without current or next then doesn't + // work at all. return false; } } @@ -52,30 +92,36 @@ class Report(List levels) return true; } - private bool CheckIfSafe(int current, int next) + private bool HasExceededLimits(int current, int next) + { + var delta = Math.Abs(next - current); + + if (delta > 3 || delta < 1) + { + return true; + } + + return false; + } + + private bool HasChangedDirection(int current, int next) { var direction = _levels[1] > _levels[0] ? Direction.Increasing : Direction.Decreasing; var isNextGreaterThanCurrent = next > current; - var delta = Math.Abs(next - current); - - if (delta > 3 || delta < 1) - { - return false; - } if (direction is Direction.Increasing && isNextGreaterThanCurrent is false) { - return false; + return true; } if (direction is Direction.Decreasing && isNextGreaterThanCurrent) { - return false; + return true; } - return true; + return false; } }