Skip to content

Commit 824c951

Browse files
committed
Day 2
1 parent 2a419d3 commit 824c951

File tree

5 files changed

+88
-3
lines changed

5 files changed

+88
-3
lines changed

.aocf/config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
year = 2024
2-
day = 1
2+
day = 2
33
editor = "vim"
44
pager = "less"

src/day_02.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use itertools::Itertools;
2+
3+
use crate::helpers::input::safe_get_input_as_vecs;
4+
5+
pub fn part_1() -> String {
6+
input().into_iter().filter(|v| safe(v)).count().to_string()
7+
}
8+
9+
pub fn part_2() -> String {
10+
input()
11+
.into_iter()
12+
.filter(|v| dampened(v).iter().any(|v| safe(v)))
13+
.count()
14+
.to_string()
15+
}
16+
17+
fn input() -> Vec<Vec<i64>> {
18+
safe_get_input_as_vecs(2024, 2)
19+
}
20+
21+
fn example_input() -> Vec<Vec<i64>> {
22+
vec![
23+
vec![7, 6, 4, 2, 1],
24+
vec![1, 2, 7, 8, 9],
25+
vec![9, 7, 6, 2, 1],
26+
vec![1, 3, 2, 4, 5],
27+
vec![8, 6, 4, 4, 1],
28+
vec![1, 3, 6, 7, 9],
29+
]
30+
}
31+
32+
fn safe(levels: &[i64]) -> bool {
33+
let signum = (levels[0] - levels[1]).signum();
34+
levels.iter().tuple_windows().all(|(&a, &b)| {
35+
let new_diff = a - b;
36+
new_diff.signum() == signum && (1i64..=3).contains(&new_diff.abs())
37+
})
38+
}
39+
40+
#[allow(clippy::ptr_arg)]
41+
fn dampened(levels: &Vec<i64>) -> Vec<Vec<i64>> {
42+
(0..levels.len())
43+
.map(|i| {
44+
let mut dampened = levels.clone();
45+
dampened.remove(i);
46+
dampened
47+
})
48+
.collect()
49+
}

src/helpers/input.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,33 @@ impl Input {
113113
{
114114
self.into_pairs().unwrap()
115115
}
116+
117+
pub fn into_vecs<T>(self) -> Result<Vec<Vec<T>>, anyhow::Error>
118+
where
119+
T: FromStr,
120+
<T as FromStr>::Err: std::fmt::Debug,
121+
{
122+
String::try_from(self)?
123+
.lines()
124+
.map(|line| {
125+
line.split_ascii_whitespace()
126+
.map(|value| {
127+
value
128+
.parse()
129+
.map_err(|e| anyhow::anyhow!("failed to parse \"{line}\": {e:?}"))
130+
})
131+
.collect()
132+
})
133+
.collect()
134+
}
135+
136+
pub fn safe_into_vecs<T>(self) -> Vec<Vec<T>>
137+
where
138+
T: FromStr,
139+
<T as FromStr>::Err: std::fmt::Debug,
140+
{
141+
self.into_vecs().unwrap()
142+
}
116143
}
117144

118145
impl TryFrom<Input> for String {
@@ -150,3 +177,11 @@ where
150177
{
151178
Input::year(year).day(day).safe_get().safe_into_pairs()
152179
}
180+
181+
pub fn safe_get_input_as_vecs<T>(year: i32, day: u32) -> Vec<Vec<T>>
182+
where
183+
T: FromStr,
184+
<T as FromStr>::Err: std::fmt::Debug,
185+
{
186+
Input::year(year).day(day).safe_get().safe_into_vecs()
187+
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#![allow(dead_code)]
44

55
pub mod day_01;
6+
pub mod day_02;
67
#[macro_use]
78
pub(crate) mod helpers;
89

9-
build_runner_for_days!(01);
10+
build_runner_for_days!(01, 02);

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct Cli {
4949

5050
fn parse_day(day: &str) -> Result<u32, String> {
5151
let day = day.parse().map_err(|e| format!("{e:?}"))?;
52-
if (1..(RUNNERS.len() as u32)).contains(&day) {
52+
if (1..=(RUNNERS.len() as u32)).contains(&day) {
5353
Ok(day)
5454
} else {
5555
Err(format!("{day} is not in 1..={}", RUNNERS.len()))

0 commit comments

Comments
 (0)