021 — Insert an Element at a Given Position
Tutorial Video
Text description (accessibility)
This video demonstrates the "021 — Insert an Element at a Given Position" functional Rust example. Difficulty level: Intermediate. Key concepts covered: Functional Programming. Inserting an element at position k (OCaml 99 Problems #21) is the inverse of removal — splicing a value into the middle of a sequence. Key difference from OCaml: 1. **`Vec::insert` vs list surgery**: Rust's `Vec::insert(k, v)` shifts elements right — O(n). OCaml's list insertion walks to position k and splices — also O(k), same complexity.
Tutorial
The Problem
Inserting an element at position k (OCaml 99 Problems #21) is the inverse of removal — splicing a value into the middle of a sequence. Together with removal, it forms the primitive operations for maintaining ordered sequences, implementing undo/redo buffers, and building persistent data structures.
The problem teaches position-based list manipulation without higher-level abstractions: build the prefix, prepend the new element, then append the suffix. In databases, this is analogous to a B-tree node split. In text editors, every character insertion is a version of this operation.
🎯 Learning Outcomes
Vec::insert(k, value) for O(n) in-place insertionVec without mutating the input (functional style)Vec::insert(k, elem) for O(n) in-place insertion that shifts elements rightCode Example
#![allow(clippy::all)]
// Placeholder — pending conversionKey Differences
Vec::insert vs list surgery**: Rust's Vec::insert(k, v) shifts elements right — O(n). OCaml's list insertion walks to position k and splices — also O(k), same complexity.Vec::insert mutates. Return v.to_vec() then insert for a functional style that does not modify the input.concat with slices**: Rust's [&v[..k], &[elem], &v[k..]].concat() creates a single allocation. OCaml's List.rev_append acc (x :: t) avoids one reverse call per step.Vec::insert shifts:** Rust's v.insert(k, elem) shifts all elements at index k and beyond one position right — O(n). Returns nothing (mutates in place).[&v[..k], &[elem], &v[k..]].concat() creates a new Vec — O(n). OCaml's recursive version also creates a new list — but shares the suffix via cons-cell reuse.len is append. Both are O(n) for Vec but O(1) for linked lists in OCaml.OCaml Approach
OCaml's version: let insert_at x k lst = let rec aux acc n = function | [] -> if n <= 0 then List.rev (x :: acc) else List.rev acc (* out of bounds — append *) | t when n = 0 -> List.rev_append acc (x :: t) | h :: t -> aux (h :: acc) (n - 1) t in aux [] (k - 1) lst. The counter starts at k-1; when it reaches 0, the element is inserted before the current head.
OCaml's insert: let rec insert_at x k = function | [] -> if k = 1 then [x] else [] (* or error *) | h :: t -> if k = 1 then x :: h :: t else h :: insert_at x (k-1) t. This builds a new list — OCaml lists are immutable. The result shares the suffix with the original via structural sharing.
Full Source
#![allow(clippy::all)]
// Placeholder — pending conversionDeep Comparison
OCaml vs Rust: Insert At
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.
Exercises
insert_sorted(v: &mut Vec<i32>, x: i32) that inserts x into a sorted Vec at the correct position to maintain sort order. Use v.binary_search(&x).unwrap_or_else(|e| e) to find the insertion point.insert_many(v: &[i32], insertions: &[(usize, i32)]) -> Vec<i32> that applies multiple insertions in position order. Sort insertions by position first.Vec::insert is O(n) while rope insertion is O(log n).insert_sorted<T: Ord>(v: &mut Vec<T>, elem: T) that inserts elem into an already-sorted Vec at the correct position using binary search (v.binary_search).insert_all(v: &[T], elems: &[(usize, T)]) -> Vec<T> that inserts multiple elements at given positions in one pass, adjusting positions as elements are inserted.