aoc/2024/src/bin/2024_02a.rs
2025-09-02 09:42:27 -04:00

97 lines
3.5 KiB
Rust

// Fortunately, the first location The Historians want to search isn't a long walk from the Chief
// Historian's office.
//
// While the Red-Nosed Reindeer nuclear fusion/fission plant appears to contain no sign of the
// Chief Historian, the engineers there run up to you as soon as they see you. Apparently, they
// still talk about the time Rudolph was saved through molecular synthesis from a single electron.
//
// They're quick to add that - since you're already here - they'd really appreciate your help
// analyzing some unusual data from the Red-Nosed reactor. You turn to check if The Historians are
// waiting for you, but they seem to have already divided into groups that are currently searching
// every corner of the facility. You offer to help with the unusual data.
//
// The unusual data (your puzzle input) consists of many reports, one report per line. Each report
// is a list of numbers called levels that are separated by spaces. For example:
//
// 7 6 4 2 1
// 1 2 7 8 9
// 9 7 6 2 1
// 1 3 2 4 5
// 8 6 4 4 1
// 1 3 6 7 9
// This example data contains six reports each containing five levels.
//
// The engineers are trying to figure out which reports are safe. The Red-Nosed reactor safety
// systems can only tolerate levels that are either gradually increasing or gradually decreasing.
// So, a report only counts as safe if both of the following are true:
//
// The levels are either all increasing or all decreasing.
// Any two adjacent levels differ by at least one and at most three.
// In the example above, the reports can be found safe or unsafe by checking those rules:
//
// 7 6 4 2 1: Safe because the levels are all decreasing by 1 or 2.
// 1 2 7 8 9: Unsafe because 2 7 is an increase of 5.
// 9 7 6 2 1: Unsafe because 6 2 is a decrease of 4.
// 1 3 2 4 5: Unsafe because 1 3 is increasing but 3 2 is decreasing.
// 8 6 4 4 1: Unsafe because 4 4 is neither an increase or a decrease.
// 1 3 6 7 9: Safe because the levels are all increasing by 1, 2, or 3.
// So, in this example, 2 reports are safe.
use std::{env, fs};
use core::read_data;
fn min_max(num1: u32, num2: u32) -> (u32, u32) {
(num1.min(num2), num1.max(num2))
}
fn in_range(min: u32, max: u32, target: u32) -> bool {
min <= target && target <= max
}
fn parse_numbers(s: &str) -> Vec<u32> {
s.split_whitespace() // split on whitespace
.filter_map(|num| num.parse::<u32>().ok()) // try to parse each piece
.collect()
}
fn is_safe(report: &str) -> bool {
let mut is_safe = true;
let numbers = parse_numbers(report);
println!("*******************************************************\nnumbers: {:?}", numbers);
let mut is_increasing = numbers[0] < numbers[1];
for index in 0..numbers.len() - 1 {
let first = numbers[index];
let second = numbers[index + 1];
if first.abs_diff(second) > 3 || first.abs_diff(second) < 1 {
is_safe = false;
}
if is_increasing && first >= second {
is_safe = false;
}
if !is_increasing && first <= second {
is_safe = false;
}
}
is_safe
}
fn main() {
let input_file = read_data("2024_02_data.txt");
let mut num_safe = 0;
// let input_file = "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9";
let reports = input_file.lines();
for report in reports {
let is_safe = is_safe(report);
println!("Handling report of {report} -> Safe: {}",is_safe);
if is_safe {
num_safe += 1;
}
}
println!("Found {num_safe} safe readings.");
}
// 606