Day2 task 1 finished
This commit is contained in:
parent
17b95068da
commit
fea2ed57c6
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -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"
|
||||||
|
@ -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
6
day2/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "day2"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
89
day2/src/common.rs
Normal file
89
day2/src/common.rs
Normal 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
1000
day2/src/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
8
day2/src/main.rs
Normal file
8
day2/src/main.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use crate::task1::task1;
|
||||||
|
|
||||||
|
mod task1;
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
task1();
|
||||||
|
}
|
11
day2/src/task1.rs
Normal file
11
day2/src/task1.rs
Normal 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)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user