Skip to content

Commit 171c12a

Browse files
committed
[2025] Faster algo for day 5
1 parent 71f7603 commit 171c12a

File tree

1 file changed

+17
-53
lines changed

1 file changed

+17
-53
lines changed

aoc_2025/src/day_05.rs

Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1-
use std::{mem, ops::RangeInclusive};
1+
use std::ops::RangeInclusive;
22

33
use common::{Answer, solution};
44

55
solution!("Cafeteria", 5);
66

7-
type Range = RangeInclusive<u64>;
8-
97
fn part_a(input: &str) -> Answer {
108
let (ranges, nums) = parse(input);
11-
let count = nums.iter().filter(|x| ranges.contains(x)).count();
12-
count.into()
9+
nums.iter()
10+
.filter(|n| ranges.iter().any(|r| r.contains(n)))
11+
.count()
12+
.into()
1313
}
1414

1515
fn part_b(input: &str) -> Answer {
16-
let (ranges, _) = parse(input);
17-
ranges.count().into()
16+
let (mut ranges, _) = parse(input);
17+
ranges.sort_by_key(|x| *x.start());
18+
19+
let (mut out, mut max) = (0, 0);
20+
for range in ranges {
21+
let (start, end) = (*range.start().max(&max), range.end() + 1);
22+
out += end.saturating_sub(start);
23+
max = max.max(end);
24+
}
25+
26+
out.into()
1827
}
1928

20-
fn parse(input: &str) -> (Ranges, Vec<u64>) {
29+
fn parse(input: &str) -> (Vec<RangeInclusive<u64>>, Vec<u64>) {
2130
let (ranges, nums) = input.split_once("\n\n").unwrap();
2231

2332
let ranges = (ranges.lines())
@@ -26,56 +35,11 @@ fn parse(input: &str) -> (Ranges, Vec<u64>) {
2635
first.parse().unwrap()..=last.parse().unwrap()
2736
})
2837
.collect();
29-
3038
let nums = nums.lines().map(|x| x.parse().unwrap()).collect();
3139

3240
(ranges, nums)
3341
}
3442

35-
#[derive(Default, Debug)]
36-
struct Ranges {
37-
inner: Vec<Range>,
38-
}
39-
40-
impl Ranges {
41-
fn add(&mut self, mut new: RangeInclusive<u64>) {
42-
fn range_combine(a: &Range, b: &Range) -> Option<Range> {
43-
(a.start() <= b.start() && a.end() >= b.start()
44-
|| b.start() <= a.start() && b.end() >= a.start())
45-
.then(|| (*a.start().min(b.start()))..=(*a.end().max(b.end())))
46-
}
47-
48-
let mut i = 0;
49-
while i < self.inner.len() {
50-
if let Some(combination) = range_combine(&self.inner[i], &new) {
51-
self.inner.remove(mem::take(&mut i));
52-
new = combination;
53-
continue;
54-
}
55-
56-
i += 1;
57-
}
58-
59-
self.inner.push(new);
60-
}
61-
62-
fn contains(&self, val: &u64) -> bool {
63-
self.inner.iter().any(|x| x.contains(val))
64-
}
65-
66-
fn count(&self) -> u64 {
67-
self.inner.iter().map(|x| x.end() - x.start() + 1).sum()
68-
}
69-
}
70-
71-
impl FromIterator<Range> for Ranges {
72-
fn from_iter<T: IntoIterator<Item = Range>>(iter: T) -> Self {
73-
let mut out = Ranges::default();
74-
iter.into_iter().for_each(|item| out.add(item));
75-
out
76-
}
77-
}
78-
7943
#[cfg(test)]
8044
mod test {
8145
use indoc::indoc;

0 commit comments

Comments
 (0)