Algorithms#
Most everyday algorithmic work uses iterator combinators on slices, vectors, or other collections.
Sorting#
let mut xs = vec![5, 1, 4, 2, 3];
xs.sort(); // ascending
xs.sort_by(|a, b| b.cmp(a)); // descending
xs.sort_by_key(|&x| x.abs());
Search#
let xs = vec![1, 3, 5, 7, 9];
match xs.binary_search(&5) {
Ok(i) => println!("found at {}", i),
Err(i) => println!("would insert at {}", i),
}
Iterators#
Iterators are lazy. Combinators chain into pipelines that compile to tight loops.
let total: i32 = (1..=100)
.filter(|n| n % 3 == 0)
.map(|n| n * n)
.sum();
Recursion#
fn fact(n: u64) -> u64 {
if n <= 1 { 1 } else { n * fact(n - 1) }
}
Linked List#
A simple owned singly linked list.
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
impl<T> List<T> {
fn push(self, value: T) -> Self {
List::Cons(value, Box::new(self))
}
}
Concurrency#
Spawn an OS thread or use Rayon for data-parallel iterators.
use std::thread;
let handle = thread::spawn(|| heavy_work());
let result = handle.join().unwrap();
use rayon::prelude::*;
let total: i32 = xs.par_iter().sum();