This commit is contained in:
itsscb 2024-12-14 21:46:01 +01:00
parent ecf3241c3c
commit 890d2b4d76
2 changed files with 192 additions and 13 deletions

View File

@ -5,7 +5,8 @@ use std::{error::Error, fs};
/// # Errors
///
/// This function will return an error if the file cannot be read or if the input is invalid.
pub fn solve_day02(path: &str) -> Result<i32, Box<dyn Error>> {
#[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
pub fn solve_day02(path: &str) -> Result<(i32, i32), Box<dyn Error>> {
let content = fs::read_to_string(path)?;
let data: Vec<Vec<i32>> = content
@ -16,18 +17,126 @@ pub fn solve_day02(path: &str) -> Result<i32, Box<dyn Error>> {
.collect::<Result<Vec<_>, _>>()
})
.collect::<Result<Vec<_>, _>>()?;
Ok(0)
let result = verify_all_reports(&data);
let result1 = result
.iter()
.filter(|safety| *safety != &Safety::Unsafe)
.count() as i32;
let result = verify_tolerance(&data);
let result2 = result
.iter()
.filter(|safety| *safety != &Safety::Unsafe)
.count() as i32;
Ok((result1, result2))
}
fn calculate_report_safety(data: &Vec<Vec<i32>>) -> i32 {
data.iter()
.map(|reports| {
for report in reports {
todo!("Implement this")
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
enum Safety {
Safe,
Unsafe,
}
#[allow(dead_code)]
fn verify_all_reports(reports: &[Vec<i32>]) -> Vec<Safety> {
reports
.iter()
.map(|report| verify_reports(report))
.collect()
}
#[allow(dead_code)]
fn verify_tolerance(reports: &[Vec<i32>]) -> Vec<Safety> {
reports
.iter()
// .filter(|report| verify_reports(report) == Safety::Unsafe)
.map(|report| {
let rep = verify_reports(report);
if rep == Safety::Safe {
return Safety::Safe;
}
if report
.iter()
.enumerate()
.map(|(index, _)| {
let temp: Vec<i32> = report
.iter()
.enumerate()
.filter(|(i, _)| *i != index)
.map(|(_, r)| *r)
.collect();
// dbg!(&report, index, &temp);
verify_reports(&temp)
})
.any(|r| r == Safety::Safe)
{
Safety::Safe
} else {
Safety::Unsafe
}
0
})
.sum()
.collect()
}
#[allow(dead_code)]
fn verify_reports(reports: &[i32]) -> Safety {
const MAX: i32 = 3;
const MIN: i32 = 1;
for (index, report) in reports.iter().enumerate() {
if index == 0 {
continue;
}
let previous_report = reports[index - 1];
if index == reports.len() - 1 {
match (*report, previous_report) {
(r, p) if r > p => {
let level = r - p;
if !(MIN..=MAX).contains(&level) {
return Safety::Unsafe;
}
}
(r, p) if r < p => {
let level = p - r;
if !(MIN..=MAX).contains(&level) {
return Safety::Unsafe;
}
}
(r, p) if r == p => return Safety::Unsafe,
_ => (),
}
return Safety::Safe;
}
let next_report = reports[index + 1];
match (*report, previous_report, next_report) {
(r, p, n) if r > p && r < n => {
let level = r - p;
if !(MIN..=MAX).contains(&level) {
return Safety::Unsafe;
}
}
(r, p, n) if r < p && r > n => {
let level = p - r;
if !(MIN..=MAX).contains(&level) {
return Safety::Unsafe;
}
}
(r, p, n) if (r < p && r < n) || (r > p && r > n) => {
return Safety::Unsafe;
}
(r, p, n) if r == p || r == n => return Safety::Unsafe,
_ => (),
}
}
Safety::Safe
}
#[cfg(test)]
@ -35,7 +144,7 @@ mod test {
use super::*;
#[test]
fn test_day02() {
fn test_day02_part_one() {
let input = vec![
vec![7, 6, 4, 2, 1],
vec![1, 2, 7, 8, 9],
@ -45,8 +154,62 @@ mod test {
vec![1, 3, 6, 7, 9],
];
let want = 2;
let want = Safety::Safe;
let got = verify_reports(&input[0]);
assert_eq!(calculate_report_safety(&input), want);
assert_eq!(want, got);
let want = Safety::Unsafe;
let got = verify_reports(&input[1]);
assert_eq!(want, got);
let got = verify_reports(&input[2]);
assert_eq!(want, got);
let got = verify_reports(&input[3]);
assert_eq!(want, got);
let got = verify_reports(&input[4]);
assert_eq!(want, got);
let want = 2;
let got = verify_all_reports(&input);
assert_eq!(
want,
got.iter()
.filter(|safety| *safety != &Safety::Unsafe)
.count()
);
let got = verify_all_reports(&input);
assert_eq!(
want,
got.iter()
.filter(|safety| *safety != &Safety::Unsafe)
.count()
);
}
#[test]
fn test_day02_part_two() {
let input = vec![
vec![7, 6, 4, 2, 1],
vec![1, 2, 7, 8, 9],
vec![9, 7, 6, 2, 1],
vec![1, 3, 2, 4, 5],
vec![8, 6, 4, 4, 1],
vec![1, 3, 6, 7, 9],
];
let want = 4;
let got = verify_tolerance(&input);
assert_eq!(input.len(), got.len());
assert_eq!(
want,
got.iter()
.filter(|safety| *safety != &Safety::Unsafe)
.count()
);
}
}

View File

@ -1,4 +1,4 @@
use adventofcode_24::day01::solve_day01;
use adventofcode_24::{day01::solve_day01, day02::solve_day02};
use clap::{Arg, Command};
fn main() {
@ -11,6 +11,11 @@ fn main() {
.short('1')
.help("Path to Day 01 Input file"),
)
.arg(
Arg::new("day02")
.short('2')
.help("Path to Day 02 Input file"),
)
.get_matches();
if let Some(file) = matches.get_one::<String>("day01") {
@ -19,4 +24,15 @@ fn main() {
Err(e) => eprintln!("{e}"),
}
}
if let Some(file) = matches.get_one::<String>("day02") {
match solve_day02(file) {
Ok((r1, r2)) => {
println!(
"Result of Day 02:\nSafe Reports: {r1}\nSafe Reports with tolerance: {r2}"
);
}
Err(e) => eprintln!("{e}"),
}
}
}