97 lines
3.5 KiB
Rust
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
|