Day2 task 1 finished

This commit is contained in:
Martin Berg Alstad 2024-12-03 22:37:39 +01:00
parent 17b95068da
commit fea2ed57c6
Signed by: martials
GPG Key ID: DF629A90917D1319
7 changed files with 1119 additions and 1 deletions

4
Cargo.lock generated
View File

@ -9,3 +9,7 @@ version = "0.1.0"
[[package]] [[package]]
name = "day1" name = "day1"
version = "0.1.0" version = "0.1.0"
[[package]]
name = "day2"
version = "0.1.0"

View File

@ -1,5 +1,5 @@
[workspace] [workspace]
members = ["./day*"] members = ["./day*", "day2"]
[package] [package]
name = "advent_of_code_2024" name = "advent_of_code_2024"

6
day2/Cargo.toml Normal file
View File

@ -0,0 +1,6 @@
[package]
name = "day2"
version = "0.1.0"
edition = "2021"
[dependencies]

89
day2/src/common.rs Normal file
View File

@ -0,0 +1,89 @@
use std::convert::{identity, Infallible};
use std::str::FromStr;
pub(crate) struct Level(Vec<usize>);
impl FromStr for Level {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(
s.split(" ")
.filter_map(|value| value.parse::<usize>().ok())
.collect::<Vec<_>>(),
))
}
}
impl Level {
// TODO optimize
pub(crate) fn is_safe(&self) -> bool {
(0..self.0.len())
.map(|index| Self::is_increasing(&self.0[index..]))
.all(identity)
|| (0..self.0.len())
.map(|index| Self::is_decreasing(&self.0[index..]))
.all(identity)
}
pub(crate) fn is_increasing(array: &[usize]) -> bool {
Self::is_changing(array, PartialOrd::gt)
}
pub(crate) fn is_decreasing(array: &[usize]) -> bool {
Self::is_changing(array, PartialOrd::lt)
}
fn is_changing(array: &[usize], operator: fn(&usize, &usize) -> bool) -> bool {
match array {
[first, second, ..] if operator(second, first) => Self::is_legal_diff(*first, *second),
[_singleton] => true,
_ => false,
}
}
fn is_legal_diff(first: usize, second: usize) -> bool {
usize::abs_diff(first, second) >= 1 && usize::abs_diff(first, second) <= 3
}
}
pub(crate) fn parse_input(input: &str) -> Vec<Level> {
input
.split("\n")
.map(Level::from_str)
.collect::<Result<_, _>>()
.unwrap()
}
#[cfg(test)]
mod tests {
use crate::common::Level;
#[test]
fn test_is_increasing() {
let increasing_array = [1, 2, 3];
assert!(Level::is_increasing(&increasing_array))
}
#[test]
fn test_is_safe_no_change() {
let increasing_then_not = vec![1, 2, 2, 3];
assert!(!Level(increasing_then_not).is_safe())
}
#[test]
fn test_task_1() {
let test_decreasing = vec![7, 6, 4, 2, 1];
let test_increase_of_5 = vec![1, 2, 7, 8, 9];
let test_decrease_of_4 = vec![9, 7, 6, 2, 1];
let test_increase_and_decrease = vec![1, 3, 2, 4, 5];
let test_leveled = vec![8, 6, 4, 4, 1];
let test_increasing = vec![1, 3, 6, 7, 9];
assert!(Level(test_decreasing).is_safe());
assert!(!Level(test_increase_of_5).is_safe());
assert!(!Level(test_decrease_of_4).is_safe());
assert!(!Level(test_increase_and_decrease).is_safe());
assert!(!Level(test_leveled).is_safe());
assert!(Level(test_increasing).is_safe());
}
}

1000
day2/src/input.txt Normal file

File diff suppressed because it is too large Load Diff

8
day2/src/main.rs Normal file
View File

@ -0,0 +1,8 @@
use crate::task1::task1;
mod task1;
mod common;
fn main() {
task1();
}

11
day2/src/task1.rs Normal file
View File

@ -0,0 +1,11 @@
use crate::common::{parse_input, Level};
pub(crate) fn task1() {
let raw_input = include_str!("./input.txt");
let levels = parse_input(raw_input);
let count = levels.into_iter()
.filter(Level::is_safe)
.count();
println!("The solution to task 1 is {}", count)
}