extern crate rand;
extern crate term_painter;

use std::cmp::Ordering;
use std::fmt::{Debug, Display, Formatter, Result};

use rand::distributions::Uniform;
use rand::Rng;
use term_painter::Color::*;
use term_painter::ToStyle;

pub type NodePtr = Option<usize>;

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Side {
    Left,
    Right,
    Up,
    Root,
}

#[derive(Debug, PartialEq, Clone, Copy)]
enum DisplayElement {
    TrunkSpace,
    SpaceLeft,
    SpaceRight,
    SpaceSpace,
    Root,
}

impl DisplayElement {
    fn string(&self) -> String {
        match *self {
            DisplayElement::TrunkSpace => "    │   ".to_string(),
            DisplayElement::SpaceRight => "    ┌───".to_string(),
            DisplayElement::SpaceLeft => "    └───".to_string(),
            DisplayElement::SpaceSpace => "        ".to_string(),
            DisplayElement::Root => "├──".to_string(),
        }
    }
}

/// Handedness of balanced insert and delete operations differs only by values encapsulated here.
struct BalanceConstants {
    bal_incr: i8,
    this_side: Side,
    that_side: Side,
    key_order: Ordering, // Ins only
    // These are used in the +1/-1 & -1/+1 deletion cases
    gcm1_child_adj: i8, // Del only, balance adjustment to child for b = -1 grandchild
    gcm1_parent_adj: i8, // Del only, balance adjustment to parent for b = -1 grandchild
    gcp1_child_adj: i8, // Del only, balance adjustment to child for b = 1 grandchild
    gcp1_parent_adj: i8, // Del only, balance adjustment to parent for b = 1 grandchild
}

const BALANCE_CONSTANTS_A: BalanceConstants = BalanceConstants {
    bal_incr: -1,
    this_side: Side::Left,
    that_side: Side::Right,
    key_order: Ordering::Greater,
    gcm1_child_adj: 0,
    gcm1_parent_adj: 1,
    gcp1_child_adj: -1,
    gcp1_parent_adj: 0,
};

const BALANCE_CONSTANTS_B: BalanceConstants = BalanceConstants {
    bal_incr: 1,
    this_side: Side::Right,
    that_side: Side::Left,
    key_order: Ordering::Less,
    gcm1_child_adj: 1,
    gcm1_parent_adj: 0,
    gcp1_child_adj: 0,
    gcp1_parent_adj: -1,
};

#[derive(Debug, Clone, Copy)]
pub struct Node<K, V> {
    key: K,
    value: V,
    balance: i8,
    left: NodePtr,
    right: NodePtr,
    up: NodePtr,
}

#[derive(Debug)]
pub struct AVLTree<K, V> {
    root: NodePtr,
    store: Vec<Node<K, V>>,
}

impl<K: Ord + Copy + Debug + Display, V: Debug + Copy + Display> Default for AVLTree<K, V> {
    fn default() -> Self {
        AVLTree::new()
    }
}

impl<K: Ord + Copy + Debug + Display, V: Debug + Copy + Display> AVLTree<K, V> {
    pub fn get_node(&self, np: NodePtr) -> Node<K, V> {
        assert!(np.is_some());
        self.store[np.unwrap()]
    }

    pub fn get_balance(&self, np: NodePtr) -> i8 {
        assert!(np.is_some());
        self.store[np.unwrap()].balance
    }

    pub fn get_key(&self, np: NodePtr) -> K {
        assert!(np.is_some());
        self.store[np.unwrap()].key
    }

    pub fn get_value(&self, np: NodePtr) -> V {
        assert!(np.is_some());
        self.store[np.unwrap()].value
    }

    pub fn get_pointer(&self, np: NodePtr, side: Side) -> NodePtr {
        assert!(np.is_some());
        self.store[np.unwrap()].get_ptr(side)
    }

    pub fn set_balance(&mut self, np: NodePtr, bal: i8) {
        assert!(np.is_some());
        self.store[np.unwrap()].balance = bal;
    }

    pub fn set_key(&mut self, np: NodePtr, to: K) {
        assert!(np.is_some());
        self.store[np.unwrap()].key = to;
    }

    pub fn set_value(&mut self, np: NodePtr, to: V) {
        assert!(np.is_some());
        self.store[np.unwrap()].value = to;
    }

    pub fn set_pointer(&mut self, np: NodePtr, side: Side, to: NodePtr) {
        assert!(np.is_some());
        self.store[np.unwrap()].set_ptr(side, to);
    }

    pub fn increment_balance(&mut self, np: NodePtr, delta: i8) -> i8 {
        assert!(np.is_some());
        self.store[np.unwrap()].balance += delta;
        self.store[np.unwrap()].balance
    }

    pub fn new() -> Self {
        AVLTree {
            root: None,
            store: Vec::<Node<K, V>>::with_capacity(20_000),
        }
    }

    /// Insert key-value
    pub fn insert(&mut self, k: K, v: V) -> Option<Node<K, V>> {
        let (n, _) = self.insert_node(Node::new(k, v));
        n
    }

    /// Insert Node struct
    pub fn insert_node(&mut self, mut n: Node<K, V>) -> (Option<Node<K, V>>, Side) {
        if self.root.is_none() {
            assert!(self.store.is_empty());
            self.store.push(n);
            self.root = Some(0);
            return (Some(n), Side::Root);
        }

        let mut p = self.root; // Possibly None
        let mut prev = p;
        let mut side = Side::Left;
        while p.is_some() {
            prev = p;
            match n.key.cmp(&self.get_key(p)) {
                Ordering::Less => {
                    side = Side::Left;
                    p = self.get_pointer(p, side);
                }
                Ordering::Greater => {
                    side = Side::Right;
                    p = self.get_pointer(p, side);
                }
                Ordering::Equal => {
                    println!("Key exists");
                    return (None, side);
                }
            }
        }
        // Set child's pointer
        n.up = prev;
        // Stow the node
        self.store.push(n);
        // Set parent's pointer
        let ptr = Some(self.store.len() - 1);
        self.set_pointer(prev, side, ptr);
        (Some(n), side)
    }

    /// Insert key-value and rebalance
    pub fn insert_bal(&mut self, k: K, v: V) -> Option<Node<K, V>> {
        self.insert_node_bal(Node::new(k, v))
    }

    /// Insert Node struct and rebalance
    pub fn insert_node_bal(&mut self, n: Node<K, V>) -> Option<Node<K, V>> {
        let (nins, side) = self.insert_node(n);
        if nins.is_none() || side == Side::Root {
            return nins;
        }

        let mut p = nins.unwrap().up;
        let mut is_left = side == Side::Left;

        while p.is_some() {
            let i_c = get_insertion_constants(is_left);

            let b = self.increment_balance(p, i_c.bal_incr);
            if b == 0 {
                break; // No further adjustments necessary
            } else if b.abs() > 1 {
                let child_p = self.get_pointer(p, i_c.this_side);
                match self.get_balance(child_p) * b {
                    2 => {
                        // -2/-1 & +2/+1 patterns
                        self.single_rotation(i_c.this_side, p, child_p);
                        self.set_balance(p, 0);
                        self.set_balance(child_p, 0);
                        break;
                    }
                    -2 => {
                        // -2/+1 & +2/-1 patterns
                        let grand_p = self.get_pointer(child_p, i_c.that_side);
                        self.double_rotation(i_c.this_side, p, child_p, grand_p);
                        if self.get_pointer(child_p, i_c.this_side).is_none() {
                            // Degenerate case, no subtrees
                            self.set_balance(child_p, 0);
                            self.set_balance(p, 0);
                        } else if n.key.cmp(&self.get_key(grand_p)) == i_c.key_order {
                            self.set_balance(child_p, i_c.bal_incr);
                            self.set_balance(p, 0);
                        } else {
                            self.set_balance(child_p, 0);
                            self.set_balance(p, -i_c.bal_incr);
                        }
                        self.set_balance(grand_p, 0);
                        break;
                    }
                    _ => unreachable!(),
                }
            }

            let child_p = p;
            p = self.get_pointer(p, Side::Up);
            if p.is_some() {
                let left_p = self.get_pointer(p, Side::Left);
                is_left = left_p.is_some() && left_p == child_p;
            }
        }

        nins
    }

    /// Remove the node at index from the store and patch the hole in the vector,
    /// modifying pointers in the moved node's parents and children.
    fn remove_carefully(&mut self, p: NodePtr) {
        assert!(p.is_some());
        let index = p.unwrap();
        let old_index = self.store.len() - 1;
        self.store.swap_remove(index);

        if index == old_index {
            // Nothing moved
            return;
        }

        // Element -1 has moved into the spot _index_. The in-pointers that need modifying
        // belong to that element's parent and children.

        // Fix child pointer in parent:
        let parent_p = self.get_pointer(p, Side::Up);
        if parent_p.is_some() {
            let l = self.get_pointer(parent_p, Side::Left);
            if l == Some(old_index) {
                self.set_pointer(parent_p, Side::Left, Some(index));
            } else {
                self.set_pointer(parent_p, Side::Right, Some(index));
            }
        }

        // Fix parent pointers in children:
        let l = self.get_pointer(p, Side::Left);
        let r = self.get_pointer(p, Side::Right);
        if l.is_some() {
            self.set_pointer(l, Side::Up, Some(index));
        }
        if r.is_some() {
            self.set_pointer(r, Side::Up, Some(index));
        }

        // Fix root if necessary
        if self.root == Some(old_index) {
            self.root = Some(index);
        }
    }

    /// Uses delete-by-copy procedure if node with key k has two children.
    /// Returns (parent, side) tuple.
    pub fn delete(&mut self, k: K) -> (NodePtr, Side) {
        let mut p = self.root;
        let mut prev = None;
        let mut res = None;
        let mut side = Side::Root;
        while p.is_some() {
            match k.cmp(&self.get_key(p)) {
                Ordering::Equal => {
                    break;
                }
                Ordering::Less => {
                    prev = p;
                    side = Side::Left;
                    p = self.get_pointer(p, side);
                }
                Ordering::Greater => {
                    prev = p;
                    side = Side::Right;
                    p = self.get_pointer(p, side);
                }
            }
        }

        if p.is_none() {
            println!("Key {:?} not found", k);
            return (res, side);
        }

        let n = self.get_node(p);
        // Is this a leaf?
        if n.is_leaf() {
            if n.key.cmp(&self.get_key(self.root)) == Ordering::Equal {
                self.root = None;
                assert_eq!(self.store.len(), 1);
            } else {
                self.set_pointer(prev, side, None);
            }
            self.remove_carefully(p);
            // The prev pointer is now stale
            res = if prev == Some(self.store.len()) {
                p
            } else {
                prev
            };

        // Is this a one-child node?
        } else if n.left.is_none() || n.right.is_none() {
            let ch = if n.left.is_some() { n.left } else { n.right };
            if n.key.cmp(&self.get_key(self.root)) == Ordering::Equal {
                self.set_pointer(ch, Side::Up, None);
                self.root = ch;
            } else {
                self.set_pointer(prev, side, ch);
                self.set_pointer(ch, Side::Up, prev);
            }
            self.remove_carefully(p);
            // The prev pointer is now stale
            res = if prev == Some(self.store.len()) {
                p
            } else {
                prev
            };

        // Complicated case:  two children, do delete-by-copy. Replace n with its first
        // predecessor (the mirror image using the first successor would work as well).
        } else {
            let mut tmp = n.left;
            let mut last = tmp;
            prev = self.get_pointer(tmp, Side::Up);
            while tmp.is_some() && self.get_pointer(last, Side::Right).is_some() {
                prev = self.get_pointer(tmp, Side::Up);
                last = tmp;
                tmp = self.get_pointer(tmp, Side::Right);
            }
            tmp = last;
            // Copy ...
            let the_key = self.get_key(tmp);
            let the_value = self.get_value(tmp);
            self.set_key(p, the_key);
            self.set_value(p, the_value);

            let left_ptr = self.get_pointer(tmp, Side::Left);
            if prev == p {
                self.set_pointer(p, Side::Left, left_ptr);
                if left_ptr.is_some() {
                    self.set_pointer(left_ptr, Side::Up, p);
                }
                side = Side::Left;
            } else {
                self.set_pointer(prev, Side::Right, left_ptr);
                if left_ptr.is_some() {
                    self.set_pointer(left_ptr, Side::Up, prev);
                }
                side = Side::Right;
            }

            self.remove_carefully(tmp);
            // The prev pointer is now stale
            res = if prev.unwrap() == self.store.len() {
                tmp
            } else {
                prev
            };
        }

        (res, side)
    }

    /// Rebalance on delete
    pub fn delete_bal(&mut self, k: K) -> Option<Node<K, V>> {
        // slug: (pointer to parent of deleted node, side of deleted node)
        let slug = self.delete(k);
        let (pdel, side) = slug;
        if pdel.is_none() {
            return None;
        };
        let ndel = self.get_node(pdel);

        let mut p = pdel;
        let mut is_left = side == Side::Left;

        // Rebalance and update balance factors. There are two different rotation sequences that
        // are the same within handedness,
        // and the +1/-1 / -1/+1 sequence has three possible balance adjustments
        // depending on the grandchild.
        while p.is_some() {
            let d_c = get_deletion_constants(is_left);

            let b = self.increment_balance(p, d_c.bal_incr);
            if b.abs() == 1 {
                break; // No further adjustments necessary
            } else if b.abs() > 1 {
                let child_p = self.get_pointer(p, d_c.this_side);
                match self.get_balance(child_p) * b {
                    2 => {
                        // +1/+1 & -1/-1 patterns
                        self.single_rotation(d_c.this_side, p, child_p);
                        self.set_balance(p, 0);
                        p = self.get_pointer(p, Side::Up);
                        self.set_balance(p, 0);
                    }
                    0 => {
                        // +1/0 & -1/0 patterns
                        self.single_rotation(d_c.this_side, p, child_p);
                        self.set_balance(p, d_c.bal_incr);
                        p = self.get_pointer(p, Side::Up);
                        self.set_balance(p, -d_c.bal_incr);
                        break; // No height change
                    }
                    -2 => {
                        // +1/-1/x & -1/+1/x patterns
                        let grand_p = self.get_pointer(child_p, d_c.that_side);
                        self.double_rotation(d_c.this_side, p, child_p, grand_p);
                        // p is now one child, grand_p is the other, child_p is their parent
                        match self.get_balance(grand_p) {
                            -1 => {
                                self.set_balance(p, d_c.gcm1_parent_adj);
                                self.set_balance(child_p, d_c.gcm1_child_adj);
                            }
                            0 => {
                                self.set_balance(p, 0);
                                self.set_balance(child_p, 0);
                            }
                            1 => {
                                self.set_balance(p, d_c.gcp1_parent_adj);
                                self.set_balance(child_p, d_c.gcp1_child_adj);
                            }
                            _ => unreachable!(),
                        }
                        self.set_balance(grand_p, 0);
                        p = self.get_pointer(p, Side::Up);
                    }
                    _ => unreachable!(),
                }
            }

            let child_p = p;
            p = self.get_pointer(p, Side::Up);
            if p.is_some() {
                let left_p = self.get_pointer(p, Side::Left);
                is_left = left_p.is_some() && left_p == child_p;
            }
        }

        Some(ndel)
    }

    /// Returns node value
    pub fn lookup(&self, k: K) -> Option<V> {
        self.search(k).map(|n| n.value)
    }

    /// Returns node (not pointer)
    pub fn search(&self, k: K) -> Option<Node<K, V>> {
        let mut p = self.root;
        let mut res = None;

        while p.is_some() {
            match k.cmp(&self.get_key(p)) {
                Ordering::Less => {
                    p = self.get_pointer(p, Side::Left);
                }
                Ordering::Greater => {
                    p = self.get_pointer(p, Side::Right);
                }
                Ordering::Equal => {
                    res = Some(self.get_node(p));
                    break;
                }
            }
        }
        res
    }

    /// Do an in-order traversal, where a "visit" prints the row with that node in it.
    fn display(&self, p: NodePtr, side: Side, e: &[DisplayElement], f: &mut Formatter) {
        if p.is_none() {
            return;
        }

        let mut elems = e.to_vec();
        let node = self.get_node(p);
        let mut tail = DisplayElement::SpaceSpace;
        if node.up != self.root {
            // Direction switching, need trunk element to be printed for lines before that node
            // is visited.
            let new_elem = if side == Side::Left && node.right.is_some() {
                DisplayElement::TrunkSpace
            } else {
                DisplayElement::SpaceSpace
            };
            elems.push(new_elem);
        }
        let hindex = elems.len() - 1;
        self.display(node.right, Side::Right, &elems, f);

        if p == self.root {
            elems[hindex] = DisplayElement::Root;
            tail = DisplayElement::TrunkSpace;
        } else if side == Side::Right {
            // Right subtree finished
            elems[hindex] = DisplayElement::SpaceRight;
            // Prepare trunk element in case there is a left subtree
            tail = DisplayElement::TrunkSpace;
        } else
        // if side == Side::Left
        {
            elems[hindex] = DisplayElement::SpaceLeft;
            let parent_p = self.get_pointer(p, Side::Up);
            let gp_p = self.get_pointer(parent_p, Side::Up);
            if gp_p.is_some() && self.get_pointer(gp_p, Side::Right) == parent_p {
                // Direction switched, need trunk element starting with this node/line
                elems[hindex - 1] = DisplayElement::TrunkSpace;
            }
        }

        // Visit node => print accumulated elements. Each node gets a line.
        {
            for e in elems.clone() {
                let _ = write!(f, "{}", e.string());
            }
            let _ = write!(
                f,
                "{key:>width$} ",
                key = Green.bold().paint(node.key),
                width = 2
            );
            let _ = write!(
                f,
                "{value:>width$} ",
                value = Blue.bold().paint(format!("{:.*}", 2, node.value)),
                width = 4
            );
            let _ = write!(
                f,
                "{bal:<-width$}
",
                bal = Red.bold().paint(node.balance),
                width = 2
            );

            elems[hindex] = tail;
        }

        self.display(node.left, Side::Left, &elems, f);
    }

    pub fn gather_balances(&self) -> (Vec<K>, Vec<i8>) {
        let mut keys = Vec::<K>::new();
        let mut bals = Vec::<i8>::new();

        self.gather_balances_impl(self.root, &mut keys, &mut bals);
        (keys, bals)
    }

    fn gather_balances_impl(&self, p: NodePtr, k: &mut Vec<K>, b: &mut Vec<i8>) {
        if p.is_none() {
            return;
        }
        let r = self.get_pointer(p, Side::Right);
        self.gather_balances_impl(r, k, b);
        k.push(self.get_key(p));
        b.push(self.get_balance(p));
        let l = self.get_pointer(p, Side::Left);
        self.gather_balances_impl(l, k, b)
    }

    pub fn compute_balances(&mut self, p: NodePtr) -> i8 {
        self.compute_balances_impl(p, 0)
    }

    fn compute_balances_impl(&mut self, p: NodePtr, level: i8) -> i8 {
        if p.is_none() {
            return level - 1;
        }
        let r = self.get_pointer(p, Side::Right);
        let l = self.get_pointer(p, Side::Left);
        let rb = self.compute_balances_impl(r, level + 1);
        let lb = self.compute_balances_impl(l, level + 1);
        self.set_balance(p, rb - lb);
        std::cmp::max(rb, lb)
    }

    ///     P                Q
    ///   /   \     =>     /       ///  h     Q          P     h'
    fn rotate_left(&mut self, p: NodePtr, q: NodePtr) {
        assert!(p.is_some());
        assert!(q.is_some());
        let p_parent = self.get_pointer(p, Side::Up);
        // Take care of parent pointers
        self.set_pointer(q, Side::Up, p_parent);
        self.set_pointer(p, Side::Up, q);
        let ql = self.get_pointer(q, Side::Left);
        if ql.is_some() {
            self.set_pointer(ql, Side::Up, p);
        }

        // Take care of child pointers
        self.set_pointer(q, Side::Left, p);
        self.set_pointer(p, Side::Right, ql);
        if p_parent.is_some() {
            let side = if self.get_pointer(p_parent, Side::Right) == p {
                Side::Right
            } else {
                Side::Left
            };
            self.set_pointer(p_parent, side, q);
        } else {
            self.root = q;
        }
    }

    ///     P                Q
    ///   /   \     =>     /       ///  Q     h          h'    P
    fn rotate_right(&mut self, p: NodePtr, q: NodePtr) {
        assert!(p.is_some());
        assert!(q.is_some());
        let p_parent = self.get_pointer(p, Side::Up);
        // Take care of parent pointers
        self.set_pointer(q, Side::Up, p_parent);
        self.set_pointer(p, Side::Up, q);
        let qr = self.get_pointer(q, Side::Right);
        if qr.is_some() {
            self.set_pointer(qr, Side::Up, p);
        }

        // Take care of child pointers
        self.set_pointer(q, Side::Right, p);
        self.set_pointer(p, Side::Left, qr);
        if p_parent.is_some() {
            let side = if self.get_pointer(p_parent, Side::Right) == p {
                Side::Right
            } else {
                Side::Left
            };
            self.set_pointer(p_parent, side, q);
        } else {
            self.root = q;
        }
    }

    fn single_rotation(&mut self, side: Side, p: NodePtr, q: NodePtr) {
        if side == Side::Left {
            self.rotate_right(p, q);
        } else {
            self.rotate_left(p, q);
        }
    }

    fn double_rotation(&mut self, side: Side, p: NodePtr, child_p: NodePtr, grand_p: NodePtr) {
        if side == Side::Left {
            self.rotate_left(child_p, grand_p);
            self.rotate_right(p, grand_p);
        } else {
            self.rotate_right(child_p, grand_p);
            self.rotate_left(p, grand_p);
        }
    }
}

impl<K: Ord + Copy, V: Copy> Node<K, V> {
    pub fn new(k: K, v: V) -> Node<K, V> {
        Node {
            key: k,
            value: v,
            balance: 0,
            left: None,
            right: None,
            up: None,
        }
    }

    pub fn is_leaf(&self) -> bool {
        self.left.is_none() && self.right.is_none()
    }

    pub fn set_ptr(&mut self, side: Side, to: NodePtr) {
        let field = match side {
            Side::Up => &mut self.up,
            Side::Left => &mut self.left,
            _ => &mut self.right,
        };
        *field = to;
    }

    pub fn get_ptr(&self, side: Side) -> NodePtr {
        match side {
            Side::Up => self.up,
            Side::Left => self.left,
            _ => self.right,
        }
    }
}

impl<K: Ord + Copy + Debug + Display, V: Debug + Copy + Display> Display for AVLTree<K, V> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        if self.root.is_none() {
            write!(f, "[empty]")
        } else {
            let v: Vec<DisplayElement> = Vec::new();
            self.display(self.root, Side::Up, &v, f);
            Ok(())
        }
    }
}

fn get_insertion_constants(is_left: bool) -> &'static BalanceConstants {
    if is_left {
        &BALANCE_CONSTANTS_A
    } else {
        &BALANCE_CONSTANTS_B
    }
}

fn get_deletion_constants(is_left: bool) -> &'static BalanceConstants {
    get_insertion_constants(!is_left)
}

pub fn random_bal_tree(n: u32) -> AVLTree<i32, f32> {
    let mut tree: AVLTree<i32, f32> = AVLTree::new();
    let mut rng = rand::thread_rng();
    // `Uniform` rather than `gen_range`'s `Uniform::sample_single` for speed
    let key_range = Uniform::new(-(n as i32) / 2, (n as i32) / 2);
    let value_range = Uniform::new(-1.0, 1.0);
    tree.insert_bal(0, rng.sample(value_range));
    for _ in 0..n {
        tree.insert_bal(rng.sample(key_range), rng.sample(value_range));
    }
    tree
}

#[cfg(test)]
mod tests {
    use rand::{seq, thread_rng};

    use super::AVLTree;
    use random_bal_tree;

    #[test]
    fn test_insert() {
        let mut tree: AVLTree<i32, f32> = AVLTree::new();
        tree.insert(0, 0.0);
        tree.insert(8, 8.8);
        tree.insert(-8, -8.8);
        assert!(tree.insert(4, 4.4).is_some());
        tree.insert(12, 12.12);

        assert_eq!(tree.lookup(4), Some(4.4));
        assert_eq!(tree.lookup(5), None);
        assert_eq!(tree.lookup(-8), Some(-8.8));

        let s = &tree.store;
        assert_eq!(
            s[s[s[tree.root.unwrap()].right.unwrap()].right.unwrap()].value,
            12.12
        );
        assert_eq!(
            s[s[s[tree.root.unwrap()].right.unwrap()].right.unwrap()].left,
            None
        );
    }

    #[test]
    fn test_delete() {
        let mut tree: AVLTree<i32, f32> = AVLTree::new();
        tree.insert(0, 0.0);
        tree.insert(8, 8.8);
        tree.insert(-8, -8.8);
        assert!(tree.insert(4, 4.4).is_some());
        tree.insert(12, 12.12);

        // delete leaf
        tree.delete(12);
        assert_eq!(tree.lookup(12), None);
        let mut n = tree.search(8).unwrap();
        assert_eq!(n.right, None);

        // delete one-child node
        tree.delete(4);
        assert_eq!(tree.lookup(4), None);
        n = tree.search(0).unwrap();
        assert_eq!(tree.store[n.right.unwrap()].key, 8);

        // delete two-child node
        tree.insert(6, 6.6);
        tree.insert(10, 10.10);
        tree.insert(7, 7.7);
        tree.delete(8);
        n = tree.search(7).unwrap();
        assert_eq!(tree.store[n.left.unwrap()].key, 6);
        assert_eq!(tree.store[n.right.unwrap()].key, 10);
        assert_eq!(tree.store[n.up.unwrap()].key, 0);

        // delete two-child root
        tree.delete(0);
        assert_eq!(tree.store[tree.root.unwrap()].key, -8);

        // delete one-child root
        tree.delete(-8);
        assert_eq!(tree.store[tree.root.unwrap()].key, 7);

        // delete no-child root
        tree.delete(6);
        tree.delete(7);
        tree.delete(10);
        assert!(tree.root.is_none());
        assert_eq!(tree.store.len(), 0);
    }

    #[test]
    fn test_rotate_left() {
        let mut tree: AVLTree<i32, f32> = AVLTree::new();
        tree.insert(0, 0.0);
        tree.insert(8, 8.8);
        tree.insert(4, 4.4);
        tree.insert(-8, -8.8);

        let mut r = tree.root;
        let mut right = tree.store[r.unwrap()].right;
        tree.rotate_left(r, right);
        r = tree.root;
        right = tree.store[r.unwrap()].right;
        let left = tree.store[r.unwrap()].left;
        let left_left = tree.store[left.unwrap()].left;
        let left_right = tree.store[left.unwrap()].right;
        assert_eq!(right, None);
        assert_eq!(tree.store[left.unwrap()].key, 0);
        assert_eq!(tree.store[left_left.unwrap()].key, -8);
        assert_eq!(tree.store[left_right.unwrap()].key, 4);
        assert_eq!(tree.store[r.unwrap()].key, 8);
    }

    #[test]
    fn test_rotate_right() {
        let mut tree: AVLTree<i32, f32> = AVLTree::new();
        tree.insert(0, 0.0);
        tree.insert(8, 8.8);
        tree.insert(-8, -8.8);
        tree.insert(-4, 4.4);

        let mut r = tree.root;
        let mut left = tree.store[r.unwrap()].left;
        tree.rotate_right(r, left);
        r = tree.root;
        left = tree.store[r.unwrap()].left;
        let right = tree.store[r.unwrap()].right;
        let right_right = tree.store[right.unwrap()].right;
        let right_left = tree.store[right.unwrap()].left;
        assert_eq!(left, None);
        assert_eq!(tree.store[right.unwrap()].key, 0);
        assert_eq!(tree.store[right_right.unwrap()].key, 8);
        assert_eq!(tree.store[right_left.unwrap()].key, -4);
        assert_eq!(tree.store[r.unwrap()].key, -8);
    }

    #[test]
    // This tree tests all four insertion types
    fn test_balanced_inserts() {
        let mut tree: AVLTree<i32, f32> = AVLTree::new();
        tree.insert_bal(0, 0.0);
        tree.insert_bal(8, 8.8);
        tree.insert_bal(-8, -8.8);
        tree.insert_bal(12, 12.12);
        tree.insert_bal(16, 16.16);
        tree.insert_bal(11, 11.11);
        tree.insert_bal(4, 4.4);
        tree.insert_bal(-10, -8.8);
        tree.insert_bal(-12, -8.8);
        tree.insert_bal(-9, -8.8);

        let mut res = tree.gather_balances();
        let (_, bals) = res;
        assert!(bals.iter().max().unwrap() < &2);
        assert!(bals.iter().min().unwrap() > &-2);

        for _ in 0..10 {
            tree = random_bal_tree(1000);
            res = tree.gather_balances();
            let (_, bals) = res;
            assert!(bals.iter().max().unwrap() < &2);
            assert!(bals.iter().min().unwrap() > &-2);
        }
    }

    #[test]
    /// This sequence hits all five rotation possibilities on each side.
    fn test_balanced_deletes() {
        let mut tree: AVLTree<i32, f32> = AVLTree::new();
        tree.insert_bal(0, 0.0);
        tree.insert_bal(-32, 0.0);
        tree.insert_bal(32, 0.0);
        tree.insert_bal(-64, 0.0);
        tree.insert_bal(64, 0.0);
        tree.delete_bal(64);
        tree.delete_bal(32);
        tree.delete_bal(-32);
        tree.delete_bal(-64);
        tree.delete_bal(0);
        assert_eq!(tree.root, None);
        assert_eq!(tree.store.len(), 0);

        tree.insert_bal(0, 0.0);
        tree.insert_bal(-32, 0.0);
        tree.insert_bal(32, 0.0);
        tree.insert_bal(-64, 0.0);
        tree.insert_bal(64, 0.0);
        tree.insert_bal(-16, 0.0);
        tree.insert_bal(16, 0.0);
        tree.insert_bal(-8, 0.0);
        tree.insert_bal(8, 0.0);
        tree.insert_bal(-12, 0.0);
        tree.insert_bal(-7, 0.0);
        tree.insert_bal(-6, 0.0);
        tree.insert_bal(-11, 0.0);

        tree.delete_bal(-64);
        tree.delete_bal(-32);
        tree.delete_bal(-7);
        tree.delete_bal(-6);
        tree.delete_bal(-16);
        tree.delete_bal(-11);
        tree.delete_bal(-12);
        tree.delete_bal(8);
        tree.delete_bal(-8);
        tree.delete_bal(0);
        tree.insert_bal(24, 0.0);
        tree.insert_bal(8, 0.0);
        tree.insert_bal(4, 0.0);
        tree.insert_bal(128, 0.0);
        tree.insert_bal(48, 0.0);
        tree.delete_bal(32);
        tree.delete_bal(48);

        tree.insert_bal(-24, 0.0);
        tree.insert_bal(-8, 0.0);
        tree.insert_bal(-128, 0.0);
        tree.insert_bal(-48, 0.0);
        tree.insert_bal(-20, 0.0);
        tree.insert_bal(-30, 0.0);
        tree.insert_bal(-22, 0.0);
        tree.insert_bal(-21, 0.0);
        tree.delete_bal(24);
        tree.delete_bal(64);
        tree.delete_bal(-30);
        tree.delete_bal(-22);
        tree.delete_bal(-21);
        tree.delete_bal(-128);
        tree.delete_bal(128);
        tree.delete_bal(-8);
        tree.insert_bal(-96, 0.0);
        tree.insert_bal(-95, 0.0);
        tree.insert_bal(-10, 0.0);
        tree.insert_bal(6, 0.0);
        tree.delete_bal(-24);

        let mut res = tree.gather_balances();
        let (_, bals) = res;
        assert!(bals.iter().max().unwrap() < &2);
        assert!(bals.iter().min().unwrap() > &-2);

        let mut p = tree.root;
        while p.is_some() {
            let key = tree.store[p.unwrap()].key;
            tree.delete_bal(key);
            p = tree.root;
        }
        assert_eq!(tree.root, None);
        assert_eq!(tree.store.len(), 0);

        // */*/+1 patterns
        tree.insert(6, 0.0);
        tree.insert(-1, 0.0);
        tree.insert(9, 0.0);
        tree.insert(7, 0.0);
        tree.insert(3, 0.0);
        tree.insert(-9, 0.0);
        tree.insert(4, 0.0);
        p = tree.root;
        tree.compute_balances(p);
        tree.delete_bal(-9);
        res = tree.gather_balances();
        let (_, bals) = res;
        tree.compute_balances(p);
        res = tree.gather_balances();
        let (_, bals_after) = res;
        assert_eq!(bals, bals_after);

        tree.insert(6, 0.0);
        tree.insert(-1, 0.0);
        tree.insert(3, 0.0);
        tree.insert(9, 0.0);
        tree.insert(7, 0.0);
        tree.insert(11, 0.0);
        tree.insert(8, 0.0);
        p = tree.root;
        tree.compute_balances(p);
        tree.delete_bal(-1);
        res = tree.gather_balances();
        let (_, bals) = res;
        tree.compute_balances(p);
        res = tree.gather_balances();
        let (_, bals_after) = res;
        assert_eq!(bals, bals_after);

        let mut rng = thread_rng();
        for _ in 0..100 {
            tree = random_bal_tree(100);
            let sample = seq::sample_iter(&mut rng, -50..50, 80).unwrap();
            for i in sample {
                tree.delete_bal(i);
            }
        }

        res = tree.gather_balances();
        let (_, bals) = res;

        if bals.len() > 0 {
            assert!(*bals.iter().max().unwrap() < 2);
            assert!(*bals.iter().min().unwrap() > -2);
        }

        return;
    }
}

Implement an AVL tree, a self-balancing binary search tree, in a chosen programming language. The AVL tree ensures the heights of two child subtrees of any node differ by at most one. It supports operations such as lookup, insertion, and deletion, all of which take O(log n) time. The tree may require rebalancing through tree rotations after insertions and deletions. Duplicate node keys are not allowed. The code also compares the performance of AVL trees with red-black trees.


use std::fmt;

#[derive(Clone,Copy)]
struct Point {
    x: f64,
    y: f64
}

fn distance (p1: Point, p2: Point) -> f64 {
    ((p1.x - p2.x).powi(2) + (p1.y - p2.y).powi(2)).sqrt()
}

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({:.4}, {:.4})", self.x, self.y)
    }
}

fn describe_circle(p1: Point, p2: Point, r: f64) {
    let sep = distance(p1, p2);

    if sep == 0. {
        if r == 0. {
            println!("No circles can be drawn through {}", p1);
        } else {
            println!("Infinitely many circles can be drawn through {}", p1);
        }
    } else if sep == 2.0 * r {
        println!("Given points are opposite ends of a diameter of the circle with center ({:.4},{:.4}) and r {:.4}",
                (p1.x+p2.x) / 2.0, (p1.y+p2.y) / 2.0, r);
    } else if sep > 2.0 * r {
        println!("Given points are farther away from each other than a diameter of a circle with r {:.4}", r);
    } else {
        let mirror_dist = (r.powi(2) - (sep / 2.0).powi(2)).sqrt();

        println!("Two circles are possible.");
        println!("Circle C1 with center ({:.4}, {:.4}), r {:.4} and Circle C2 with center ({:.4}, {:.4}), r {:.4}",
                ((p1.x + p2.x) / 2.0) + mirror_dist * (p1.y-p2.y)/sep, (p1.y+p2.y) / 2.0 + mirror_dist*(p2.x-p1.x)/sep,
                r,
                (p1.x+p2.x) / 2.0 - mirror_dist*(p1.y-p2.y)/sep, (p1.y+p2.y) / 2.0 - mirror_dist*(p2.x-p1.x)/sep, r);
    }
}

fn main() {
    let points: Vec<(Point, Point)> = vec![
        (Point { x: 0.1234, y: 0.9876 }, Point { x: 0.8765, y: 0.2345 }),
        (Point { x: 0.0000, y: 2.0000 }, Point { x: 0.0000, y: 0.0000 }),
        (Point { x: 0.1234, y: 0.9876 }, Point { x: 0.1234, y: 0.9876 }),
        (Point { x: 0.1234, y: 0.9876 }, Point { x: 0.8765, y: 0.2345 }),
        (Point { x: 0.1234, y: 0.9876 }, Point { x: 0.1234, y: 0.9876 })
    ];
    let radii: Vec<f64> = vec![2.0, 1.0, 2.0, 0.5, 0.0];

    for (p, r) in points.into_iter().zip(radii.into_iter()) {
        println!("\nPoints: ({}, {}), Radius: {:.4}", p.0, p.1, r);
        describe_circle(p.0, p.1, r);
    }
}

"Function to calculate two possible circles given two points and a radius in 2D space. The function handles special cases such as when radius is zero, points are coincident, points form a diameter, or points are too distant. The function returns the circles or a special indication when two equal or distinct circles cannot be returned."


Implement the main step of the GOST 28147-89 symmetric encryption algorithm, which involves taking a 64-bit block of text and one of the eight 32-bit encryption key elements, using a replacement table, and returning an encrypted block.


Library: rand
// cargo-deps: rand

extern crate rand;
use rand::{thread_rng, Rng};

fn main() {
    let mut rng = thread_rng();
    loop {
        let num = rng.gen_range(0, 20);
        if num == 10 {
            println!("{}", num);
            break;
        }
        println!("{}", rng.gen_range(0, 20));
    }
}

generate and print random numbers from 0 to 19. If the generated number is 10, the loop stops. If the number is not 10, a second random number is generated and printed before the loop restarts. If 10 is never generated, the loop runs indefinitely.


fn bit_count(mut n: usize) -> usize {
    let mut count = 0;
    while n > 0 {
        n >>= 1;
        count += 1;
    }
    count
}

fn mod_pow(p: usize, n: usize) -> usize {
    let mut square = 1;
    let mut bits = bit_count(p);
    while bits > 0 {
        square = square * square;
        bits -= 1;
        if (p & (1 << bits)) != 0 {
            square <<= 1;
        }
        square %= n;
    }
    return square;
}

fn is_prime(n: usize) -> bool {
    if n < 2 {
        return false;
    }
    if n % 2 == 0 {
        return n == 2;
    }
    if n % 3 == 0 {
        return n == 3;
    }
    let mut p = 5;
    while p * p <= n {
        if n % p == 0 {
            return false;
        }
        p += 2;
        if n % p == 0 {
            return false;
        }
        p += 4;
    }
    true
}

fn find_mersenne_factor(p: usize) -> usize {
    let mut k = 0;
    loop {
        k += 1;
        let q = 2 * k * p + 1;
        if q % 8 == 1 || q % 8 == 7 {
            if mod_pow(p, q) == 1 && is_prime(p) {
                return q;
            }
        }
    }
}

fn main() {
    println!("{}", find_mersenne_factor(929));
}

implement a method to find a factor of a Mersenne number (in this case, M929). The method uses efficient algorithms to determine if a number divides 2P-1, including a self-implemented modPow operation. It also incorporates properties of Mersenne numbers to refine the process, such as the form of any factor q of 2P-1 and the conditions that q must meet. The method stops when 2kP+1 > sqrt(N). It only works on Mersenne numbers where P is prime.


use std::collections::HashSet;

fn main() {
  let a = vec![1, 3, 4].into_iter().collect::<HashSet<i32>>();
  let b = vec![3, 5, 6].into_iter().collect::<HashSet<i32>>();

  println!("Set A: {:?}", a.iter().collect::<Vec<_>>());
  println!("Set B: {:?}", b.iter().collect::<Vec<_>>());
  println!("Does A contain 4? {}", a.contains(&4));
  println!("Union: {:?}", a.union(&b).collect::<Vec<_>>());
  println!("Intersection: {:?}", a.intersection(&b).collect::<Vec<_>>());
  println!("Difference: {:?}", a.difference(&b).collect::<Vec<_>>());
  println!("Is A a subset of B? {}", a.is_subset(&b));
  println!("Is A equal to B? {}", a == b);
}

demonstrate various set operations such as creation, checking if an element is present in a set, union, intersection, difference, subset and equality of sets. The code also optionally shows other set operations and methods to modify a mutable set. It may implement a set using an associative array, binary search tree, hash table, or an ordered array of binary bits. The code also discusses the time complexity of the basic test operation in different scenarios.


"Determines the years between 2008 and 2121 in which Christmas falls on a Sunday using standard date handling libraries, and checks for any discrepancies in date handling across different programming languages."


use std::collections::HashSet;
use std::hash::Hash;

fn remove_duplicate_elements_hashing<T: Hash + Eq>(elements: &mut Vec<T>) {
    let set: HashSet<_> = elements.drain(..).collect();
    elements.extend(set.into_iter());
}

fn remove_duplicate_elements_sorting<T: Ord>(elements: &mut Vec<T>) {
    elements.sort_unstable(); // order does not matter
    elements.dedup();
}

fn main() {
    let mut sample_elements = vec![0, 0, 1, 1, 2, 3, 2];
    println!("Before removal of duplicates : {:?}", sample_elements);
    remove_duplicate_elements_sorting(&mut sample_elements);
    println!("After removal of duplicates : {:?}", sample_elements);
}

implement three methods to remove duplicate elements from an array: 1) Using a hash table, 2) Sorting the array and removing consecutive duplicates, and 3) Iterating through the list and discarding any repeated elements.


fn main() {
    println!("Sort numbers in descending order");
    let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", numbers);

    quick_sort(&mut numbers, &|x,y| x > y);
    println!("After:  {:?}\n", numbers);

    println!("Sort strings alphabetically");
    let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"];
    println!("Before: {:?}", strings);

    quick_sort(&mut strings, &|x,y| x < y);
    println!("After:  {:?}\n", strings);

    println!("Sort strings by length");
    println!("Before: {:?}", strings);

    quick_sort(&mut strings, &|x,y| x.len() < y.len());
    println!("After:  {:?}", strings);
}

fn quick_sort<T,F>(v: &mut [T], f: &F)
    where F: Fn(&T,&T) -> bool
{
    let len = v.len();
    if len >= 2 {
        let pivot_index = partition(v, f);
        quick_sort(&mut v[0..pivot_index], f);
        quick_sort(&mut v[pivot_index + 1..len], f);
    }
}

fn partition<T,F>(v: &mut [T], f: &F) -> usize
    where F: Fn(&T,&T) -> bool
{
    let len = v.len();
    let pivot_index = len / 2;
    let last_index = len - 1;

    v.swap(pivot_index, last_index);

    let mut store_index = 0;
    for i in 0..last_index {
        if f(&v[i], &v[last_index]) {
            v.swap(i, store_index);
            store_index += 1;
        }
    }

    v.swap(store_index, len - 1);
    store_index
}

implement the Quicksort algorithm for sorting an array or list. The algorithm selects a pivot element and divides the rest of the elements into two partitions - one with elements less than the pivot and the other with elements greater than the pivot. It then recursively sorts these partitions and combines them with the pivot to produce a sorted array. The code also includes an optimized version of Quicksort that performs the sorting in place to avoid additional memory allocation. The pivot selection method is not specified and can vary. The code also includes a functional style implementation of the algorithm.


fn main() {
    let now = chrono::Utc::now();
    println!("{}", now.format("%Y-%m-%d"));
    println!("{}", now.format("%A, %B %d, %Y"));
}

display the current date in the formats "2007-11-23" and "Friday, November 23, 2007" using chrono 0.4.6.


use std::collections::BTreeSet;

fn powerset<T: Ord + Clone>(mut set: BTreeSet<T>) -> BTreeSet<BTreeSet<T>> {
    if set.is_empty() {
        let mut powerset = BTreeSet::new();
        powerset.insert(set);
        return powerset;
    }
    // Access the first value. This could be replaced with `set.pop_first().unwrap()`
    // But this is an unstable feature
    let entry = set.iter().nth(0).unwrap().clone();
    set.remove(&entry);
    let mut powerset = powerset(set);
    for mut set in powerset.clone().into_iter() {
        set.insert(entry.clone());
        powerset.insert(set);
    }
    powerset
}

fn main() {
    let set = (1..5).collect();
    let set = powerset(set);
    println!("{:?}", set);

    let set = ["a", "b", "c", "d"].iter().collect();
    let set = powerset(set);
    println!("{:?}", set);
}

implement a function that generates the power set of a given set S. The function can use a library or built-in set type, or define a set type with necessary operations. The power set includes all subsets of S, including the empty set and the set itself. The function should also demonstrate the ability to generate the power set of the empty set and the set containing only the empty set. The implementation requires that the input type T is fully ordered and clonable.


struct RomanNumeral {
    symbol: &'static str,
    value: u32
}

const NUMERALS: [RomanNumeral; 13] = [
    RomanNumeral {symbol: "M",  value: 1000},
    RomanNumeral {symbol: "CM", value: 900},
    RomanNumeral {symbol: "D",  value: 500},
    RomanNumeral {symbol: "CD", value: 400},
    RomanNumeral {symbol: "C",  value: 100},
    RomanNumeral {symbol: "XC", value: 90},
    RomanNumeral {symbol: "L",  value: 50},
    RomanNumeral {symbol: "XL", value: 40},
    RomanNumeral {symbol: "X",  value: 10},
    RomanNumeral {symbol: "IX", value: 9},
    RomanNumeral {symbol: "V",  value: 5},
    RomanNumeral {symbol: "IV", value: 4},
    RomanNumeral {symbol: "I",  value: 1}
];

fn to_roman(mut number: u32) -> String {
    let mut min_numeral = String::new();
    for numeral in NUMERALS.iter() {
        while numeral.value <= number {
            min_numeral = min_numeral + numeral.symbol;
            number -= numeral.value;
        }
    }
    min_numeral
}

fn main() {
    let nums = [2014, 1999, 25, 1666, 3888];
    for &n in nums.iter() {
        // 4 is minimum printing width, for alignment
        println!("{:2$} = {}", n, to_roman(n), 4);
    }
}

create a function that converts a positive integer into its equivalent Roman numeral representation.


let a = [1, 2, 3]; // immutable array
let mut m = [1, 2, 3]; // mutable array
let zeroes = [0; 200]; // creates an array of 200 zeroes

let a = [1, 2, 3];
a.len();
for e in a.iter() {
    e;
}

let names = ["Graydon", "Brian", "Niko"];
names[1]; // second element

let v = vec![1, 2, 3];

let mut v = vec![1, 2, 3];
v.push(4);
v.len(); // 4

demonstrate the basic syntax of arrays in Rust, including the creation of both fixed-length and dynamic arrays (vectors), assigning values to them, and retrieving elements. The codes also show how to make an array mutable, get its length, iterate over it, and use subscript notation to access specific elements. The codes also incorporate elements from obsolete tasks related to array creation, value assignment, and element retrieval.


use std::fs::File;
use std::io::{Read, Write};

fn main() {
    let mut file = File::open("input.txt").unwrap();
    let mut data = Vec::new();
    file.read_to_end(&mut data).unwrap();
    let mut file = File::create("output.txt").unwrap();
    file.write_all(&data).unwrap();
}

use std::fs::File;
use std::io::{self, Read,  Write};
use std::path::Path;
use std::{env, fmt, process};

fn main() {
    let files: Vec<_> = env::args_os().skip(1).take(2).collect();

    if files.len() != 2 {
        exit_err("Both an input file and output file are required", 1);
    }

    copy(&files[0], &files[1]).unwrap_or_else(|e| exit_err(&e, e.raw_os_error().unwrap_or(-1)));
}

fn copy<P: AsRef<Path>>(infile: P, outfile: P) -> io::Result<()> {
    let mut vec = Vec::new();

    Ok(try!(File::open(infile)
         .and_then(|mut i| i.read_to_end(&mut vec))
         .and_then(|_| File::create(outfile))
         .and_then(|mut o| o.write_all(&vec))))
}

fn exit_err<T: fmt::Display>(msg: T, code: i32) -> ! {
    writeln!(&mut io::stderr(), "ERROR: {}", msg).expect("Could not write to stdout");
    process::exit(code);
}

demonstrate how to read content from "input.txt" file into a variable, and then write this variable's content into a new file called "output.txt". The program also includes proper error handling.


Works with: Rust version  1.3
fn main() {
    println!("{}", "jalapeño".to_uppercase()); // JALAPEÑO
    println!("{}", "JALAPEÑO".to_lowercase()); // jalapeño
}

demonstrate the conversion of the string "alphaBETA" to upper-case and lower-case using the default string literal or ASCII encoding. The code also showcases additional case conversion functions such as swapping case or capitalizing the first letter if available in the language's library. Note that in some languages, the toLower and toUpper functions may not be reversible.


//! We interpret complex numbers as points in the Cartesian plane, here. We also use the
//! [sweepline/plane sweep closest pairs algorithm][algorithm] instead of the divide-and-conquer
//! algorithm, since it's (arguably) easier to implement, and an efficient implementation does not
//! require use of unsafe.
//!
//! [algorithm]: http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairPS.html
extern crate num;

use num::complex::Complex;
use std::cmp::{Ordering, PartialOrd};
use std::collections::BTreeSet;
type Point = Complex<f32>;

/// Wrapper around `Point` (i.e. `Complex<f32>`) so that we can use a `TreeSet`
#[derive(PartialEq)]
struct YSortedPoint {
    point: Point,
}

impl PartialOrd for YSortedPoint {
    fn partial_cmp(&self, other: &YSortedPoint) -> Option<Ordering> {
        (self.point.im, self.point.re).partial_cmp(&(other.point.im, other.point.re))
    }
}

impl Ord for YSortedPoint {
    fn cmp(&self, other: &YSortedPoint) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl Eq for YSortedPoint {}

fn closest_pair(points: &mut [Point]) -> Option<(Point, Point)> {
    if points.len() < 2 {
        return None;
    }

    points.sort_by(|a, b| (a.re, a.im).partial_cmp(&(b.re, b.im)).unwrap());

    let mut closest_pair = (points[0], points[1]);
    let mut closest_distance_sqr = (points[0] - points[1]).norm_sqr();
    let mut closest_distance = closest_distance_sqr.sqrt();

    // the strip that we inspect for closest pairs as we sweep right
    let mut strip: BTreeSet<YSortedPoint> = BTreeSet::new();
    strip.insert(YSortedPoint { point: points[0] });
    strip.insert(YSortedPoint { point: points[1] });

    // index of the leftmost point on the strip (on points)
    let mut leftmost_idx = 0;

    // Start the sweep!
    for (idx, point) in points.iter().enumerate().skip(2) {
        // Remove all points farther than `closest_distance` away from `point`
        // along the x-axis
        while leftmost_idx < idx {
            let leftmost_point = &points[leftmost_idx];
            if (leftmost_point.re - point.re).powi(2) < closest_distance_sqr {
                break;
            }
            strip.remove(&YSortedPoint {
                point: *leftmost_point,
            });
            leftmost_idx += 1;
        }

        // Compare to points in bounding box
        {
            let low_bound = YSortedPoint {
                point: Point {
                    re: ::std::f32::INFINITY,
                    im: point.im - closest_distance,
                },
            };
            let mut strip_iter = strip.iter().skip_while(|&p| p < &low_bound);
            loop {
                let point2 = match strip_iter.next() {
                    None => break,
                    Some(p) => p.point,
                };
                if point2.im - point.im >= closest_distance {
                    // we've reached the end of the box
                    break;
                }
                let dist_sqr = (*point - point2).norm_sqr();
                if dist_sqr < closest_distance_sqr {
                    closest_pair = (point2, *point);
                    closest_distance_sqr = dist_sqr;
                    closest_distance = dist_sqr.sqrt();
                }
            }
        }

        // Insert point into strip
        strip.insert(YSortedPoint { point: *point });
    }

    Some(closest_pair)
}

pub fn main() {
    let mut test_data = [
        Complex::new(0.654682, 0.925557),
        Complex::new(0.409382, 0.619391),
        Complex::new(0.891663, 0.888594),
        Complex::new(0.716629, 0.996200),
        Complex::new(0.477721, 0.946355),
        Complex::new(0.925092, 0.818220),
        Complex::new(0.624291, 0.142924),
        Complex::new(0.211332, 0.221507),
        Complex::new(0.293786, 0.691701),
        Complex::new(0.839186, 0.728260),
    ];
    let (p1, p2) = closest_pair(&mut test_data[..]).unwrap();
    println!("Closest pair: {} and {}", p1, p2);
    println!("Distance: {}", (p1 - p2).norm_sqr().sqrt());
}

provide two functions to solve the Closest Pair of Points problem in a 2D plane. The first function uses a brute force algorithm with a complexity of O(n^2) to find the two closest points. The second function uses a recursive divide and conquer approach with a complexity of O(n log n) to find the two closest points. Both functions return the minimum distance and the pair of points.


create a collection and add values to it. The collection can be of various types such as arrays, slices, string slices, vectors, strings, VecDequeue, doubly-linked list, hash map, B-Tree map, set implementations, and priority queue. The type of collection used depends on the specific requirements of the task.


generates a comma-separated list from 1 to 10 using a loop, with separate output statements for the number and the comma in the loop body. An alternative solution uses the join method.


use std::boxed::Box;
use std::collections::{HashMap, HashSet};

#[derive(Debug, PartialEq, Eq, Hash)]
struct Library<'a> {
    name: &'a str,
    children: Vec<&'a str>,
    num_parents: usize,
}

fn build_libraries(input: Vec<&str>) -> HashMap<&str, Box<Library>> {
    let mut libraries: HashMap<&str, Box<Library>> = HashMap::new();

    for input_line in input {
        let line_split = input_line.split_whitespace().collect::<Vec<&str>>();
        let name = line_split.get(0).unwrap();
        let mut num_parents: usize = 0;
        for parent in line_split.iter().skip(1) {
            if parent == name {
                continue;
            }
            if !libraries.contains_key(parent) {
                libraries.insert(
                    parent,
                    Box::new(Library {
                        name: parent,
                        children: vec![name],
                        num_parents: 0,
                    }),
                );
            } else {
                libraries.get_mut(parent).unwrap().children.push(name);
            }
            num_parents += 1;
        }

        if !libraries.contains_key(name) {
            libraries.insert(
                name,
                Box::new(Library {
                    name,
                    children: Vec::new(),
                    num_parents,
                }),
            );
        } else {
            libraries.get_mut(name).unwrap().num_parents = num_parents;
        }
    }
    libraries
}

fn topological_sort<'a>(
    mut libraries: HashMap<&'a str, Box<Library<'a>>>,
) -> Result<Vec<&'a str>, String> {
    let mut needs_processing = libraries
        .iter()
        .map(|(k, _v)| k.clone())
        .collect::<HashSet<&str>>();
    let mut options: Vec<&str> = libraries
        .iter()
        .filter(|(_k, v)| v.num_parents == 0)
        .map(|(k, _v)| *k)
        .collect();
    let mut sorted: Vec<&str> = Vec::new();
    while !options.is_empty() {
        let cur = options.pop().unwrap();
        for children in libraries
            .get_mut(cur)
            .unwrap()
            .children
            .drain(0..)
            .collect::<Vec<&str>>()
        {
            let child = libraries.get_mut(children).unwrap();
            child.num_parents -= 1;
            if child.num_parents == 0 {
                options.push(child.name)
            }
        }
        sorted.push(cur);
        needs_processing.remove(cur);
    }
    match needs_processing.is_empty() {
        true => Ok(sorted),
        false => Err(format!("Cycle detected among {:?}", needs_processing)),
    }
}

fn main() {
    let input: Vec<&str> = vec![
        "des_system_lib   std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee\n",
        "dw01             ieee dw01 dware gtech dw04\n",
        "dw02             ieee dw02 dware\n",
        "dw03             std synopsys dware dw03 dw02 dw01 ieee gtech\n",
        "dw04             dw04 ieee dw01 dware gtech\n",
        "dw05             dw05 ieee dware\n",
        "dw06             dw06 ieee dware\n",
        "dw07             ieee dware\n",
        "dware            ieee dware\n",
        "gtech            ieee gtech\n",
        "ramlib           std ieee\n",
        "std_cell_lib     ieee std_cell_lib\n",
        "synopsys\n",
    ];

    let libraries = build_libraries(input);
    match topological_sort(libraries) {
        Ok(sorted) => println!("{:?}", sorted),
        Err(msg) => println!("{:?}", msg),
    }
}

["std", "synopsys", "ieee", "std_cell_lib", "ramlib", "gtech", "dware", "dw07", "dw06", "dw05", "dw02", "dw01", "dw04", "dw03", "des_system_lib"]

"des_system_lib   std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee\n",
        "dw01             ieee dw01 dware gtech dw04\n",
        "dw02             ieee dw02 dware\n",
        "dw03             std synopsys dware dw03 dw02 dw01 ieee gtech\n",
        "dw04             dw04 ieee dw01 dware gtech\n",
        "dw05             dw05 ieee dware\n",
        "dw06             dw06 ieee dware\n",
        "dw07             ieee dware\n",
        "dware            ieee dware\n",
        "gtech            ieee gtech\n",
        "ramlib           std ieee\n",
        "std_cell_lib     ieee std_cell_lib\n",
        "synopsys\n",

"Cycle detected among {\"dw03\", \"des_system_lib\", \"dw04\", \"dw01\"}"

implement a function that performs a topological sort on VHDL libraries based on their dependencies. The function returns a valid compile order of the libraries, ignoring self-dependencies and flagging un-orderable dependencies. The libraries are assumed to be single words and the order of compiling for libraries mentioned only as dependents is also provided. The function uses either Kahn's 1962 topological sort or depth-first search algorithm for sorting.


fn print_match(possible_match: Option<usize>) {
    match possible_match {
        Some(match_pos) => println!("Found match at pos {}", match_pos),
        None => println!("Did not find any matches")
    }
}

fn main() {
    let s1 = "abcd";
    let s2 = "abab";
    let s3 = "ab";

    // Determining if the first string starts with second string
    assert!(s1.starts_with(s3));
    // Determining if the first string contains the second string at any location
    assert!(s1.contains(s3));
    // Print the location of the match
    print_match(s1.find(s3)); // Found match at pos 0
    print_match(s1.find(s2)); // Did not find any matches
    // Determining if the first string ends with the second string
    assert!(s2.ends_with(s3));
}

fn main(){
    let hello = String::from("Hello world");
    println!(" Start with \"he\" {} \n Ends with \"rd\" {}\n Contains \"wi\" {}",
                                                        hello.starts_with("He"),
                                                        hello.ends_with("ld"),
                                                        hello.contains("wi"));
}

The code checks if a given string starts with, contains, or ends with a second string. It also prints the location of the match and handles multiple occurrences of the second string within the first string.


#![feature(inclusive_range_syntax)]

fn is_unique(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8) -> bool {
    a != b && a != c && a != d && a != e && a != f && a != g &&
    b != c && b != d && b != e && b != f && b != g &&
    c != d && c != e && c != f && c != g &&
    d != e && d != f && d != g &&
    e != f && e != g &&
    f != g
}

fn is_solution(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8, g: u8) -> bool {
    a + b == b + c + d &&
        b + c + d == d + e + f &&
        d + e + f == f + g
}

fn four_squares(low: u8, high: u8, unique: bool) -> Vec<Vec<u8>> {
    let mut results: Vec<Vec<u8>> = Vec::new();

    for a in low..=high {
        for b in low..=high {
            for c in low..=high {
                for d in low..=high {
                    for e in low..=high {
                        for f in low..=high {
                            for g in low..=high {
                                if (!unique || is_unique(a, b, c, d, e, f, g)) &&
                                    is_solution(a, b, c, d, e, f, g) {
                                    results.push(vec![a, b, c, d, e, f, g]);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    results
}

fn print_results(solutions: &Vec<Vec<u8>>) {
    for solution in solutions {
        println!("{:?}", solution)
    }
}

fn print_results_summary(solutions: usize, low: u8, high: u8, unique: bool) {
    let uniqueness = if unique {
        "unique"
    } else {
        "non-unique"
    };
    println!("{} {} solutions in {} to {} range", solutions, uniqueness, low, high)
}

fn uniques(low: u8, high: u8) {
    let solutions = four_squares(low, high, true);
    print_results(&solutions);
    print_results_summary(solutions.len(), low, high, true);
}

fn nonuniques(low: u8, high: u8) {
    let solutions = four_squares(low, high, false);
    print_results_summary(solutions.len(), low, high, false);
}

fn main() {
    uniques(1, 7);
    println!();
    uniques(3, 9);
    println!();
    nonuniques(0, 9);
}

The code finds all possible solutions for a 4-squares puzzle where each square sums up to the same total. It operates under two conditions: each letter representing a unique value between 1-7 and 3-9, and each letter representing a non-unique value between 0-9. The code also counts the number of non-unique solutions.


// cargo-deps: time="0.1"
extern crate time;

use std::thread;
use std::time::Duration;

const TOP: &str = " ⡎⢉⢵ ⠀⢺⠀ ⠊⠉⡱ ⠊⣉⡱ ⢀⠔⡇ ⣏⣉⡉ ⣎⣉⡁ ⠊⢉⠝ ⢎⣉⡱ ⡎⠉⢱ ⠀⠶⠀";
const BOT: &str = " ⢗⣁⡸ ⢀⣸⣀ ⣔⣉⣀ ⢄⣀⡸ ⠉⠉⡏ ⢄⣀⡸ ⢇⣀⡸ ⢰⠁⠀ ⢇⣀⡸ ⢈⣉⡹ ⠀⠶⠀";

fn main() {
    let top: Vec<&str> = TOP.split_whitespace().collect();
    let bot: Vec<&str> = BOT.split_whitespace().collect();

    loop {
        let tm = &time::now().rfc822().to_string()[17..25];
        let top_str: String = tm.chars().map(|x| top[x as usize - '0' as usize]).collect();
        let bot_str: String = tm.chars().map(|x| bot[x as usize - '0' as usize]).collect();

        clear_screen();
        println!("{}", top_str);
        println!("{}", bot_str);

        thread::sleep(Duration::from_secs(1));
    }
}

fn clear_screen() {
    println!("{}[H{}[J", 27 as char, 27 as char);
}

illustrate a time-keeping device that updates every second and cycles periodically. It is designed to be simple, efficient, and not to overuse CPU resources by avoiding unnecessary system timer polling. The time displayed aligns with the system clock. Both text-based and graphical representations are supported.


use std::thread;

fn f1 (a : u64, b : u64, c : u64, d : u64) -> u64 {
    let mut primitive_count = 0;
    for triangle in [[a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c],
                     [a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c],
                     [2*b + 2*c - a, b + 2*c - 2*a, 2*b + 3*c - 2*a]] .iter() {
        let l  = triangle[0] + triangle[1] + triangle[2];
        if l > d { continue; }
        primitive_count +=  1 + f1(triangle[0], triangle[1], triangle[2], d);
    }
    primitive_count
}

fn f2 (a : u64, b : u64, c : u64, d : u64) -> u64 {
    let mut triplet_count = 0;
    for triangle in [[a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c],
                     [a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c],
                     [2*b + 2*c - a, b + 2*c - 2*a, 2*b + 3*c - 2*a]] .iter() {
        let l  = triangle[0] + triangle[1] + triangle[2];
        if l > d { continue; }
        triplet_count +=  (d/l) + f2(triangle[0], triangle[1], triangle[2], d);
    }
    triplet_count
}

fn main () {
    let new_th_1 = thread::Builder::new().stack_size(32 * 1024 * 1024).spawn (move || {
        let mut i = 100;
        while i <= 100_000_000_000 {
            println!(" Primitive triples below {} : {}", i, f1(3, 4, 5, i) + 1);
            i *= 10;
        }
    }).unwrap();

    let new_th_2 =thread::Builder::new().stack_size(32 * 1024 * 1024).spawn (move || {
        let mut i = 100;
        while i <= 100_000_000_000 {
            println!(" Triples below {} : {}", i, f2(3, 4, 5, i) + i/12);
            i *= 10;
        }
    }).unwrap();

    new_th_1.join().unwrap();
    new_th_2.join().unwrap();
}

The code calculates the number of Pythagorean triples (a, b, c) where a, b, and c are positive integers, a < b < c, and a^2 + b^2 = c^2, with a perimeter (a + b + c) no larger than 100. It also determines the number of these triples that are primitive, meaning a, b, and c are co-prime. The code is also optimized to handle large values up to a maximum perimeter of 100,000,000.


Library: winit
use winit::event::{Event, WindowEvent};  // winit 0.24
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::WindowBuilder;

fn main() {
    let event_loop = EventLoop::new();
    let _win = WindowBuilder::new()
        .with_title("Window")
        .build(&event_loop).unwrap();

    event_loop.run(move |ev, _, flow| {
        match ev {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested, ..
            } => {
                *flow = ControlFlow::Exit;
            }
            _ => {}
        }
    });
}

Create an empty GUI window that can handle close requests.


use std::collections::btree_map::BTreeMap;
use std::{env, process};
use std::io::{self, Read, Write};
use std::fmt::Display;
use std::fs::File;

fn main() {
    let filename = env::args().nth(1)
        .ok_or("Please supply a file name")
        .unwrap_or_else(|e| exit_err(e, 1));

    let mut buf = String::new();
    let mut count = BTreeMap::new();

    File::open(&filename)
        .unwrap_or_else(|e| exit_err(e, 2))
        .read_to_string(&mut buf)
        .unwrap_or_else(|e| exit_err(e, 3));

    for c in buf.chars() {
        *count.entry(c).or_insert(0) += 1;
    }

    println!("Number of occurences per character");
    for (ch, count) in &count {
        println!("{:?}: {}", ch, count);
    }
}

#[inline]
fn exit_err<T>(msg: T, code: i32) -> ! where T: Display {
    writeln!(&mut io::stderr(), "{}", msg).expect("Could not write to stderr");
    process::exit(code)
}

Number of occurences per character
'\n': 35
' ': 167
'!': 4
'\"': 10
'#': 1
'&': 4
'(': 25
')': 25
'*': 1
'+': 1
',': 12
'-': 1
'.': 10
'0': 1
'1': 3
'2': 2
'3': 2
':': 37
';': 13
'<': 1
'=': 4
'>': 2
'?': 1
'B': 2
'C': 1
'D': 2
'F': 2
'M': 2
'N': 1
'P': 1
'R': 1
'S': 1
'T': 5
'W': 1
'[': 1
']': 1
'_': 15
'a': 20
'b': 5
'c': 22
'd': 12
'e': 75
'f': 14
'g': 5
'h': 6
'i': 29
'k': 1
'l': 23
'm': 13
'n': 36
'o': 28
'p': 17
'r': 45
's': 33
't': 42
'u': 24
'v': 2
'w': 8
'x': 6
'y': 4
'{': 9
'|': 6
'}': 9

The code opens a text file and counts the frequency of each letter, including all UTF-8 characters. It can count all characters or only letters from A to Z, depending on the program. The output is generated when run on the source file.


 struct Node<T> {
    elem: T,
    next: Option<Box<Node<T>>>,
}

type Link<T> = Option<Box<Node<T>>>; // Type alias
pub struct List<T> { // User-facing interface for list
    head: Link<T>,
}

struct Node<T> { // Private implementation of Node
    elem: T,
    next: Link<T>,
}

impl<T> List<T> {
    #[inline]
    pub fn new() -> Self { // List constructor
        List { head: None }
    // Add other methods here
}

extern crate LinkedList; // Name is arbitrary here

use LinkedList::List;

fn main() {
    let list = List::new();
    // Do stuff
}

define a data structure for a singly-linked list element. This element holds a numeric value and a mutable link to the next element. The implementation uses Rust's Option<T> type and Box<T> for a known size. However, it lacks encapsulation for library use. A separate program can utilize this basic implementation.


Library: Piston
//Cargo deps :
//  piston = "0.35.0"
//  piston2d-graphics = "0.23.0"
//  piston2d-opengl_graphics = "0.49.0"
//  pistoncore-glutin_window = "0.42.0"

extern crate piston;
extern crate graphics;
extern crate opengl_graphics;
extern crate glutin_window;

use piston::window::WindowSettings;
use piston::event_loop::{Events, EventSettings};
use piston::input::RenderEvent;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{GlGraphics, OpenGL};
use graphics::{clear, line, Context};

const ANG: f64 = 20.0;
const COLOR: [f32; 4] = [1.0, 0.0, 0.5, 1.0];
const LINE_THICKNESS: f64 = 5.0;
const DEPTH: u32 = 11;

fn main() {
    let mut window: Window = WindowSettings::new("Fractal Tree", [1024, 768])
        .opengl(OpenGL::V3_2)
        .exit_on_esc(true)
        .build()
        .unwrap();
    let mut gl = GlGraphics::new(OpenGL::V3_2);

    let mut events = Events::new(EventSettings::new());
    while let Some(e) = events.next(&mut window) {
        if let Some(args) = e.render_args() {
            gl.draw(args.viewport(), |c, g| {
                clear([1.0, 1.0, 1.0, 1.0], g);
                draw_fractal_tree(512.0, 700.0, 0.0, DEPTH, c, g);
            });
        }
    }
}

fn draw_fractal_tree(x1: f64, y1: f64, angle: f64, depth: u32, c: Context, g: &mut GlGraphics) {
    let x2 = x1 + angle.to_radians().sin() * depth as f64 * 10.0;
    let y2 = y1 - angle.to_radians().cos() * depth as f64 * 10.0;
    line(
        COLOR,
        LINE_THICKNESS * depth as f64 * 0.2,
        [x1, y1, x2, y2],
        c.transform,
        g,
    );
    if depth > 0 {
        draw_fractal_tree(x2, y2, angle - ANG, depth - 1, c, g);
        draw_fractal_tree(x2, y2, angle + ANG, depth - 1, c, g);
    }
}

generate and draw a fractal tree by first drawing the trunk, then splitting the trunk at the end by a certain angle to form two branches, and repeating this process until a desired level of branching is reached.


fn main() {
    assert_eq!(vec![1, 2, 4, 5, 10, 10, 20, 25, 50, 100], factor(100)); // asserts that two expressions are equal to each other
    assert_eq!(vec![1, 101], factor(101));

}

fn factor(num: i32) -> Vec<i32> {
    let mut factors: Vec<i32> = Vec::new(); // creates a new vector for the factors of the number

    for i in 1..((num as f32).sqrt() as i32 + 1) {
        if num % i == 0 {
            factors.push(i); // pushes smallest factor to factors
            factors.push(num/i); // pushes largest factor to factors
        }
    }
    factors.sort(); // sorts the factors into numerical order for viewing purposes
    factors // returns the factors
}

fn factor(n: i32) -> Vec<i32> {
    (1..=n).filter(|i| n % i == 0).collect()
}

compute the factors of a given positive integer, excluding zero and negative integers. It also notes that every prime number has two factors: 1 and itself.


use std::iter::{repeat, Extend};

enum AlignmentType {
    Left,
    Center,
    Right,
}

fn get_column_widths(text: &str) -> Vec<usize> {
    let mut widths = Vec::new();
    for line in text
        .lines()
        .map(|s| s.trim_matches(' ').trim_end_matches('$'))
    {
        let lens = line.split('$').map(|s| s.chars().count());
        for (idx, len) in lens.enumerate() {
            if idx < widths.len() {
                widths[idx] = std::cmp::max(widths[idx], len);
            } else {
                widths.push(len);
            }
        }
    }
    widths
}

fn align_columns(text: &str, alignment: AlignmentType) -> String {
    let widths = get_column_widths(text);
    let mut result = String::new();
    for line in text
        .lines()
        .map(|s| s.trim_matches(' ').trim_end_matches('$'))
    {
        for (s, w) in line.split('$').zip(widths.iter()) {
            let blank_count = w - s.chars().count();
            let (pre, post) = match alignment {
                AlignmentType::Left => (0, blank_count),
                AlignmentType::Center => (blank_count / 2, (blank_count + 1) / 2),
                AlignmentType::Right => (blank_count, 0),
            };
            result.extend(repeat(' ').take(pre));
            result.push_str(s);
            result.extend(repeat(' ').take(post));
            result.push(' ');
        }
        result.push_str("\n");
    }
    result
}

fn main() {
    let text = r#"Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column."#;

    println!("{}", align_columns(text, AlignmentType::Left));
    println!("{}", repeat('-').take(110).collect::<String>());
    println!("{}", align_columns(text, AlignmentType::Center));
    println!("{}", repeat('-').take(110).collect::<String>());
    println!("{}", align_columns(text, AlignmentType::Right));
}

The code reads a text file with lines separated by a dollar character. It aligns each column of fields by ensuring at least one space between words in each column. It also allows each word in a column to be left, right, or center justified. The minimum space between columns is computed from the text, not hard-coded. Trailing dollar characters or consecutive spaces at the end of lines do not affect the alignment. The output is suitable for viewing in a mono-spaced font on a plain text editor or basic terminal.


let conn = ldap3::LdapConn::new("ldap://ldap.example.com")?;
conn.simple_bind("bind_dn", "bind_pass")?.success()?;

establish a connection to an Active Directory or Lightweight Directory Access Protocol server using the ldap3 crate.


fn rot13(string: &str) -> String {
    string.chars().map(|c| {
        match c {
            'a'..='m' | 'A'..='M' => ((c as u8) + 13) as char,
            'n'..='z' | 'N'..='Z' => ((c as u8) - 13) as char,
            _ => c
        }
    }).collect()
}

fn main () {
    assert_eq!(rot13("abc"), "nop");
}

implement a rot-13 function that replaces every letter of the ASCII alphabet with the letter which is "rotated" 13 characters around the 26 letter alphabet. The function should work on both upper and lower case letters, preserve case, and pass all non-alphabetic characters without alteration. Optionally, the function can be wrapped in a utility program that performs rot-13 encoding line-by-line for every line of input in each file listed on its command line or acts as a filter on its standard input.


use std::cmp::Ordering;

#[derive(Debug)]
struct Employee {
    name: String,
    category: String,
}

impl Employee {
    fn new(name: &str, category: &str) -> Self {
        Employee {
            name: name.into(),
            category: category.into(),
        }
    }
}

impl PartialEq for Employee {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name
    }
}

impl Eq for Employee {}

impl PartialOrd for Employee {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Employee {
    fn cmp(&self, other: &Self) -> Ordering {
        self.name.cmp(&other.name)
    }
}

fn main() {
    let mut employees = vec![
        Employee::new("David", "Manager"),
        Employee::new("Alice", "Sales"),
        Employee::new("Joanna", "Director"),
        Employee::new("Henry", "Admin"),
        Employee::new("Tim", "Sales"),
        Employee::new("Juan", "Admin"),
    ];
    employees.sort();
    for e in employees {
        println!("{:<6} : {}", e.name, e.category);
    }
}

sort an array of composite structures, specifically name-value pairs, by the key name using a custom comparator.


fn main() {
    for i in 0..5 {
        for _ in 0..=i {
            print!("*");
        }

        println!();
    }
}

The code demonstrates the use of nested 'for' loops to print a pattern. The outer loop controls the number of iterations of the inner loop, resulting in a pyramid pattern of asterisks. The underscore (_) is used to avoid compiler warnings for unused variables.


use std::collections::HashMap;
fn main() {
    let mut olympic_medals = HashMap::new();
    olympic_medals.insert("United States", (1072, 859, 749));
    olympic_medals.insert("Soviet Union", (473, 376, 355));
    olympic_medals.insert("Great Britain", (246, 276, 284));
    olympic_medals.insert("Germany", (252, 260, 270));
    println!("{:?}", olympic_medals);
}

"Create an associative array, also known as a dictionary, map, or hash."


extern crate rand;

pub use rand::{Rng, SeedableRng};

pub struct BsdLcg {
    state: u32,
}

impl Rng for BsdLcg {
    // Because the output is in the range [0, 2147483647], this should technically be `next_u16`
    // (the largest integer size which is fully covered, as `rand::Rng` assumes).  The `rand`
    // crate does not provide it however.  If serious usage is required, implementing this
    // function as a concatenation of two `next_u16`s (elsewhere defined) should work.
    fn next_u32(&mut self) -> u32 {
        self.state = self.state.wrapping_mul(1_103_515_245).wrapping_add(12_345);
        self.state %= 1 << 31;
        self.state
    }
}

impl SeedableRng<u32> for BsdLcg {
    fn from_seed(seed: u32) -> Self {
        Self { state: seed }
    }
    fn reseed(&mut self, seed: u32) {
        self.state = seed;
    }
}

pub struct MsLcg {
    state: u32,
}

impl Rng for MsLcg {
    // Similarly, this outputs in the range [0, 32767] and should output a `u8`.  Concatenate
    // four `next_u8`s for serious usage.
    fn next_u32(&mut self) -> u32 {
        self.state = self.state.wrapping_mul(214_013).wrapping_add(2_531_011);
        self.state %= 1 << 31;
        self.state >> 16 // rand_n = state_n / 2^16
    }
}

impl SeedableRng<u32> for MsLcg {
    fn from_seed(seed: u32) -> Self {
        Self { state: seed }
    }
    fn reseed(&mut self, seed: u32) {
        self.state = seed;
    }
}

fn main() {
    println!("~~~ BSD ~~~");
    let mut bsd = BsdLcg::from_seed(0);
    for _ in 0..10 {
        println!("{}", bsd.next_u32());
    }

    println!("~~~ MS ~~~");
    let mut ms = MsLcg::from_seed(0);
    for _ in 0..10 {
        println!("{}", ms.next_u32());
    }

    // Because we have implemented the `rand::Rng` trait, we can generate a variety of other types.
    println!("~~~ Others ~~~");
    println!("{:?}", ms.gen::<[u32; 5]>());
    println!("{}", ms.gen::<bool>());
    println!("{}", ms.gen_ascii_chars().take(15).collect::<String>());
}

The code implements two historic random number generators: the rand() function from BSD libc and the rand() function from the Microsoft C Runtime (MSCVRT.DLL). These generators use the linear congruential generator formula with specific constants. The generators produce a sequence of integers, starting from a seed value, that is not cryptographically secure but can be used for simple tasks. The BSD generator outputs numbers in the range 0 to 2147483647, while the Microsoft generator outputs numbers in the range 0 to 32767.


impl<T> List<T> {
    pub fn new() -> Self {
        List { head: None }
    }

    pub fn push(&mut self, elem: T) {
    let new_node = Box::new(Node {
        elem: elem,
        next: self.head.take(),
    });
    self.head = Some(new_node);
}

implement a method to insert an element into a singly-linked list after a specified element. Specifically, the code inserts element C into a list of elements A->B, after element A. The code also extends the Singly-Linked List (element) in Rust and includes the Linked List struct declarations.


fn double(a: i32) -> i32 {
    2*a
}

fn halve(a: i32) -> i32 {
    a/2
}

fn is_even(a: i32) -> bool {
    a % 2 == 0
}

fn ethiopian_multiplication(mut x: i32, mut y: i32) -> i32 {
    let mut sum = 0;

    while x >= 1 {
        print!("{} \t {}", x, y);
        match is_even(x) {
            true  => println!("\t Not Kept"),
            false => {
                println!("\t Kept");
                sum += y;
            }
        }
        x = halve(x);
        y = double(y);
    }
    sum
}

fn main() {
    let output = ethiopian_multiplication(17, 34);
    println!("---------------------------------");
    println!("\t {}", output);
}

The code defines three functions for halving an integer, doubling an integer, and checking if an integer is even. These functions are used to implement Ethiopian multiplication, a method of multiplying integers using addition, doubling, and halving. The multiplication process involves creating a table, discarding rows with even numbers in the left column, and summing the remaining values in the right column.


Works with: Rust version 1.17
#[derive(Clone, Copy, Debug)]
enum Operator {
    Sub,
    Plus,
    Mul,
    Div,
}

#[derive(Clone, Debug)]
struct Factor {
    content: String,
    value: i32,
}

fn apply(op: Operator, left: &[Factor], right: &[Factor]) -> Vec<Factor> {
    let mut ret = Vec::new();
    for l in left.iter() {
        for r in right.iter() {
            use Operator::*;
            ret.push(match op {
                Sub if l.value > r.value => Factor {
                    content: format!("({} - {})", l.content, r.content),
                    value: l.value - r.value,
                },
                Plus => Factor {
                    content: format!("({} + {})", l.content, r.content),
                    value: l.value + r.value,
                },
                Mul => Factor {
                    content: format!("({} x {})", l.content, r.content),
                    value: l.value * r.value,
                },
                Div if l.value >= r.value && r.value > 0 && l.value % r.value == 0 => Factor {
                    content: format!("({} / {})", l.content, r.content),
                    value: l.value / r.value,
                },
                _ => continue,
            })
        }
    }
    ret
}

fn calc(op: [Operator; 3], numbers: [i32; 4]) -> Vec<Factor> {
    fn calc(op: &[Operator], numbers: &[i32], acc: &[Factor]) -> Vec<Factor> {
        use Operator::*;
        if op.is_empty() {
            return Vec::from(acc)
        }
        let mut ret = Vec::new();
        let mono_factor = [Factor {
            content: numbers[0].to_string(),
            value: numbers[0],
        }];
        match op[0] {
            Mul => ret.extend_from_slice(&apply(op[0], acc, &mono_factor)),
            Div => {
                ret.extend_from_slice(&apply(op[0], acc, &mono_factor));
                ret.extend_from_slice(&apply(op[0], &mono_factor, acc));
            },
            Sub => {
                ret.extend_from_slice(&apply(op[0], acc, &mono_factor));
                ret.extend_from_slice(&apply(op[0], &mono_factor, acc));
            },
            Plus => ret.extend_from_slice(&apply(op[0], acc, &mono_factor)),
        }
        calc(&op[1..], &numbers[1..], &ret)
    }
    calc(&op, &numbers[1..], &[Factor { content: numbers[0].to_string(), value: numbers[0] }])
}

fn solutions(numbers: [i32; 4]) -> Vec<Factor> {
    use std::collections::hash_set::HashSet;
    let mut ret = Vec::new();
    let mut hash_set = HashSet::new();

    for ops in OpIter(0) {
        for o in orders().iter() {
            let numbers = apply_order(numbers, o);
            let r = calc(ops, numbers);
            ret.extend(r.into_iter().filter(|&Factor { value, ref content }| value == 24 && hash_set.insert(content.to_owned())))
        }
    }
    ret
}

fn main() {
    let mut numbers = Vec::new();
    if let Some(input) = std::env::args().skip(1).next() {
        for c in input.chars() {
            if let Ok(n) = c.to_string().parse() {
                numbers.push(n)
            }
            if numbers.len() == 4 {
                let numbers = [numbers[0], numbers[1], numbers[2], numbers[3]];
                let solutions = solutions(numbers);
                let len = solutions.len();
                if len == 0 {
                    println!("no solution for {}, {}, {}, {}", numbers[0], numbers[1], numbers[2], numbers[3]);
                    return
                }
                println!("solutions for {}, {}, {}, {}", numbers[0], numbers[1], numbers[2], numbers[3]);
                for s in solutions {
                    println!("{}", s.content)
                }
                println!("{} solutions found", len);
                return
            }
        }
    } else {
        println!("empty input")
    }
}

struct OpIter (usize);

impl Iterator for OpIter {
    type Item = [Operator; 3];
    fn next(&mut self) -> Option<[Operator; 3]> {
        use Operator::*;
        const OPTIONS: [Operator; 4] = [Mul, Sub, Plus, Div];
        if self.0 >= 1 << 6 {
            return None
        }
        let f1 = OPTIONS[(self.0 & (3 << 4)) >> 4];
        let f2 = OPTIONS[(self.0 & (3 << 2)) >> 2];
        let f3 = OPTIONS[(self.0 & (3 << 0)) >> 0];
        self.0 += 1;
        Some([f1, f2, f3])
    }
}

fn orders() -> [[usize; 4]; 24] {
    [
        [0, 1, 2, 3],
        [0, 1, 3, 2],
        [0, 2, 1, 3],
        [0, 2, 3, 1],
        [0, 3, 1, 2],
        [0, 3, 2, 1],
        [1, 0, 2, 3],
        [1, 0, 3, 2],
        [1, 2, 0, 3],
        [1, 2, 3, 0],
        [1, 3, 0, 2],
        [1, 3, 2, 0],
        [2, 0, 1, 3],
        [2, 0, 3, 1],
        [2, 1, 0, 3],
        [2, 1, 3, 0],
        [2, 3, 0, 1],
        [2, 3, 1, 0],
        [3, 0, 1, 2],
        [3, 0, 2, 1],
        [3, 1, 0, 2],
        [3, 1, 2, 0],
        [3, 2, 0, 1],
        [3, 2, 1, 0]
    ]
}

fn apply_order(numbers: [i32; 4], order: &[usize; 4]) -> [i32; 4] {
    [numbers[order[0]], numbers[order[1]], numbers[order[2]], numbers[order[3]]]
}

The code accepts four digits, either from user input or randomly generated, and calculates arithmetic expressions following the 24 game rules. It also displays examples of the solutions it generates.


fn factorial_recursive (n: u64) -> u64 {
    match n {
        0 => 1,
        _ => n * factorial_recursive(n-1)
    }
}

fn factorial_iterative(n: u64) -> u64 {
    (1..=n).product()
}

fn main () {
    for i in 1..10 {
        println!("{}", factorial_recursive(i))
    }
    for i in 1..10 {
        println!("{}", factorial_iterative(i))
    }
}

The code defines a function that calculates the factorial of a given number. The factorial is the product of all positive integers from the given number down to 1. The function can be implemented either iteratively or recursively. It optionally includes error handling for negative input numbers. It is related to the task of generating primorial numbers.


Library: rand
use std::io;
use rand::{Rng,thread_rng};

extern crate rand;

const NUMBER_OF_DIGITS: usize = 4;

static DIGITS: [char; 9] = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];

fn generate_digits() -> Vec<char> {
    let mut temp_digits: Vec<_> = (&DIGITS[..]).into();
    thread_rng().shuffle(&mut temp_digits);
    return temp_digits.iter().take(NUMBER_OF_DIGITS).map(|&a| a).collect();
}

fn parse_guess_string(guess: &str) -> Result<Vec<char>, String> {
    let chars: Vec<char> = (&guess).chars().collect();

    if !chars.iter().all(|c| DIGITS.contains(c)) {
        return Err("only digits, please".to_string());
    }

    if chars.len() != NUMBER_OF_DIGITS {
        return Err(format!("you need to guess with {} digits", NUMBER_OF_DIGITS));
    }

    let mut uniques: Vec<char> = chars.clone();
    uniques.dedup();
    if uniques.len() != chars.len() {
        return Err("no duplicates, please".to_string());
    }

    return Ok(chars);
}

fn calculate_score(given_digits: &[char], guessed_digits: &[char]) -> (usize, usize) {
    let mut bulls = 0;
    let mut cows = 0;
    for i in 0..NUMBER_OF_DIGITS {
        let pos: Option<usize> = guessed_digits.iter().position(|&a| -> bool {a == given_digits[i]});
        match pos {
            None              => (),
            Some(p) if p == i => bulls += 1,
            Some(_)           => cows += 1
        }
    }
    return (bulls, cows);
}

fn main() {
    let reader = io::stdin();

    loop {
        let given_digits = generate_digits();
        println!("I have chosen my {} digits. Please guess what they are", NUMBER_OF_DIGITS);

        loop {
            let guess_string: String = {
                let mut buf = String::new();
                reader.read_line(&mut buf).unwrap();
                buf.trim().into()
            };

            let digits_maybe = parse_guess_string(&guess_string);
            match digits_maybe {
                Err(msg) => {
                    println!("{}", msg);
                    continue;
                },
                Ok(guess_digits) => {
                    match calculate_score(&given_digits, &guess_digits) {
                        (NUMBER_OF_DIGITS, _) => {
                            println!("you win!");
                            break;
                        },
                        (bulls, cows) => println!("bulls: {}, cows: {}", bulls, cows)
                    }
                }
            }
        }
    }
}

generate a unique four-digit number, accept and validate user guesses, calculate and print scores based on matching digits and their positions, and end the program when the user guess matches the generated number.


Library: rand

extern crate rand;
use rand::distributions::{Normal, IndependentSample};

fn main() {
    let mut rands = [0.0; 1000];
    let normal = Normal::new(1.0, 0.5);
    let mut rng = rand::thread_rng();
    for num in rands.iter_mut() {
        *num = normal.ind_sample(&mut rng);
    }
}

extern crate rand;
use rand::distributions::{Normal, IndependentSample};

fn main() {
    let rands: Vec<_> = {
        let normal = Normal::new(1.0, 0.5);
        let mut rng = rand::thread_rng();
        (0..1000).map(|_| normal.ind_sample(&mut rng)).collect()
    };
}

generates a collection of 1000 normally distributed pseudo-random numbers with a mean of 1.0 and a standard deviation of 0.5, using either a for-loop or iterators. It utilizes libraries that generate uniformly distributed random numbers.


// alternatively, fn dot_product(a: &Vec<u32>, b: &Vec<u32>)
// but using slices is more general and rustic
fn dot_product(a: &[i32], b: &[i32]) -> Option<i32> {
    if a.len() != b.len() { return None }
    Some(
        a.iter()
            .zip( b.iter() )
            .fold(0, |sum, (el_a, el_b)| sum + el_a*el_b)
    )
}

fn main() {
    let v1 = vec![1, 3, -5];
    let v2 = vec![4, -2, -1];

    println!("{}", dot_product(&v1, &v2).unwrap());
}

#![feature(zero_one)] // <-- unstable feature
use std::ops::{Add, Mul};
use std::num::Zero;

fn dot_product<T1, T2, U, I1, I2>(lhs: I1, rhs: I2) -> Option<U>
    where T1: Mul<T2, Output = U>,
          U: Add<U, Output = U> + Zero,
          I1: IntoIterator<Item = T1>,
          I2: IntoIterator<Item = T2>,
          I1::IntoIter: ExactSizeIterator,
          I2::IntoIter: ExactSizeIterator,
{
    let (iter_lhs, iter_rhs) = (lhs.into_iter(), rhs.into_iter());
    match (iter_lhs.len(), iter_rhs.len()) {
        (0, _) | (_, 0) => None,
        (a,b) if a != b => None,
        (_,_) => Some( iter_lhs.zip(iter_rhs)
           .fold(U::zero(), |sum, (a, b)| sum + (a * b)) )
    }
}

fn main() {
    let v1 = vec![1, 3, -5];
    let v2 = vec![4, -2, -1];

    println!("{}", dot_product(&v1, &v2).unwrap());
}

implement a function to calculate the dot product of two vectors. The vectors can be of arbitrary length but must be the same length to perform the operation. The function multiplies corresponding terms from each vector and sums the products to produce the result. It also includes a check for equal length of vectors and can work with any two types that can be multiplied to result in a third type which can be added with itself. The function is compatible with any argument convertible to an Iterator of known length.


 use std::io::{self, BufReader, Read, BufRead};
use std::fs::File;

fn main() {
    print_by_line(io::stdin())
        .expect("Could not read from stdin");

    File::open("/etc/fstab")
        .and_then(print_by_line)
        .expect("Could not read from file");
}

fn print_by_line<T: Read>(reader: T) -> io::Result<()> {
    let buffer = BufReader::new(reader);
    for line in buffer.lines() {
        println!("{}", line?)
    }
    Ok(())
}

"Continuously read words or lines from a text stream until there is no more data available."


// 20210210 Rust programming solution

extern crate chrono;
use chrono::prelude::*;

fn main() {
   let utc: DateTime<Utc> = Utc::now();
   println!("{}", utc.format("%d/%m/%Y %T"));
}

the system time in a specified unit. This can be used for debugging, network information, random number seeds, or program performance. The time is retrieved either by a system command or a built-in language function. It is related to the task of date formatting and retrieving system time.


fn sedol(input: &str) -> Option<String> {
    let weights = vec![1, 3, 1, 7, 3, 9, 1];
    let valid_chars = "0123456789BCDFGHJKLMNPQRSTVWXYZ";

    if input.len() != 6 {
        return None;
    }

    // could be done by regex if needed
    for c in input.chars() {
        if !valid_chars.contains(c) {
            return None;
        }
    }

    let mut result: u32 = input
        .chars()
        .map(|c| {
            if c.is_digit(10) {
                c as u32 - 48
            } else {
                c as u32 - 55
            }
        })
        .zip(weights)
        .map(|(cnum, w)| w * cnum)
        .collect::<Vec<u32>>()
        .iter()
        .sum();

    result = (10 - result % 10) % 10;

    Some(input.to_owned() + &result.to_string())
}

fn main() {
    let inputs = vec![
        "710889", "B0YBKJ", "406566", "B0YBLH", "228276", "B0YBKL", "557910", "B0YBKR", "585284",
        "B0YBKT", "B00030",
    ];

    for input in inputs {
        println!("{} SEDOL: {:?}", &input, sedol(&input).unwrap());
    }
}

The code takes a list of 6-digit SEDOLs as input, calculates the checksum digit for each SEDOL, and appends it to the end of the respective SEDOL. It also validates the input to ensure it contains only valid characters for a SEDOL string.


// [dependencies]
// image = "0.23"

use image::{GrayImage, Luma};

type Vector = [f64; 3];

fn normalize(v: &mut Vector) {
    let inv_len = 1.0/dot_product(v, v).sqrt();
    v[0] *= inv_len;
    v[1] *= inv_len;
    v[2] *= inv_len;
}

fn dot_product(v1: &Vector, v2: &Vector) -> f64 {
    v1.iter().zip(v2.iter()).map(|(x, y)| *x * *y).sum()
}

fn draw_sphere(radius: u32, k: f64, ambient: f64, dir: &Vector) -> GrayImage {
    let width = radius * 4;
    let height = radius * 3;
    let mut image = GrayImage::new(width, height);
    let mut vec = [0.0; 3];
    let diameter = radius * 2;
    let r = radius as f64;
    let xoffset = (width - diameter)/2;
    let yoffset = (height - diameter)/2;
    for i in 0..diameter {
        let x = i as f64 - r;
        for j in 0..diameter {
            let y = j as f64 - r;
            let z = r * r - x * x - y * y;
            if z >= 0.0 {
                vec[0] = x;
                vec[1] = y;
                vec[2] = z.sqrt();
                normalize(&mut vec);
                let mut s = dot_product(&dir, &vec);
                if s < 0.0 {
                    s = 0.0;
                }
                let mut lum = 255.0 * (s.powf(k) + ambient)/(1.0 + ambient);
                if lum < 0.0 {
                    lum = 0.0;
                } else if lum > 255.0 {
                    lum = 255.0;
                }
                image.put_pixel(i + xoffset, j + yoffset, Luma([lum as u8]));
            }
        }
    }
    image
}

fn main() {
    let mut dir = [-30.0, -30.0, 50.0];
    normalize(&mut dir);
    match draw_sphere(200, 1.5, 0.2, &dir).save("sphere.png") {
        Ok(()) => {}
        Err(error) => eprintln!("{}", error),
    }
}

represent the functionality of drawing a sphere, either graphically or in ASCII art, with the option of static or rotational projection, depending on the language capabilities.


The code defines a function that takes an integer input greater than or equal to zero and returns a string representation of the number with an ordinal suffix. The function is tested with ranges 0 to 25, 250 to 265, and 1000 to 1025. The use of apostrophes in the output is optional.


fn strip_characters(original : &str, to_strip : &str) -> String {
    let mut result = String::new();
    for c in original.chars() {
        if !to_strip.contains(c) {
           result.push(c);
       }
    }
    result
}

fn strip_characters(original : &str, to_strip : &str) -> String {
    original.chars().filter(|&c| !to_strip.contains(c)).collect()
}

fn main() {
    println!("{}", strip_characters("She was a soul stripper. She took my heart!", "aei"));
}

The code defines a function that removes a specified set of characters from a given string. The function takes two inputs: the original string and a string of characters to be removed. The function then returns the original string with all instances of the specified characters removed.