rs-06-interval-map
1.000
Challenge · difficulty 5/5
# Generic interval map
Implement the library file **`src/lib.rs`** exposing a generic structure that maps integer
intervals to values:
```rust
pub struct IntervalMap<T> { /* ... */ }
impl<T> IntervalMap<T> {
pub fn new() -> Self;
pub fn insert(&mut self, start: i64, end: i64, value: T);
pub fn get(&self, point: i64) -> Option<&T>;
pub fn get_all(&self, point: i64) -> Vec<&T>;
}
```
Intervals are **half-open**: `[start, end)` covers every `p` with `start <= p < end`.
- **`insert(start, end, value)`** records that the half-open interval `[start, end)` maps to
`value`. If `start >= end` the range is empty and the call is a **no-op**. Intervals may overlap.
- **`get(point)`** returns the value of the **most recently inserted** interval that covers `point`,
or `None` if no interval covers it. (Newest insert wins on overlap.)
- **`get_all(point)`** returns references to the values of **all** intervals covering `point`,
ordered **most-recently-inserted first**. Empty `Vec` if none cover it.
The structure is generic over the value type `T` (no trait bounds required). Values are owned by the
map; `get`/`get_all` return borrows.
Tests live in `tests/` and use `challenge::IntervalMap`.
tests/interval_map.rs
use challenge::IntervalMap;
#[test]
fn point_lookup_respects_half_open_bounds() {
let mut m = IntervalMap::new();
m.insert(0, 10, "a");
assert_eq!(m.get(5), Some(&"a"));
assert_eq!(m.get(0), Some(&"a")); // start is inclusive
assert_eq!(m.get(10), None); // end is exclusive
assert_eq!(m.get(-1), None);
}
#[test]
fn empty_map_returns_none() {
let m: IntervalMap<i32> = IntervalMap::new();
assert_eq!(m.get(0), None);
assert_eq!(m.get_all(0), Vec::<&i32>::new());
}
#[test]
fn newest_insert_wins_on_overlap() {
let mut m = IntervalMap::new();
m.insert(0, 10, 1);
m.insert(5, 15, 2);
assert_eq!(m.get(2), Some(&1)); // only the first interval
assert_eq!(m.get(7), Some(&2)); // overlap -> newest wins
assert_eq!(m.get(12), Some(&2)); // only the second interval
}
#[test]
fn get_all_returns_all_covering_newest_first() {
let mut m = IntervalMap::new();
m.insert(0, 10, 1);
m.insert(5, 15, 2);
m.insert(6, 8, 3);
assert_eq!(m.get_all(7), vec![&3, &2, &1]);
assert_eq!(m.get_all(2), vec![&1]);
assert_eq!(m.get_all(20), Vec::<&i32>::new());
}
#[test]
fn empty_or_reversed_ranges_are_ignored() {
let mut m = IntervalMap::new();
m.insert(5, 5, "empty");
m.insert(8, 3, "reversed");
assert_eq!(m.get(5), None);
assert_eq!(m.get(4), None);
}
#[test]
fn works_with_owned_string_values() {
let mut m = IntervalMap::new();
m.insert(0, 100, String::from("x"));
assert_eq!(m.get(50), Some(&String::from("x")));
}
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.
Proposed solution
Looking at the requirements, I need to implement a generic interval map that:
1. Stores intervals as half-open ranges `[start, end)`
2. Handles overlapping intervals (newest insert wins for `get`)
3. Returns all covering intervals in reverse insertion order for `get_all`
Here's my implementation:
```rust
#[derive(Debug)]
pub struct IntervalMap<T> {
intervals: Vec<(i64, i64, T)>,
}
impl<T> IntervalMap<T> {
pub fn new() -> Self {
IntervalMap {
intervals: Vec::new(),
}
}
pub fn insert(&mut self, start: i64, end: i64, value: T) {
// Only insert if the interval is valid (start < end)
if start < end {
self.intervals.push((start, end, value));
}
}
pub fn get(&self, point: i64) -> Option<&T> {
// Iterate in reverse order to find the most recently inserted interval
for i in (0..self.intervals.len()).rev() {
let (start, end, _) = &self.intervals[i];
if *start <= point && point < *end {
return Some(&self.intervals[i].2);
}
}
None
}
pub fn get_all(&self, point: i64) -> Vec<&T> {
let mut result = Vec::new();
// Iterate in reverse order to get most-recently-inserted first
for i in (0..self.intervals.len()).rev() {
let (start, end, _) = &self.intervals[i];
if *start <= point && point < *end {
result.push(&self.intervals[i].2);
}
}
result
}
}
impl<T> Default for IntervalMap<T> {
fn default() -> Self {
Self::new()
}
}
```
The implementation:
- Uses a `Vec` to store intervals as tuples `(start, end, value)`
- `insert` only adds valid intervals (where `start < end`)
- `get` iterates in reverse to find the most recent interval covering the point
- `get_all` collects all covering intervals in reverse insertion order (most recent first)
- Implements `Default` for convenienceTest output (stdout)
running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 6 tests ...... test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s