Skip to content

Commit e187e5d

Browse files
committed
fix(05/2025): fix diff method in range; fix and solve second part
1 parent 68666de commit e187e5d

File tree

3 files changed

+80
-45
lines changed

3 files changed

+80
-45
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
| [Day 2: Gift Shop](src/solutions/year2025/day02.rs) | ⭐⭐ | 65.103 | 81.719 |
1616
| [Day 3: Lobby](src/solutions/year2025/day03.rs) | ⭐⭐ | 0.131 | 0.133 |
1717
| [Day 4: Printing Department](src/solutions/year2025/day04.rs) | ⭐⭐ | 3.615 | 9.998 |
18-
| [Day 5: Cafeteria](src/solutions/year2025/day05.rs) | | 0.275 | - |
18+
| [Day 5: Cafeteria](src/solutions/year2025/day05.rs) | | 0.275 | 0.469 |
1919
| [Day 6: Trash Compactor](src/solutions/year2025/day06.rs) | ⭐⭐ | 0.117 | 2.577 |
2020

2121
# 2024

src/solutions/year2025/day05.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,10 @@ impl Day05 {
6969

7070
while let Some(range) = queue.pop_front() {
7171
result.push(range);
72-
// println!(" ==== {} ==== ", range);
7372

74-
for (k, other) in queue.clone().iter().enumerate() {
75-
if range.collide(other) {
76-
queue.remove(k);
77-
78-
let intersect = range.intersect(other).unwrap();
79-
let lefts = other.diff(&intersect);
80-
81-
// println!("{} collide: {} - {:?}", range, other, lefts);
82-
83-
for left in lefts {
84-
queue.push_back(left);
85-
}
86-
}
87-
}
73+
queue = queue.iter().flat_map(|other| other.diff(&range)).collect();
8874
}
8975

90-
// println!("{:?}", result);
91-
9276
result.iter().map(|range| range.len()).sum::<isize>()
9377
}
9478
}

src/utils/range.rs

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -56,33 +56,72 @@ impl Range {
5656
Ok(Self::new(self.start.max(other.start), self.end.min(other.end)).unwrap())
5757
}
5858

59+
/// Calculates the difference between two ranges.
60+
///
61+
/// This method returns a vector of ranges representing the parts of `self`
62+
/// that are not present in `other`.
63+
///
64+
/// # Cases:
65+
/// - If `other` completely contains `self`, the result is an empty vector.
66+
/// - If `self` completely contains `other`, the result is a vector with two ranges.
67+
/// - If they partially overlap, the result is a vector with one range.
68+
/// - If they do not overlap, the result is a vector containing `self`.
69+
///
70+
/// # Example
71+
///
72+
/// ```
73+
/// use crate::utils::range::Range;
74+
///
75+
/// let range = Range::new(3, 8).unwrap();
76+
///
77+
/// // Case where `other` is inside `self`
78+
/// let other1 = Range::new(5, 6).unwrap();
79+
/// assert_eq!(
80+
/// vec![Range::new(3, 4).unwrap(), Range::new(7, 8).unwrap()],
81+
/// range.diff(&other1)
82+
/// );
83+
///
84+
/// // Case where `other` overlaps on the right
85+
/// let other2 = Range::new(7, 10).unwrap();
86+
/// assert_eq!(
87+
/// vec![Range::new(3, 6).unwrap()],
88+
/// range.diff(&other2)
89+
/// );
90+
///
91+
/// // Case where `other` does not overlap
92+
/// let other3 = Range::new(10, 12).unwrap();
93+
/// assert_eq!(
94+
/// vec![range],
95+
/// range.diff(&other3)
96+
/// );
97+
///
98+
/// // Case where `other` completely contains `self`
99+
/// let other4 = Range::new(1, 10).unwrap();
100+
/// assert_eq!(
101+
/// Vec::<Range>::new(),
102+
/// range.diff(&other4)
103+
/// );
104+
/// ```
59105
pub fn diff(&self, other: &Self) -> Vec<Self> {
60-
// other is outside self
61-
if other.start <= self.start && other.end >= self.end {
62-
return vec![];
63-
}
106+
let mut result = Vec::new();
64107

65-
// other is inside self
66-
if other.start > self.start && other.end < self.end {
67-
return vec![
68-
Self::new(self.start, other.start - 1).unwrap(),
69-
Self::new(other.end + 1, self.end).unwrap(),
70-
];
108+
// Part of self before other starts
109+
if self.start < other.start {
110+
let end = self.end.min(other.start - 1);
111+
if self.start <= end {
112+
result.push(Self::new(self.start, end).unwrap());
113+
}
71114
}
72115

73-
let start: isize;
74-
let end: isize;
75-
76-
// collide on side
77-
if self.start < other.start {
78-
start = self.start.min(other.start);
79-
end = self.start.max(other.start) - 1;
80-
} else {
81-
start = self.end.min(other.end) + 1;
82-
end = self.end.max(other.end);
116+
// Part of self after other ends
117+
if self.end > other.end {
118+
let start = self.start.max(other.end + 1);
119+
if start <= self.end {
120+
result.push(Self::new(start, self.end).unwrap());
121+
}
83122
}
84123

85-
vec![Self::new(start, end).unwrap()]
124+
result
86125
}
87126

88127
pub fn iter(&self) -> impl Iterator<Item = isize> {
@@ -192,14 +231,26 @@ mod tests {
192231
);
193232

194233
assert_eq!(
195-
vec![Range::new(3, 3).unwrap(), Range::new(6, 6).unwrap(),],
234+
vec![Range::new(3, 3).unwrap(), Range::new(6, 6).unwrap()],
196235
range.diff(&Range::new(4, 5).unwrap())
197236
);
198237

199-
// @fixme - why it doesnt work for that case?
200-
// assert_eq!(
201-
// Vec::<Range>::new(),
202-
// range.diff(&Range::new(10, 14).unwrap())
203-
// );
238+
// Case where other does not overlap and is after self
239+
assert_eq!(vec![range], range.diff(&Range::new(10, 14).unwrap()));
240+
241+
// Case where other does not overlap and is before self
242+
assert_eq!(vec![range], range.diff(&Range::new(0, 1).unwrap()));
243+
244+
// Case where other completely contains self
245+
assert_eq!(Vec::<Range>::new(), range.diff(&Range::new(2, 7).unwrap()));
246+
247+
// Case where self and other are identical
248+
assert_eq!(Vec::<Range>::new(), range.diff(&Range::new(3, 6).unwrap()));
249+
250+
// Case where other overlaps on the left
251+
assert_eq!(
252+
vec![Range::new(5, 6).unwrap()],
253+
range.diff(&Range::new(1, 4).unwrap())
254+
);
204255
}
205256
}

0 commit comments

Comments
 (0)