Red-Nosed Reports

2024-12-02

Problem Overview

In this challenge, we analyze reactor safety reports. Each report is a sequence of levels, and a report is considered "safe" if:

  • The levels are either all increasing or all decreasing
  • Adjacent levels differ by at least 1 and at most 3

Our task is to count how many reports are safe.

Part 1: Basic Safety Check

Looking at this problem, I need to determine if each sequence follows a consistent pattern. The tricky part is that I don't know upfront whether a sequence should be increasing or decreasing - I have to figure that out as I go.

My approach is to track both possibilities until I see the first difference between consecutive numbers. Once I know the direction, any violation of that pattern or any jump outside the 1-3 range means the report is unsafe. Single-element reports are an interesting edge case - they're technically safe since they don't violate any rules!

#include<bits/stdc++.h> using namespace std; int main() { ifstream file("input.txt"); string line; int safe = 0; while (getline(file, line)) { stringstream ss(line); int num, prev = -1, inc = -1, dec = -1; bool increasing = true, decreasing = true, is_safe = true; while (ss >> num) { if (prev == -1) prev = num; else { if (inc == -1 && dec == -1) { if (num > prev) inc = 1; else if (num < prev) dec = 1; } if (inc == 1 && num <= prev) increasing = false; if (dec == 1 && num >= prev) decreasing = false; if (abs(num - prev) < 1 || abs(num - prev) > 3) is_safe = false; prev = num; } } if (increasing && decreasing && is_safe) safe++; } cout << safe << endl; }

Part 2: Problem Dampener

Part 2 introduces the Problem Dampener - we can now tolerate one bad reading by removing it. This changes the game completely. Instead of immediately rejecting an unsafe report, I need to check if removing any single element would make it safe.

The strategy is straightforward but thorough: first check if the report is already safe (no need to remove anything), and if not, try removing each element one by one until I find a configuration that works. It's like having a second chance when something goes wrong!

#include<bits/stdc++.h> using namespace std; bool check_safety(vector<int> level, int avoid) { int prev = -1, inc = -1, dec = -1; bool increasing = true, decreasing = true, is_safe = true; for (int i = 0; i < level.size(); ++i) { if (i == avoid) continue; if (prev == -1) prev = level[i]; else { if (inc == -1 && dec == -1) { if (level[i] > prev) inc = 1; else if (level[i] < prev) dec = 1; } if (inc == 1 && level[i] <= prev) increasing = false; if (dec == 1 && level[i] >= prev) decreasing = false; if (abs(level[i] - prev) < 1 || abs(level[i] - prev) > 3) is_safe = false; prev = level[i]; } } if (increasing && decreasing && is_safe) return true; return false; } int main() { ifstream file("input.txt"); string line; int safe = 0; vector<vector<int>> reports; while (getline(file, line)) { stringstream ss(line); vector<int> levels; int num; while (ss >> num) levels.push_back(num); reports.push_back(levels); } for (auto report : reports) { if (check_safety(report, -1)) safe++; else { for (int i = 0; i < report.size(); ++i) { if (check_safety(report, i)) { safe++; break; } } } } cout << safe << endl; }

Turns out the Problem Dampener is just "try turning it off and on again" but for data points. Works every time!