โข Option
โข Result
โข The ? operator propagates errors up the call stack concisely
โข Combinators like .map(), .and_then(), .unwrap_or() chain fallible operations
โข The compiler forces you to handle every error case โ no silent failures
โข Option
โข Result
โข The ? operator propagates errors up the call stack concisely
โข Combinators like .map(), .and_then(), .unwrap_or() chain fallible operations
โข The compiler forces you to handle every error case โ no silent failures
fn slice<T: Clone>(lst: &[T], i: usize, k: usize) -> Vec<T> {
let start = if i == 0 { 0 } else { i - 1 }; // 1-based โ 0-based
let end = k.min(lst.len()); // clamp to list length
if start >= end {
return vec![]; // empty range
}
lst[start..end].to_vec() // Rust slice: 0-based, exclusive end
}
| Concept | OCaml | Rust |
|---|---|---|
| Slice syntax | No native slice; use `List.filteri` | `lst[start..end]` (0-based, exclusive) |
| Index convention | 1-based (99 Problems style) | 0-based natively; convert at boundary |
| Bounds safety | Runtime `Invalid_argument` | `.min(lst.len())` + safe slice |
| Copy to owned | `List.map Fun.id` | `.to_vec()` |
| Empty range | Returns `[]` | Returns `vec![]` |
// Slice List โ 99 Problems #18
// Extract a slice from a list given 1-based inclusive indices [i..k].
// slice ['a','b','c','d','e','f','g','h','i','k'] 3 7
// โ ['c','d','e','f','g']
fn slice<T: Clone>(lst: &[T], i: usize, k: usize) -> Vec<T> {
// Convert 1-based to 0-based, inclusive on both ends
let start = if i == 0 { 0 } else { i - 1 };
let end = k.min(lst.len());
if start >= end {
return vec![];
}
lst[start..end].to_vec()
}
/// Recursive version.
fn slice_rec<T: Clone>(lst: &[T], i: usize, k: usize) -> Vec<T> {
fn aux<T: Clone>(lst: &[T], i: usize, k: usize, pos: usize) -> Vec<T> {
match lst {
[] => vec![],
[head, tail @ ..] => {
if pos > k {
vec![]
} else if pos >= i {
let mut result = vec![head.clone()];
result.extend(aux(tail, i, k, pos + 1));
result
} else {
aux(tail, i, k, pos + 1)
}
}
}
}
aux(lst, i, k, 1)
}
fn main() {
let input = vec!['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
println!("Input: {:?}", input);
println!("Slice [3..7]: {:?}", slice(&input, 3, 7));
println!("Slice [1..3]: {:?}", slice(&input, 1, 3));
println!("Slice [1..1]: {:?}", slice(&input, 1, 1));
println!("Rec [3..7]: {:?}", slice_rec(&input, 3, 7));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_slice_middle() {
let input = vec!['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
assert_eq!(slice(&input, 3, 7), vec!['c', 'd', 'e', 'f', 'g']);
}
#[test]
fn test_slice_from_start() {
let input = vec![1, 2, 3, 4, 5];
assert_eq!(slice(&input, 1, 3), vec![1, 2, 3]);
}
#[test]
fn test_slice_single() {
let input = vec!['a', 'b', 'c'];
assert_eq!(slice(&input, 2, 2), vec!['b']);
}
#[test]
fn test_slice_rec_matches() {
let input = vec!['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'];
assert_eq!(slice(&input, 3, 7), slice_rec(&input, 3, 7));
}
}
(* Slice List *)
(* OCaml 99 Problems #18 *)
(* Implementation for example 18 *)
(* Tests *)
let () =
(* Add tests *)
print_endline "โ OCaml tests passed"