Skip to content

Commit 9f119b0

Browse files
committed
chore: cleanup (of sorts)
1 parent b1723ea commit 9f119b0

File tree

4 files changed

+103
-42
lines changed

4 files changed

+103
-42
lines changed

aoclp/src/functional.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
pub trait PredHelper<T, U> {
1+
pub trait ConsumingPredHelper<T, U> {
22
fn with_ref(self) -> impl Fn(&T) -> U
33
where
44
T: Clone;
55
}
66

7-
impl<F, T, U> PredHelper<T, U> for F
7+
impl<F, T, U> ConsumingPredHelper<T, U> for F
88
where
99
F: Fn(T) -> U,
1010
{
@@ -15,3 +15,16 @@ where
1515
move |x| self(x.clone())
1616
}
1717
}
18+
19+
pub trait ByRefPredHelper<T, U> {
20+
fn without_ref(self) -> impl Fn(T) -> U;
21+
}
22+
23+
impl<F, T, U> ByRefPredHelper<T, U> for F
24+
where
25+
F: Fn(&T) -> U,
26+
{
27+
fn without_ref(self) -> impl Fn(T) -> U {
28+
move |x| self(&x)
29+
}
30+
}

aoclp/src/solvers_impl/input.rs

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,7 @@ impl<'a> Input<'a> {
9494
T: FromStr,
9595
<T as FromStr>::Err: std::fmt::Debug,
9696
{
97-
String::try_from(self)?
98-
.lines()
99-
.map(|line| {
100-
line.parse()
101-
.map_err(|e| anyhow!("failed to parse \"{line}\": {e:?}"))
102-
})
103-
.collect()
97+
Self::parse_many(String::try_from(self)?.lines())
10498
}
10599

106100
pub fn safe_into_many<T>(self) -> Vec<T>
@@ -117,22 +111,15 @@ impl<'a> Input<'a> {
117111
<T as FromStr>::Err: std::fmt::Debug,
118112
{
119113
let separators = self.separators;
120-
String::try_from(self)?
121-
.lines()
122-
.map(|line| {
123-
let (a, b) = line
124-
.split(separators)
125-
.filter(|value| !value.is_empty())
126-
.collect_tuple()
127-
.ok_or(anyhow!("invalid number of elements in \"{line}\""))?;
128-
Ok((
129-
a.parse()
130-
.map_err(|e| anyhow!("failed to parse \"{a}\": {e:?}"))?,
131-
b.parse()
132-
.map_err(|e| anyhow!("failed to parse \"{b}\": {e:?}"))?,
133-
))
114+
let vecs = Self::parse_many_vecs(String::try_from(self)?.lines(), separators)?;
115+
116+
Ok(vecs
117+
.into_iter()
118+
.map(|v| {
119+
let (a, b) = v.into_iter().collect_tuple().unwrap();
120+
(a, b)
134121
})
135-
.collect()
122+
.collect())
136123
}
137124

138125
pub fn safe_into_many_pairs<T>(self) -> Vec<(T, T)>
@@ -160,6 +147,31 @@ impl<'a> Input<'a> {
160147
self.into_many_vecs().unwrap()
161148
}
162149

150+
pub fn into_many_of_two_types<T, U>(self) -> crate::Result<(Vec<T>, Vec<U>)>
151+
where
152+
T: FromStr,
153+
U: FromStr,
154+
<T as FromStr>::Err: std::fmt::Debug,
155+
<U as FromStr>::Err: std::fmt::Debug,
156+
{
157+
let data: String = self.try_into()?;
158+
159+
let first = Self::parse_many(data.lines().take_while(|line| !line.is_empty()))?;
160+
let second = Self::parse_many(data.lines().skip_while(|line| !line.is_empty()).skip(1))?;
161+
162+
Ok((first, second))
163+
}
164+
165+
pub fn safe_into_many_of_two_types<T, U>(self) -> (Vec<T>, Vec<U>)
166+
where
167+
T: FromStr,
168+
U: FromStr,
169+
<T as FromStr>::Err: std::fmt::Debug,
170+
<U as FromStr>::Err: std::fmt::Debug,
171+
{
172+
self.into_many_of_two_types().unwrap()
173+
}
174+
163175
#[allow(clippy::type_complexity)]
164176
pub fn into_many_vecs_of_two_types<T, U>(self) -> crate::Result<(Vec<Vec<T>>, Vec<Vec<U>>)>
165177
where
@@ -224,6 +236,23 @@ impl<'a> Input<'a> {
224236
self.into_terrain().unwrap()
225237
}
226238

239+
fn parse_many<T, L, S>(lines: L) -> crate::Result<Vec<T>>
240+
where
241+
T: FromStr,
242+
<T as FromStr>::Err: std::fmt::Debug,
243+
L: IntoIterator<Item = S>,
244+
S: AsRef<str>,
245+
{
246+
lines
247+
.into_iter()
248+
.map(|line| {
249+
let line = line.as_ref();
250+
line.parse()
251+
.map_err(|e| anyhow!("failed to parse \"{line}\": {e:?}"))
252+
})
253+
.collect()
254+
}
255+
227256
fn parse_many_vecs<T, L, S>(lines: L, separators: &[char]) -> crate::Result<Vec<Vec<T>>>
228257
where
229258
T: FromStr,
@@ -300,6 +329,19 @@ where
300329
Input::year(year).day(day).safe_get().safe_into_one_vec()
301330
}
302331

332+
pub fn safe_get_input_as_many_of_two_types<T, U>(year: i32, day: u32) -> (Vec<T>, Vec<U>)
333+
where
334+
T: FromStr,
335+
U: FromStr,
336+
<T as FromStr>::Err: std::fmt::Debug,
337+
<U as FromStr>::Err: std::fmt::Debug,
338+
{
339+
Input::year(year)
340+
.day(day)
341+
.safe_get()
342+
.safe_into_many_of_two_types()
343+
}
344+
303345
pub fn safe_get_input_as_many_vecs_of_two_types<T, U>(
304346
year: i32,
305347
day: u32,

aoclp_solutions/src/y2025/day_02.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ops::RangeInclusive;
22
use std::str::FromStr;
33

4-
use aoclp::functional::PredHelper;
4+
use aoclp::functional::ConsumingPredHelper;
55
use aoclp::num::Integer;
66
use aoclp::solvers_impl::input::safe_get_input_as_one_vec;
77
use itertools::Itertools;
@@ -85,6 +85,7 @@ impl IntoIterator for IdRange {
8585
}
8686
}
8787

88+
// noinspection DuplicatedCode
8889
impl FromStr for IdRange {
8990
type Err = aoclp::Error;
9091

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::cmp::{max, min};
2-
use std::ops::RangeInclusive;
2+
use std::ops::{Deref, RangeInclusive};
33
use std::str::FromStr;
44

5-
use aoclp::solvers_impl::input::safe_get_input_as_many_vecs_of_two_types;
5+
use aoclp::functional::ByRefPredHelper;
6+
use aoclp::solvers_impl::input::safe_get_input_as_many_of_two_types;
67
use itertools::Itertools;
78

89
pub fn part_1() -> usize {
@@ -17,30 +18,36 @@ pub fn part_2() -> usize {
1718
let (fresh_ids, _) = input();
1819
fresh_ids
1920
.into_iter()
20-
.map(|r| r.0)
2121
.sorted_by(|a, b| a.start().cmp(b.start()).then(a.end().cmp(b.end())))
2222
.fold(Vec::new(), |mut acc, r| {
2323
match acc.last() {
2424
None => acc.push(r),
25-
Some(prev) if prev.end() < r.start() => acc.push(r),
25+
Some(prev) if (prev.end() + 1) < *r.start() => acc.push(r),
2626
Some(prev) => {
2727
let from = *min(prev.start(), r.start());
2828
let to = *max(prev.end(), r.end());
2929
acc.pop();
30-
acc.push(from..=to);
30+
acc.push(IdRange(from..=to));
3131
},
3232
}
3333

3434
acc
3535
})
3636
.into_iter()
37-
.map(|r| r.count())
37+
.map(IdRange::len.without_ref())
3838
.sum()
3939
}
4040

4141
#[derive(Debug, Clone)]
4242
struct IdRange(RangeInclusive<usize>);
4343

44+
impl IdRange {
45+
pub fn len(&self) -> usize {
46+
self.end() - self.start() + 1
47+
}
48+
}
49+
50+
// noinspection DuplicatedCode
4451
impl FromStr for IdRange {
4552
type Err = aoclp::Error;
4653

@@ -50,16 +57,14 @@ impl FromStr for IdRange {
5057
}
5158
}
5259

60+
impl Deref for IdRange {
61+
type Target = RangeInclusive<usize>;
62+
63+
fn deref(&self) -> &Self::Target {
64+
&self.0
65+
}
66+
}
67+
5368
fn input() -> (Vec<IdRange>, Vec<usize>) {
54-
let (fresh_ids, available_ids) = safe_get_input_as_many_vecs_of_two_types(2025, 5);
55-
(
56-
fresh_ids
57-
.into_iter()
58-
.map(|v| v.into_iter().next().unwrap())
59-
.collect_vec(),
60-
available_ids
61-
.into_iter()
62-
.map(|v| v.into_iter().next().unwrap())
63-
.collect_vec(),
64-
)
69+
safe_get_input_as_many_of_two_types(2025, 5)
6570
}

0 commit comments

Comments
 (0)