// 095: Double-Ended Iterator
fn is_palindrome(v: &[i32]) -> bool {
v.iter().eq(v.iter().rev())
}
fn take_from_both(v: &[i32]) -> (Vec<i32>, Vec<i32>) {
let mut iter = v.iter();
let front: Vec<i32> = (0..2).filter_map(|_| iter.next().copied()).collect();
let back: Vec<i32> = (0..2).filter_map(|_| iter.next_back().copied()).collect();
(front, back)
}
fn main() {
println!("palindrome [1,2,3,2,1]: {}", is_palindrome(&[1, 2, 3, 2, 1]));
let (f, b) = take_from_both(&[1, 2, 3, 4, 5]);
println!("front: {:?}, back: {:?}", f, b);
// rev() works because slice iterator is DoubleEnded
let reversed: Vec<i32> = [1, 2, 3, 4, 5].iter().rev().copied().collect();
println!("reversed: {:?}", reversed);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_palindrome() {
assert!(is_palindrome(&[1, 2, 3, 2, 1]));
assert!(!is_palindrome(&[1, 2, 3]));
}
#[test]
fn test_take_both() {
let (f, b) = take_from_both(&[1, 2, 3, 4, 5]);
assert_eq!(f, vec![1, 2]);
assert_eq!(b, vec![5, 4]);
}
#[test]
fn test_next_back() {
let v = vec![1, 2, 3];
let mut iter = v.iter();
assert_eq!(iter.next_back(), Some(&3));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
}
}
(* 095: Double-Ended Iteration *)
(* OCaml lists are singly-linked โ no efficient reverse iteration *)
(* We simulate with arrays *)
let iter_both arr =
let n = Array.length arr in
let front = ref 0 in
let back = ref (n - 1) in
let next_front () =
if !front > !back then None
else (let v = arr.(!front) in incr front; Some v)
in
let next_back () =
if !back < !front then None
else (let v = arr.(!back) in decr back; Some v)
in
(next_front, next_back)
let is_palindrome_arr arr =
let n = Array.length arr in
let rec check i = i >= n / 2 || (arr.(i) = arr.(n - 1 - i) && check (i + 1)) in
check 0
(* Tests *)
let () =
let arr = [|1; 2; 3; 4; 5|] in
let (nf, nb) = iter_both arr in
assert (nf () = Some 1);
assert (nb () = Some 5);
assert (nf () = Some 2);
assert (nb () = Some 4);
assert (is_palindrome_arr [|1; 2; 3; 2; 1|]);
assert (not (is_palindrome_arr [|1; 2; 3|]));
Printf.printf "โ All tests passed\n"