<commit_before>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Rank/Select data structure based on Gonzalez, Grabowski, Mäkinen, Navarro (2005).
//! This implementation uses only a single level of blocks, and performs well for large n.
//!
//! Example
//!
//! ```
//! extern crate bv;
//! # extern crate bio;
//! # fn main() {
//! use bio::data_structures::rank_select::RankSelect;
//! use bv::BitVec;
//! use bv::BitsMut;
//!
//! let mut bits: BitVec<u8> = BitVec::new_fill(false, 64);
//! bits.set_bit(5, true);
//! bits.set_bit(32, true);
//! let rs = RankSelect::new(bits, 1);
//! assert!(rs.rank(6).unwrap() == 1);
//! # }
//! ```

use std::cmp;

use bv::BitVec;
use bv::Bits;

/// A rank/select data structure.
#[derive(Serialize, Deserialize)]
pub struct RankSelect {
    n: usize,
    bits: BitVec<u8>,
    superblocks_1: Vec<u64>,
    superblocks_0: Vec<u64>,
    s: usize,
    k: usize,
}

impl RankSelect {
    /// Create a new instance.
    ///
    /// # Arguments
    ///
    /// * `bits` - A bit vector.
    /// * `k` - Determines the size (k * 32 bits) of the superblocks.
    ///   A small k means faster rank query times at the expense of using more
    ///   space and slower select query times.
    ///   The data structure needs O(n + n log n / (k * 32)) bits with n being the bits of the given bitvector.
    ///   The data structure is succinct if k is chosen as a sublinear function of n
    ///   (e.g. k = (log n)² / 32).
    pub fn new(bits: BitVec<u8>, k: usize) -> RankSelect {
        let n = bits.len() as usize;
        let s = k * 32;

        RankSelect {
            n,
            s,
            k,
            superblocks_1: superblocks(true, n, s, &bits),
            superblocks_0: superblocks(false, n, s, &bits),
            bits,
        }
    }

    /// Return the used k (see `RankSelect::new()`).
    pub fn k(&self) -> usize {
        self.k
    }

    /// Get internal representation of bit vector.
    pub fn bits(&self) -> &BitVec<u8> {
        &self.bits
    }

    /// Return i-th bit.
    pub fn get(&self, i: u64) -> bool {
        self.bits.get_bit(i)
    }

    /// Get the 1-rank of a given bit, i.e. the number of 1-bits in the bitvector up to i (inclusive).
    /// Complexity: O(k).
    ///
    /// # Arguments
    ///
    /// * `i` - Position of the bit to determine the rank for.
    pub fn rank_1(&self, i: u64) -> Option<u64> {
        if i >= self.n as u64 {
            None
        } else {
            let s = i / self.s as u64; // the superblock
            let b = i / 8; // the block
            let j = i % 8; // the bit in the block
                           // take the superblock rank
            let mut rank = self.superblocks_1[s as usize];
            // add the rank within the block
            let mask = ((2u16 << j) - 1) as u8;
            rank += (self.bits.get_block(b as usize) & mask).count_ones() as u64;
            // add the popcounts of blocks in between
            for block in s * 32 / 8..b {
                let b = self.bits.get_block(block as usize);
                rank += b.count_ones() as u64;
            }

            Some(rank)
        }
    }

    /// Get the 0-rank of a given bit, i.e. the number of 0-bits in the bitvector up to i (inclusive).
    /// Complexity: O(k).
    ///
    /// # Arguments
    ///
    /// * `i` - Position of the bit to determine the rank for.
    pub fn rank_0(&self, i: u64) -> Option<u64> {
        self.rank_1(i).map(|r| (i + 1) - r)
    }

    /// Alias for `RankSelect::rank_1`.
    pub fn rank(&self, i: u64) -> Option<u64> {
        self.rank_1(i)
    }

    /// Get the smallest bit with a given 1-rank.
    /// Complexity: O(log (n / k) + k).
    ///
    /// # Arguments
    ///
    /// * `j` - The rank to find the smallest bit for.
    pub fn select_1(&self, j: u64) -> Option<u64> {
        self.select_x(j, &self.superblocks_1, |bit| bit != 0)
    }

    /// Get the smallest bit with a given 0-rank.
    /// Complexity: O(log (n / k) + k).
    ///
    /// # Arguments
    ///
    /// * `j` - The rank to find the smallest bit for.
    pub fn select_0(&self, j: u64) -> Option<u64> {
        self.select_x(j, &self.superblocks_0, |bit| bit == 0)
    }

    fn select_x<F: Fn(u8) -> bool>(&self, j: u64, superblocks: &[u64], is_match: F) -> Option<u64> {
        let mut superblock = match superblocks.binary_search(&j) {
            Ok(i) | Err(i) => i, // superblock with same rank exists
        };
        if superblock > 0 {
            superblock -= 1;
        }
        let mut rank = superblocks[superblock];

        let first_block = superblock * self.s / 8;
        for block in first_block..cmp::min(first_block + self.s / 8, self.bits.block_len()) {
            let b = self.bits.get_block(block);
            let p = b.count_zeros() as u64;
            if rank + p >= j {
                let mut bit = 0b1;
                // do not look at unused bits of the last block
                let max_bit = cmp::min(8, self.bits.len() - block as u64 * 8);
                for i in 0..max_bit {
                    rank += is_match(b & bit) as u64;
                    if rank == j {
                        return Some((first_block + block) as u64 * 8 + i);
                    }
                    bit <<= 1;
                }
            }
            rank += p;
        }

        None
    }

    /// Alias for `RankSelect::select_1`.
    pub fn select(&self, j: u64) -> Option<u64> {
        self.select_1(j)
    }
}

/// Create `n` superblocks of size `s` from a given bitvector.
fn superblocks(t: bool, n: usize, s: usize, bits: &BitVec<u8>) -> Vec<u64> {
    let mut superblocks = Vec::with_capacity(n / s + 1);
    let mut rank: u64 = 0;
    let mut i = 0;
    let nblocks = (bits.len() as f64 / 8.0).ceil() as usize;
    for block in 0..nblocks {
        let b = bits.get_block(block);
        if i % s == 0 {
            superblocks.push(rank);
        }
        rank += if t {
            b.count_ones() as u64
        } else {
            b.count_zeros() as u64
        };
        i += 8;
    }

    superblocks
}

#[cfg(test)]
mod tests {
    use super::*;
    use bv::BitVec;
    use bv::BitsMut;

    #[test]
    fn test_rank_select() {
        let mut bits: BitVec<u8> = BitVec::new_fill(false, 64);
        bits.set_bit(5, true);
        bits.set_bit(32, true);
        let rs = RankSelect::new(bits, 1);
        assert_eq!(rs.rank_1(1).unwrap(), 0);
        assert_eq!(rs.rank_1(5).unwrap(), 1);
        assert_eq!(rs.rank_1(6).unwrap(), 1);
        assert_eq!(rs.rank_1(7).unwrap(), 1);
        assert_eq!(rs.rank_1(32).unwrap(), 2);
        assert_eq!(rs.rank_1(33).unwrap(), 2);
        assert_eq!(rs.rank_1(64), None);
        assert_eq!(rs.select_1(0).unwrap(), 0);
        assert_eq!(rs.select_1(1).unwrap(), 5);
        assert_eq!(rs.rank_0(1).unwrap(), 2);
        assert_eq!(rs.rank_0(4).unwrap(), 5);
        assert_eq!(rs.rank_0(5).unwrap(), 5);
        assert_eq!(rs.select_0(0), None);
        assert_eq!(rs.select_0(1).unwrap(), 0);
        assert_eq!(rs.get(5), true);
        assert_eq!(rs.get(1), false);
        assert_eq!(rs.get(32), true);
    }

    #[test]
    fn test_select() {
        let bits: BitVec<u8> = bit_vec![true, false];
        let rs = RankSelect::new(bits, 1);

        assert_eq!(rs.select_0(0), Some(0));
        assert_eq!(rs.select_1(0), None);

        assert_eq!(rs.select_0(1), Some(1));
        assert_eq!(rs.select_1(1), Some(0));

        assert_eq!(rs.select_0(2), None);
        assert_eq!(rs.select_1(2), None);
    }
}
<commit_msg>more tests, fix corner case<commit_after>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Rank/Select data structure based on Gonzalez, Grabowski, Mäkinen, Navarro (2005).
//! This implementation uses only a single level of blocks, and performs well for large n.
//!
//! Example
//!
//! ```
//! extern crate bv;
//! # extern crate bio;
//! # fn main() {
//! use bio::data_structures::rank_select::RankSelect;
//! use bv::BitVec;
//! use bv::BitsMut;
//!
//! let mut bits: BitVec<u8> = BitVec::new_fill(false, 64);
//! bits.set_bit(5, true);
//! bits.set_bit(32, true);
//! let rs = RankSelect::new(bits, 1);
//! assert!(rs.rank(6).unwrap() == 1);
//! # }
//! ```

use std::cmp;

use bv::BitVec;
use bv::Bits;

/// A rank/select data structure.
#[derive(Serialize, Deserialize)]
pub struct RankSelect {
    n: usize,
    bits: BitVec<u8>,
    superblocks_1: Vec<u64>,
    superblocks_0: Vec<u64>,
    s: usize,
    k: usize,
}

impl RankSelect {
    /// Create a new instance.
    ///
    /// # Arguments
    ///
    /// * `bits` - A bit vector.
    /// * `k` - Determines the size (k * 32 bits) of the superblocks.
    ///   A small k means faster rank query times at the expense of using more
    ///   space and slower select query times.
    ///   The data structure needs O(n + n log n / (k * 32)) bits with n being the bits of the given bitvector.
    ///   The data structure is succinct if k is chosen as a sublinear function of n
    ///   (e.g. k = (log n)² / 32).
    pub fn new(bits: BitVec<u8>, k: usize) -> RankSelect {
        let n = bits.len() as usize;
        let s = k * 32;

        RankSelect {
            n,
            s,
            k,
            superblocks_1: superblocks(true, n, s, &bits),
            superblocks_0: superblocks(false, n, s, &bits),
            bits,
        }
    }

    /// Return the used k (see `RankSelect::new()`).
    pub fn k(&self) -> usize {
        self.k
    }

    /// Get internal representation of bit vector.
    pub fn bits(&self) -> &BitVec<u8> {
        &self.bits
    }

    /// Return i-th bit.
    pub fn get(&self, i: u64) -> bool {
        self.bits.get_bit(i)
    }

    /// Get the 1-rank of a given bit, i.e. the number of 1-bits in the bitvector up to i (inclusive).
    /// Complexity: O(k).
    ///
    /// # Arguments
    ///
    /// * `i` - Position of the bit to determine the rank for.
    pub fn rank_1(&self, i: u64) -> Option<u64> {
        if i >= self.n as u64 {
            None
        } else {
            let s = i / self.s as u64; // the superblock
            let b = i / 8; // the block
            let j = i % 8; // the bit in the block
                           // take the superblock rank
            let mut rank = self.superblocks_1[s as usize];
            // add the rank within the block
            let mask = ((2u16 << j) - 1) as u8;
            rank += (self.bits.get_block(b as usize) & mask).count_ones() as u64;
            // add the popcounts of blocks in between
            for block in s * 32 / 8..b {
                let b = self.bits.get_block(block as usize);
                rank += b.count_ones() as u64;
            }

            Some(rank)
        }
    }

    /// Get the 0-rank of a given bit, i.e. the number of 0-bits in the bitvector up to i (inclusive).
    /// Complexity: O(k).
    ///
    /// # Arguments
    ///
    /// * `i` - Position of the bit to determine the rank for.
    pub fn rank_0(&self, i: u64) -> Option<u64> {
        self.rank_1(i).map(|r| (i + 1) - r)
    }

    /// Alias for `RankSelect::rank_1`.
    pub fn rank(&self, i: u64) -> Option<u64> {
        self.rank_1(i)
    }

    /// Get the smallest bit with a given 1-rank.
    /// Complexity: O(log (n / k) + k).
    ///
    /// # Arguments
    ///
    /// * `j` - The rank to find the smallest bit for.
    pub fn select_1(&self, j: u64) -> Option<u64> {
        self.select_x(
            j,
            &self.superblocks_1,
            |bit| bit != 0,
            |block| block.count_ones(),
        )
    }

    /// Get the smallest bit with a given 0-rank.
    /// Complexity: O(log (n / k) + k).
    ///
    /// # Arguments
    ///
    /// * `j` - The rank to find the smallest bit for.
    pub fn select_0(&self, j: u64) -> Option<u64> {
        self.select_x(
            j,
            &self.superblocks_0,
            |bit| bit == 0,
            |block| block.count_zeros(),
        )
    }

    fn select_x<F: Fn(u8) -> bool, C: Fn(u8) -> u32>(
        &self,
        j: u64,
        superblocks: &[u64],
        is_match: F,
        count_all: C,
    ) -> Option<u64> {
        let mut superblock = match superblocks.binary_search(&j) {
            Ok(i) | Err(i) => i, // superblock with same rank exists
        };
        if superblock > 0 {
            superblock -= 1;
        }
        let mut rank = superblocks[superblock];

        let first_block = superblock * self.s / 8;
        for block in first_block..cmp::min(first_block + self.s / 8, self.bits.block_len()) {
            let b = self.bits.get_block(block);
            let p = count_all(b) as u64;
            if rank + p >= j {
                let mut bit = 0b1;
                // do not look at unused bits of the last block
                let max_bit = cmp::min(8, self.bits.len() - block as u64 * 8);
                for i in 0..max_bit {
                    rank += is_match(b & bit) as u64;
                    if rank == j {
                        return Some((first_block + block) as u64 * 8 + i);
                    }
                    bit <<= 1;
                }
            }
            rank += p;
        }

        None
    }

    /// Alias for `RankSelect::select_1`.
    pub fn select(&self, j: u64) -> Option<u64> {
        self.select_1(j)
    }
}

/// Create `n` superblocks of size `s` from a given bitvector.
fn superblocks(t: bool, n: usize, s: usize, bits: &BitVec<u8>) -> Vec<u64> {
    let mut superblocks = Vec::with_capacity(n / s + 1);
    let mut rank: u64 = 0;
    let mut i = 0;
    let nblocks = (bits.len() as f64 / 8.0).ceil() as usize;
    for block in 0..nblocks {
        let b = bits.get_block(block);
        if i % s == 0 {
            superblocks.push(rank);
        }
        rank += if t {
            b.count_ones() as u64
        } else {
            b.count_zeros() as u64
        };
        i += 8;
    }

    superblocks
}

#[cfg(test)]
mod tests {
    use super::*;
    use bv::BitVec;
    use bv::BitsMut;

    #[test]
    fn test_rank_select() {
        let mut bits: BitVec<u8> = BitVec::new_fill(false, 64);
        bits.set_bit(5, true);
        bits.set_bit(32, true);
        let rs = RankSelect::new(bits, 1);
        assert_eq!(rs.rank_1(1).unwrap(), 0);
        assert_eq!(rs.rank_1(5).unwrap(), 1);
        assert_eq!(rs.rank_1(6).unwrap(), 1);
        assert_eq!(rs.rank_1(7).unwrap(), 1);
        assert_eq!(rs.rank_1(32).unwrap(), 2);
        assert_eq!(rs.rank_1(33).unwrap(), 2);
        assert_eq!(rs.rank_1(64), None);
        assert_eq!(rs.select_1(0).unwrap(), 0);
        assert_eq!(rs.select_1(1).unwrap(), 5);
        assert_eq!(rs.rank_0(1).unwrap(), 2);
        assert_eq!(rs.rank_0(4).unwrap(), 5);
        assert_eq!(rs.rank_0(5).unwrap(), 5);
        assert_eq!(rs.select_0(0), None);
        assert_eq!(rs.select_0(1).unwrap(), 0);
        assert_eq!(rs.get(5), true);
        assert_eq!(rs.get(1), false);
        assert_eq!(rs.get(32), true);
    }

    #[test]
    fn test_select() {
        let bits: BitVec<u8> = bit_vec![true, false];
        let rs = RankSelect::new(bits, 1);

        assert_eq!(rs.select_0(0), Some(0));
        assert_eq!(rs.select_1(0), None);

        assert_eq!(rs.select_0(1), Some(1));
        assert_eq!(rs.select_1(1), Some(0));

        assert_eq!(rs.select_0(2), None);
        assert_eq!(rs.select_1(2), None);
    }

    #[test]
    fn test_single_select() {
        let bits: BitVec<u8> = bit_vec![true];
        let rs = RankSelect::new(bits, 1);
        assert_eq!(rs.select_1(0), None);
        assert_eq!(rs.select_1(1), Some(0));
        assert_eq!(rs.select_0(0), Some(0));
        assert_eq!(rs.select_0(1), None);

        let bits: BitVec<u8> = bit_vec![false];
        let rs = RankSelect::new(bits, 1);
        assert_eq!(rs.select_1(1), None);
        assert_eq!(rs.select_1(0), Some(0));
        assert_eq!(rs.select_0(0), None);
        assert_eq!(rs.select_0(1), Some(0));
        assert_eq!(rs.rank_0(0), Some(1));
        assert_eq!(rs.rank_1(0), Some(0));
    }
}
<|endoftext|>


<commit_before>// TODO: Make -w flag work with decimals
// TODO: Support -f flag

// spell-checker:ignore (ToDO) istr chiter argptr ilen

#[macro_use]
extern crate uucore;

use clap::{App, AppSettings, Arg};
use num_bigint::BigInt;
use num_traits::One;
use num_traits::Zero;
use num_traits::{Num, ToPrimitive};
use std::cmp;
use std::io::{stdout, Write};
use std::str::FromStr;

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT.";
static OPT_SEPARATOR: &str = "separator";
static OPT_TERMINATOR: &str = "terminator";
static OPT_WIDTHS: &str = "widths";

static ARG_NUMBERS: &str = "numbers";

fn get_usage() -> String {
    format!(
        "{0} [OPTION]... LAST
    {0} [OPTION]... FIRST LAST
    {0} [OPTION]... FIRST INCREMENT LAST",
        executable!()
    )
}
#[derive(Clone)]
struct SeqOptions {
    separator: String,
    terminator: Option<String>,
    widths: bool,
}

enum Number {
    BigInt(BigInt),
    F64(f64),
}

impl Number {
    fn is_zero(&self) -> bool {
        match self {
            Number::BigInt(n) => n.is_zero(),
            Number::F64(n) => n.is_zero(),
        }
    }

    fn into_f64(self) -> f64 {
        match self {
            // BigInt::to_f64() can not return None.
            Number::BigInt(n) => n.to_f64().unwrap(),
            Number::F64(n) => n,
        }
    }
}

impl FromStr for Number {
    type Err = String;
    /// Tries to parse this string as a BigInt, or if that fails as an f64.
    fn from_str(mut s: &str) -> Result<Self, Self::Err> {
        if s.starts_with('+') {
            s = &s[1..];
        }

        match s.parse::<BigInt>() {
            Ok(n) => Ok(Number::BigInt(n)),
            Err(_) => match s.parse::<f64>() {
                Ok(n) => Ok(Number::F64(n)),
                Err(e) => Err(format!(
                    "seq: invalid floating point argument `{}`: {}",
                    s, e
                )),
            },
        }
    }
}

fn escape_sequences(s: &str) -> String {
    s.replace("\\n", "\n").replace("\\t", "\t")
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = get_usage();
    let matches = App::new(executable!())
        .setting(AppSettings::AllowLeadingHyphen)
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .arg(
            Arg::with_name(OPT_SEPARATOR)
                .short("s")
                .long("separator")
                .help("Separator character (defaults to \\n)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_TERMINATOR)
                .short("t")
                .long("terminator")
                .help("Terminator character (defaults to separator)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_WIDTHS)
                .short("w")
                .long("widths")
                .help("Equalize widths of all numbers by padding with zeros"),
        )
        .arg(
            Arg::with_name(ARG_NUMBERS)
                .multiple(true)
                .takes_value(true)
                .allow_hyphen_values(true)
                .max_values(3),
        )
        .get_matches_from(args);

    let numbers = matches.values_of(ARG_NUMBERS).unwrap().collect::<Vec<_>>();

    let mut options = SeqOptions {
        separator: "\n".to_owned(),
        terminator: None,
        widths: false,
    };
    options.separator = matches.value_of(OPT_SEPARATOR).unwrap_or("\n").to_string();
    options.terminator = matches.value_of(OPT_TERMINATOR).map(String::from);
    options.widths = matches.is_present(OPT_WIDTHS);

    let mut largest_dec = 0;
    let mut padding = 0;
    let first = if numbers.len() > 1 {
        let slice = numbers[0];
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = len - dec;
        padding = dec;
        match slice.parse() {
            Ok(n) => n,
            Err(s) => {
                show_error!("{}", s);
                return 1;
            }
        }
    } else {
        Number::BigInt(BigInt::one())
    };
    let increment = if numbers.len() > 2 {
        let slice = numbers[1];
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = cmp::max(largest_dec, len - dec);
        padding = cmp::max(padding, dec);
        match slice.parse() {
            Ok(n) => n,
            Err(s) => {
                show_error!("{}", s);
                return 1;
            }
        }
    } else {
        Number::BigInt(BigInt::one())
    };
    if increment.is_zero() {
        show_error!("increment value: '{}'", numbers[1]);
        return 1;
    }
    let last = {
        let slice = numbers[numbers.len() - 1];
        padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len()));
        match slice.parse::<Number>() {
            Ok(n) => n,
            Err(s) => {
                show_error!("{}", s);
                return 1;
            }
        }
    };
    if largest_dec > 0 {
        largest_dec -= 1;
    }
    let separator = escape_sequences(&options.separator[..]);
    let terminator = match options.terminator {
        Some(term) => escape_sequences(&term[..]),
        None => separator.clone(),
    };

    match (first, last, increment) {
        (Number::BigInt(first), Number::BigInt(last), Number::BigInt(increment)) => {
            print_seq_integers(
                first,
                increment,
                last,
                separator,
                terminator,
                options.widths,
                padding,
            )
        }
        (first, last, increment) => print_seq(
            first.into_f64(),
            increment.into_f64(),
            last.into_f64(),
            largest_dec,
            separator,
            terminator,
            options.widths,
            padding,
        ),
    }
    0
}

fn done_printing<T: Num + PartialOrd>(next: &T, increment: &T, last: &T) -> bool {
    if increment >= &T::zero() {
        next > last
    } else {
        next < last
    }
}

/// Floating point based code path
#[allow(clippy::too_many_arguments)]
fn print_seq(
    first: f64,
    increment: f64,
    last: f64,
    largest_dec: usize,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
) {
    let mut i = 0isize;
    let mut value = first + i as f64 * increment;
    while !done_printing(&value, &increment, &last) {
        let istr = format!("{:.*}", largest_dec, value);
        let ilen = istr.len();
        let before_dec = istr.find('.').unwrap_or(ilen);
        if pad && before_dec < padding {
            for _ in 0..(padding - before_dec) {
                print!("0");
            }
        }
        print!("{}", istr);
        i += 1;
        value = first + i as f64 * increment;
        if !done_printing(&value, &increment, &last) {
            print!("{}", separator);
        }
    }
    if (first >= last && increment < 0f64) || (first <= last && increment > 0f64) {
        print!("{}", terminator);
    }
    crash_if_err!(1, stdout().flush());
}

/// BigInt based code path
fn print_seq_integers(
    first: BigInt,
    increment: BigInt,
    last: BigInt,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
) {
    let mut value = first;
    let mut is_first_iteration = true;
    while !done_printing(&value, &increment, &last) {
        if !is_first_iteration {
            print!("{}", separator);
        }
        is_first_iteration = false;
        if pad {
            print!("{number:>0width$}", number = value, width = padding);
        } else {
            print!("{}", value);
        }
        value += &increment;
    }

    if !is_first_iteration {
        print!("{}", terminator);
    }
}
<commit_msg>seq: make arguments required<commit_after>// TODO: Make -w flag work with decimals
// TODO: Support -f flag

// spell-checker:ignore (ToDO) istr chiter argptr ilen

#[macro_use]
extern crate uucore;

use clap::{App, AppSettings, Arg};
use num_bigint::BigInt;
use num_traits::One;
use num_traits::Zero;
use num_traits::{Num, ToPrimitive};
use std::cmp;
use std::io::{stdout, Write};
use std::str::FromStr;

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT.";
static OPT_SEPARATOR: &str = "separator";
static OPT_TERMINATOR: &str = "terminator";
static OPT_WIDTHS: &str = "widths";

static ARG_NUMBERS: &str = "numbers";

fn get_usage() -> String {
    format!(
        "{0} [OPTION]... LAST
    {0} [OPTION]... FIRST LAST
    {0} [OPTION]... FIRST INCREMENT LAST",
        executable!()
    )
}
#[derive(Clone)]
struct SeqOptions {
    separator: String,
    terminator: Option<String>,
    widths: bool,
}

enum Number {
    BigInt(BigInt),
    F64(f64),
}

impl Number {
    fn is_zero(&self) -> bool {
        match self {
            Number::BigInt(n) => n.is_zero(),
            Number::F64(n) => n.is_zero(),
        }
    }

    fn into_f64(self) -> f64 {
        match self {
            // BigInt::to_f64() can not return None.
            Number::BigInt(n) => n.to_f64().unwrap(),
            Number::F64(n) => n,
        }
    }
}

impl FromStr for Number {
    type Err = String;
    /// Tries to parse this string as a BigInt, or if that fails as an f64.
    fn from_str(mut s: &str) -> Result<Self, Self::Err> {
        if s.starts_with('+') {
            s = &s[1..];
        }

        match s.parse::<BigInt>() {
            Ok(n) => Ok(Number::BigInt(n)),
            Err(_) => match s.parse::<f64>() {
                Ok(n) => Ok(Number::F64(n)),
                Err(e) => Err(format!(
                    "seq: invalid floating point argument `{}`: {}",
                    s, e
                )),
            },
        }
    }
}

fn escape_sequences(s: &str) -> String {
    s.replace("\\n", "\n").replace("\\t", "\t")
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let usage = get_usage();
    let matches = App::new(executable!())
        .setting(AppSettings::AllowLeadingHyphen)
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .arg(
            Arg::with_name(OPT_SEPARATOR)
                .short("s")
                .long("separator")
                .help("Separator character (defaults to \\n)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_TERMINATOR)
                .short("t")
                .long("terminator")
                .help("Terminator character (defaults to separator)")
                .takes_value(true)
                .number_of_values(1),
        )
        .arg(
            Arg::with_name(OPT_WIDTHS)
                .short("w")
                .long("widths")
                .help("Equalize widths of all numbers by padding with zeros"),
        )
        .arg(
            Arg::with_name(ARG_NUMBERS)
                .multiple(true)
                .takes_value(true)
                .allow_hyphen_values(true)
                .max_values(3)
                .required(true),
        )
        .get_matches_from(args);

    let numbers = matches.values_of(ARG_NUMBERS).unwrap().collect::<Vec<_>>();

    let mut options = SeqOptions {
        separator: "\n".to_owned(),
        terminator: None,
        widths: false,
    };
    options.separator = matches.value_of(OPT_SEPARATOR).unwrap_or("\n").to_string();
    options.terminator = matches.value_of(OPT_TERMINATOR).map(String::from);
    options.widths = matches.is_present(OPT_WIDTHS);

    let mut largest_dec = 0;
    let mut padding = 0;
    let first = if numbers.len() > 1 {
        let slice = numbers[0];
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = len - dec;
        padding = dec;
        match slice.parse() {
            Ok(n) => n,
            Err(s) => {
                show_error!("{}", s);
                return 1;
            }
        }
    } else {
        Number::BigInt(BigInt::one())
    };
    let increment = if numbers.len() > 2 {
        let slice = numbers[1];
        let len = slice.len();
        let dec = slice.find('.').unwrap_or(len);
        largest_dec = cmp::max(largest_dec, len - dec);
        padding = cmp::max(padding, dec);
        match slice.parse() {
            Ok(n) => n,
            Err(s) => {
                show_error!("{}", s);
                return 1;
            }
        }
    } else {
        Number::BigInt(BigInt::one())
    };
    if increment.is_zero() {
        show_error!("increment value: '{}'", numbers[1]);
        return 1;
    }
    let last = {
        let slice = numbers[numbers.len() - 1];
        padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len()));
        match slice.parse::<Number>() {
            Ok(n) => n,
            Err(s) => {
                show_error!("{}", s);
                return 1;
            }
        }
    };
    if largest_dec > 0 {
        largest_dec -= 1;
    }
    let separator = escape_sequences(&options.separator[..]);
    let terminator = match options.terminator {
        Some(term) => escape_sequences(&term[..]),
        None => separator.clone(),
    };

    match (first, last, increment) {
        (Number::BigInt(first), Number::BigInt(last), Number::BigInt(increment)) => {
            print_seq_integers(
                first,
                increment,
                last,
                separator,
                terminator,
                options.widths,
                padding,
            )
        }
        (first, last, increment) => print_seq(
            first.into_f64(),
            increment.into_f64(),
            last.into_f64(),
            largest_dec,
            separator,
            terminator,
            options.widths,
            padding,
        ),
    }
    0
}

fn done_printing<T: Num + PartialOrd>(next: &T, increment: &T, last: &T) -> bool {
    if increment >= &T::zero() {
        next > last
    } else {
        next < last
    }
}

/// Floating point based code path
#[allow(clippy::too_many_arguments)]
fn print_seq(
    first: f64,
    increment: f64,
    last: f64,
    largest_dec: usize,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
) {
    let mut i = 0isize;
    let mut value = first + i as f64 * increment;
    while !done_printing(&value, &increment, &last) {
        let istr = format!("{:.*}", largest_dec, value);
        let ilen = istr.len();
        let before_dec = istr.find('.').unwrap_or(ilen);
        if pad && before_dec < padding {
            for _ in 0..(padding - before_dec) {
                print!("0");
            }
        }
        print!("{}", istr);
        i += 1;
        value = first + i as f64 * increment;
        if !done_printing(&value, &increment, &last) {
            print!("{}", separator);
        }
    }
    if (first >= last && increment < 0f64) || (first <= last && increment > 0f64) {
        print!("{}", terminator);
    }
    crash_if_err!(1, stdout().flush());
}

/// BigInt based code path
fn print_seq_integers(
    first: BigInt,
    increment: BigInt,
    last: BigInt,
    separator: String,
    terminator: String,
    pad: bool,
    padding: usize,
) {
    let mut value = first;
    let mut is_first_iteration = true;
    while !done_printing(&value, &increment, &last) {
        if !is_first_iteration {
            print!("{}", separator);
        }
        is_first_iteration = false;
        if pad {
            print!("{number:>0width$}", number = value, width = padding);
        } else {
            print!("{}", value);
        }
        value += &increment;
    }

    if !is_first_iteration {
        print!("{}", terminator);
    }
}
<|endoftext|>


<commit_before>use std::cmp;
use rand::Rng;
use rand::distributions::{Sample, IndependentSample};
use function::factorial;
use statistics::*;
use distribution::{Univariate, Discrete, Distribution};
use {Result, StatsError};

/// Implements the [Hypergeometric](http://en.wikipedia.org/wiki/Hypergeometric_distribution)
/// distribution
///
/// # Examples
///
/// ```
/// ```
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Hypergeometric {
    population: u64,
    successes: u64,
    draws: u64,
}

impl Hypergeometric {
    /// Constructs a new hypergeometric distribution
    /// with a population (N) of `population`, number
    /// of successes (K) of `successes`, and number of draws
    /// (n) of `draws`
    ///
    /// # Errors
    ///
    /// If `successes > population` or `draws > population`
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let mut result = Hypergeometric::new(2, 2, 2);
    /// assert!(result.is_ok());
    ///
    /// result = Hypergeometric::new(2, 3, 2);
    /// assert!(result.is_err());
    /// ```
    pub fn new(population: u64, successes: u64, draws: u64) -> Result<Hypergeometric> {
        if successes > population || draws > population {
            Err(StatsError::BadParams)
        } else {
            Ok(Hypergeometric {
                population: population,
                successes: successes,
                draws: draws,
            })
        }
    }

    /// Returns the population size of the hypergeometric
    /// distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// assert_eq!(n.population(), 10);
    /// ```
    pub fn population(&self) -> u64 {
        self.population
    }

    /// Returns the number of observed successes of the hypergeometric
    /// distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// assert_eq!(n.successes(), 5);
    /// ```
    pub fn successes(&self) -> u64 {
        self.successes
    }

    /// Returns the number of draws of the hypergeometric
    /// distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// assert_eq!(n.draws(), 3);
    /// ```
    pub fn draws(&self) -> u64 {
        self.draws
    }
}

impl Sample<f64> for Hypergeometric {
    /// Generate a random sample from a hypergeometric
    /// distribution using `r` as the source of randomness.
    /// Refer [here](#method.sample-1) for implementation details
    fn sample<R: Rng>(&mut self, r: &mut R) -> f64 {
        super::Distribution::sample(self, r)
    }
}

impl IndependentSample<f64> for Hypergeometric {
    /// Generate a random independent sample from a hypergeometric
    /// distribution using `r` as the source of randomness.
    /// Refer [here](#method.sample-1) for implementation details
    fn ind_sample<R: Rng>(&self, r: &mut R) -> f64 {
        super::Distribution::sample(self, r)
    }
}

impl Distribution<f64> for Hypergeometric {
    /// Generates a random sample from the hypergeometric distribution
    /// using `r` as the source of randomness
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate rand;
    /// # extern crate statrs;
    /// use rand::StdRng;
    /// use statrs::distribution::{Hypergeometric, Distribution};
    ///
    /// # fn main() {
    /// let mut r = rand::StdRng::new().unwrap();
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// print!("{}", n.sample::<StdRng>(&mut r));
    /// # }
    /// ```
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        let mut population = self.population as f64;
        let mut successes = self.successes as f64;
        let mut draws = self.draws;
        let mut x = 0.0;
        loop {
            let p = successes / population;
            let next = r.next_f64();
            if next < p {
                x += 1.0;
                successes -= 1.0;
            }
            population -= 1.0;
            draws -= 1;
            if draws == 0 {
                break;
            }
        }
        x
    }
}

impl Univariate<u64, f64> for Hypergeometric {
    /// Calculates the cumulative distribution function for the hypergeometric
    /// distribution at `x`
    ///
    /// # Panics
    ///
    /// If `x < n + K - N` or `x >= min(K, n)`
    ///
    /// # Formula
    ///
    /// ```ignore
    /// TODO
    /// ```
    fn cdf(&self, x: f64) -> f64 {
        assert!(x >= self.min() as f64,
                format!("{}", StatsError::ArgGteArg("x", "n + K - N")));
        assert!(x < self.max() as f64,
                format!("{}", StatsError::ArgLtArg("x", "min(K, n)")));
        let k = x.floor() as u64;
        let ln_denom = factorial::ln_binomial(self.population, self.draws);
        (0..k + 1).fold(0.0, |acc, i| {
            acc +
            (factorial::ln_binomial(self.successes, i) +
             factorial::ln_binomial(self.population - self.successes, self.draws - i) -
             ln_denom)
                .exp()
        })
    }
}

impl Min<u64> for Hypergeometric {
    /// Returns the minimum value in the domain of the
    /// hypergeometric distribution representable by a 64-bit
    /// integer
    ///
    /// # Formula
    ///
    /// ```ignore
    /// 1 -
    /// ```
    fn min(&self) -> u64 {
        (self.draws + self.successes).saturating_sub(self.population)
    }
}

impl Max<u64> for Hypergeometric {
    /// Returns the maximum value in the domain of the
    /// hypergeometric distribution representable by a 64-bit
    /// integer
    ///
    /// # Formula
    ///
    /// ```ignore
    /// 2^63 - 1
    /// ```
    fn max(&self) -> u64 {
        cmp::min(self.successes, self.draws)
    }
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[cfg(test)]
mod test {
    use std::fmt::Debug;
    use statistics::*;
    use distribution::{Univariate, Discrete, Hypergeometric};

    fn try_create(population: u64, successes: u64, draws: u64) -> Hypergeometric {
        let n = Hypergeometric::new(population, successes, draws);
        assert!(n.is_ok());
        n.unwrap()
    }

    fn create_case(population: u64, successes: u64, draws: u64) {
        let n = try_create(population, successes, draws);
        assert_eq!(population, n.population());
        assert_eq!(successes, n.successes());
        assert_eq!(draws, n.draws());
    }

    fn bad_create_case(population: u64, successes: u64, draws: u64) {
        let n = Hypergeometric::new(population, successes, draws);
        assert!(n.is_err());
    }

    fn get_value<T, F>(population: u64, successes: u64, draws: u64, eval: F) -> T
        where T: PartialEq + Debug,
              F: Fn(Hypergeometric) -> T
    {
        let n = try_create(population, successes, draws);
        eval(n)
    }

    fn test_case<T, F>(population: u64, successes: u64, draws: u64, expected: T, eval: F)
        where T: PartialEq + Debug,
              F: Fn(Hypergeometric) -> T
    {
        let x = get_value(population, successes, draws, eval);
        assert_eq!(expected, x);
    }

    fn test_almost<F>(population: u64, successes: u64, draws: u64, expected: f64, acc: f64, eval: F)
        where F: Fn(Hypergeometric) -> f64
    {
        let x = get_value(population, successes, draws, eval);
        assert_almost_eq!(expected, x, acc);
    }

    #[test]
    fn test_create() {
        create_case(0, 0, 0);
        create_case(1, 1, 1,);
        create_case(2, 1, 1);
        create_case(2, 2, 2);
        create_case(10, 1, 1);
        create_case(10, 5, 3);
    }

    #[test]
    fn test_bad_create() {
        bad_create_case(2, 3, 2);
        bad_create_case(10, 5, 20);
        bad_create_case(0, 1, 1);
    }

    #[test]
    fn test_min() {
        test_case(0, 0, 0, 0, |x| x.min());
        test_case(1, 1, 1, 1, |x| x.min());
        test_case(2, 1, 1, 0, |x| x.min());
        test_case(2, 2, 2, 2, |x| x.min());
        test_case(10, 1, 1, 0, |x| x.min());
        test_case(10, 5, 3, 0, |x| x.min());
    }

    #[test]
    fn test_max() {
        test_case(0, 0, 0, 0, |x| x.max());
        test_case(1, 1, 1, 1, |x| x.max());
        test_case(2, 1, 1, 1, |x| x.max());
        test_case(2, 2, 2, 2, |x| x.max());
        test_case(10, 1, 1, 1, |x| x.max());
        test_case(10, 5, 3, 3, |x| x.max());
    }

    #[test]
    fn test_cdf() {
        test_case(2, 1, 1, 0.5, |x| x.cdf(0.3));
        test_almost(10, 1, 1, 0.9, 1e-14, |x| x.cdf(0.3));
        test_almost(10, 5, 3, 0.5, 1e-15, |x| x.cdf(1.1));
        test_almost(10, 5, 3, 11.0 / 12.0, 1e-14, |x| x.cdf(2.0));
        test_almost(10000, 2, 9800, 199.0 / 499950.0, 1e-14, |x| x.cdf(0.0));
        test_almost(10000, 2, 9800, 199.0 / 499950.0, 1e-14, |x| x.cdf(0.5));
        test_almost(10000, 2, 9800, 19799.0 / 499950.0, 1e-12, |x| x.cdf(1.5));
    }

    #[test]
    #[should_panic]
    fn test_cdf_arg_too_big() {
        get_value(0, 0, 0, |x| x.cdf(0.5));
    }

    #[test]
    #[should_panic]
    fn test_cdf_arg_too_small() {
        get_value(2, 2, 2, |x| x.cdf(0.0));
    }
}<commit_msg>wip: impl and test hypergeo mean<commit_after>use std::cmp;
use std::f64;
use rand::Rng;
use rand::distributions::{Sample, IndependentSample};
use function::factorial;
use statistics::*;
use distribution::{Univariate, Discrete, Distribution};
use {Result, StatsError};

/// Implements the [Hypergeometric](http://en.wikipedia.org/wiki/Hypergeometric_distribution)
/// distribution
///
/// # Examples
///
/// ```
/// ```
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Hypergeometric {
    population: u64,
    successes: u64,
    draws: u64,
}

impl Hypergeometric {
    /// Constructs a new hypergeometric distribution
    /// with a population (N) of `population`, number
    /// of successes (K) of `successes`, and number of draws
    /// (n) of `draws`
    ///
    /// # Errors
    ///
    /// If `successes > population` or `draws > population`
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let mut result = Hypergeometric::new(2, 2, 2);
    /// assert!(result.is_ok());
    ///
    /// result = Hypergeometric::new(2, 3, 2);
    /// assert!(result.is_err());
    /// ```
    pub fn new(population: u64, successes: u64, draws: u64) -> Result<Hypergeometric> {
        if successes > population || draws > population {
            Err(StatsError::BadParams)
        } else {
            Ok(Hypergeometric {
                population: population,
                successes: successes,
                draws: draws,
            })
        }
    }

    /// Returns the population size of the hypergeometric
    /// distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// assert_eq!(n.population(), 10);
    /// ```
    pub fn population(&self) -> u64 {
        self.population
    }

    /// Returns the number of observed successes of the hypergeometric
    /// distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// assert_eq!(n.successes(), 5);
    /// ```
    pub fn successes(&self) -> u64 {
        self.successes
    }

    /// Returns the number of draws of the hypergeometric
    /// distribution
    ///
    /// # Examples
    ///
    /// ```
    /// use statrs::distribution::Hypergeometric;
    ///
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// assert_eq!(n.draws(), 3);
    /// ```
    pub fn draws(&self) -> u64 {
        self.draws
    }
}

impl Sample<f64> for Hypergeometric {
    /// Generate a random sample from a hypergeometric
    /// distribution using `r` as the source of randomness.
    /// Refer [here](#method.sample-1) for implementation details
    fn sample<R: Rng>(&mut self, r: &mut R) -> f64 {
        super::Distribution::sample(self, r)
    }
}

impl IndependentSample<f64> for Hypergeometric {
    /// Generate a random independent sample from a hypergeometric
    /// distribution using `r` as the source of randomness.
    /// Refer [here](#method.sample-1) for implementation details
    fn ind_sample<R: Rng>(&self, r: &mut R) -> f64 {
        super::Distribution::sample(self, r)
    }
}

impl Distribution<f64> for Hypergeometric {
    /// Generates a random sample from the hypergeometric distribution
    /// using `r` as the source of randomness
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate rand;
    /// # extern crate statrs;
    /// use rand::StdRng;
    /// use statrs::distribution::{Hypergeometric, Distribution};
    ///
    /// # fn main() {
    /// let mut r = rand::StdRng::new().unwrap();
    /// let n = Hypergeometric::new(10, 5, 3).unwrap();
    /// print!("{}", n.sample::<StdRng>(&mut r));
    /// # }
    /// ```
    fn sample<R: Rng>(&self, r: &mut R) -> f64 {
        let mut population = self.population as f64;
        let mut successes = self.successes as f64;
        let mut draws = self.draws;
        let mut x = 0.0;
        loop {
            let p = successes / population;
            let next = r.next_f64();
            if next < p {
                x += 1.0;
                successes -= 1.0;
            }
            population -= 1.0;
            draws -= 1;
            if draws == 0 {
                break;
            }
        }
        x
    }
}

impl Univariate<u64, f64> for Hypergeometric {
    /// Calculates the cumulative distribution function for the hypergeometric
    /// distribution at `x`
    ///
    /// # Panics
    ///
    /// If `x < n + K - N` or `x >= min(K, n)`
    ///
    /// # Formula
    ///
    /// ```ignore
    /// TODO
    /// ```
    fn cdf(&self, x: f64) -> f64 {
        assert!(x >= self.min() as f64,
                format!("{}", StatsError::ArgGteArg("x", "n + K - N")));
        assert!(x < self.max() as f64,
                format!("{}", StatsError::ArgLtArg("x", "min(K, n)")));
        let k = x.floor() as u64;
        let ln_denom = factorial::ln_binomial(self.population, self.draws);
        (0..k + 1).fold(0.0, |acc, i| {
            acc +
            (factorial::ln_binomial(self.successes, i) +
             factorial::ln_binomial(self.population - self.successes, self.draws - i) -
             ln_denom)
                .exp()
        })
    }
}

impl Min<u64> for Hypergeometric {
    /// Returns the minimum value in the domain of the
    /// hypergeometric distribution representable by a 64-bit
    /// integer
    ///
    /// # Formula
    ///
    /// ```ignore
    /// max(0, n + K - N)
    /// ```
    ///
    /// where `N` is population, `K` is successes, and `n` is draws
    fn min(&self) -> u64 {
        (self.draws + self.successes).saturating_sub(self.population)
    }
}

impl Max<u64> for Hypergeometric {
    /// Returns the maximum value in the domain of the
    /// hypergeometric distribution representable by a 64-bit
    /// integer
    ///
    /// # Formula
    ///
    /// ```ignore
    /// min(K, n)
    /// ```
    ///
    /// where `K` is successes and `n` is draws
    fn max(&self) -> u64 {
        cmp::min(self.successes, self.draws)
    }
}

impl Mean<f64> for Hypergeometric {
    /// Returns the mean of the hypergeometric distribution
    ///
    /// # Remarks
    ///
    /// Returns `INF` if `N` is `0`
    ///
    /// # Formula
    ///
    /// ```ignore
    /// K * n / N
    /// ```
    ///
    /// where `N` is population, `K` is successes, and `n` is draws
    fn mean(&self) -> f64 {
        if self.population == 0 {
            return f64::INFINITY;
        }
        self.successes as f64 * self.draws as f64 / self.population as f64
    }
}

#[cfg_attr(rustfmt, rustfmt_skip)]
#[cfg(test)]
mod test {
    use std::f64;
    use std::fmt::Debug;
    use statistics::*;
    use distribution::{Univariate, Discrete, Hypergeometric};

    fn try_create(population: u64, successes: u64, draws: u64) -> Hypergeometric {
        let n = Hypergeometric::new(population, successes, draws);
        assert!(n.is_ok());
        n.unwrap()
    }

    fn create_case(population: u64, successes: u64, draws: u64) {
        let n = try_create(population, successes, draws);
        assert_eq!(population, n.population());
        assert_eq!(successes, n.successes());
        assert_eq!(draws, n.draws());
    }

    fn bad_create_case(population: u64, successes: u64, draws: u64) {
        let n = Hypergeometric::new(population, successes, draws);
        assert!(n.is_err());
    }

    fn get_value<T, F>(population: u64, successes: u64, draws: u64, eval: F) -> T
        where T: PartialEq + Debug,
              F: Fn(Hypergeometric) -> T
    {
        let n = try_create(population, successes, draws);
        eval(n)
    }

    fn test_case<T, F>(population: u64, successes: u64, draws: u64, expected: T, eval: F)
        where T: PartialEq + Debug,
              F: Fn(Hypergeometric) -> T
    {
        let x = get_value(population, successes, draws, eval);
        assert_eq!(expected, x);
    }

    fn test_almost<F>(population: u64, successes: u64, draws: u64, expected: f64, acc: f64, eval: F)
        where F: Fn(Hypergeometric) -> f64
    {
        let x = get_value(population, successes, draws, eval);
        assert_almost_eq!(expected, x, acc);
    }

    #[test]
    fn test_create() {
        create_case(0, 0, 0);
        create_case(1, 1, 1,);
        create_case(2, 1, 1);
        create_case(2, 2, 2);
        create_case(10, 1, 1);
        create_case(10, 5, 3);
    }

    #[test]
    fn test_bad_create() {
        bad_create_case(2, 3, 2);
        bad_create_case(10, 5, 20);
        bad_create_case(0, 1, 1);
    }

    #[test]
    fn test_mean() {
        test_case(0, 0, 0, f64::INFINITY, |x| x.mean());
        test_case(1, 1, 1, 1.0, |x| x.mean());
        test_case(2, 1, 1, 0.5, |x| x.mean());
        test_case(2, 2, 2, 2.0, |x| x.mean());
        test_case(10, 1, 1, 0.1, |x| x.mean());
        test_case(10, 5, 3, 15.0 / 10.0, |x| x.mean());
    }

    #[test]
    fn test_min() {
        test_case(0, 0, 0, 0, |x| x.min());
        test_case(1, 1, 1, 1, |x| x.min());
        test_case(2, 1, 1, 0, |x| x.min());
        test_case(2, 2, 2, 2, |x| x.min());
        test_case(10, 1, 1, 0, |x| x.min());
        test_case(10, 5, 3, 0, |x| x.min());
    }

    #[test]
    fn test_max() {
        test_case(0, 0, 0, 0, |x| x.max());
        test_case(1, 1, 1, 1, |x| x.max());
        test_case(2, 1, 1, 1, |x| x.max());
        test_case(2, 2, 2, 2, |x| x.max());
        test_case(10, 1, 1, 1, |x| x.max());
        test_case(10, 5, 3, 3, |x| x.max());
    }

    #[test]
    fn test_cdf() {
        test_case(2, 1, 1, 0.5, |x| x.cdf(0.3));
        test_almost(10, 1, 1, 0.9, 1e-14, |x| x.cdf(0.3));
        test_almost(10, 5, 3, 0.5, 1e-15, |x| x.cdf(1.1));
        test_almost(10, 5, 3, 11.0 / 12.0, 1e-14, |x| x.cdf(2.0));
        test_almost(10000, 2, 9800, 199.0 / 499950.0, 1e-14, |x| x.cdf(0.0));
        test_almost(10000, 2, 9800, 199.0 / 499950.0, 1e-14, |x| x.cdf(0.5));
        test_almost(10000, 2, 9800, 19799.0 / 499950.0, 1e-12, |x| x.cdf(1.5));
    }

    #[test]
    #[should_panic]
    fn test_cdf_arg_too_big() {
        get_value(0, 0, 0, |x| x.cdf(0.5));
    }

    #[test]
    #[should_panic]
    fn test_cdf_arg_too_small() {
        get_value(2, 2, 2, |x| x.cdf(0.0));
    }
}<|endoftext|>


<commit_before>//! `Definitions` node and its children.

use fnv::FnvHashMap;
use parser::binary::{Parser, ParserSource, Attributes};
use loader::binary::simple::{Result, Error};
use loader::binary::simple::fbx7400::Properties70;

/// `Definitions` node.
#[derive(Debug, Clone, PartialEq)]
pub struct Definitions {
    /// Version of the node.
    pub version: i32,
    /// Reference count?
    pub count: i32,
    /// Property templates for object types.
    pub object_types: Vec<ObjectType>,
}

impl Definitions {
    /// Loads node contents from the parser.
    pub fn load<R, P>(mut parser: P) -> Result<Self>
    where
        R: ParserSource,
        P: Parser<R>,
    {
        let mut version = None;
        let mut count = None;
        let mut object_types = Vec::new();

        loop {
            let node_type = try_get_node_attrs!(parser, DefinitionsChildAttrs::load);
            match node_type {
                DefinitionsChildAttrs::Version(v) => {
                    version = Some(v);
                    parser.skip_current_node()?;
                },
                DefinitionsChildAttrs::Count(v) => {
                    count = Some(v);
                    parser.skip_current_node()?;
                },
                DefinitionsChildAttrs::ObjectType(attrs) => {
                    object_types.push(ObjectType::load(parser.subtree_parser(), attrs)?);
                },
            }
        }
        Ok(Definitions {
            version: ensure_node_exists!(version, "Definitions", "Version"),
            count: ensure_node_exists!(count, "Definitions", "Count"),
            object_types: object_types,
        })
    }
}

child_attr_loader! { DefinitionsChildAttrs {
    "Count" => Count(i32),
    "Version" => Version(i32),
    "ObjectType" => ObjectType(String),
}}

/// An object type and property template for it.
#[derive(Debug, Clone, PartialEq)]
pub struct ObjectType {
    /// Target object type.
    pub object_type: String,
    /// Reference count?
    pub count: i32,
    /// Property templates.
    pub property_template: FnvHashMap<String, Properties70>,
}

impl ObjectType {
    /// Loads node contents from the parser.
    pub fn load<R, P>(mut parser: P, attrs: String) -> Result<Self>
    where
        R: ParserSource,
        P: Parser<R>,
    {
        let mut count = None;
        let mut property_template = FnvHashMap::default();

        loop {
            let node_type = try_get_node_attrs!(parser, ObjectTypeChildAttrs::load);
            match node_type {
                ObjectTypeChildAttrs::Count(v) => {
                    count = Some(v);
                    parser.skip_current_node()?;
                },
                ObjectTypeChildAttrs::PropertyTemplate(attrs) => {
                    let props = load_property_template(parser.subtree_parser())?;
                    property_template.insert(attrs, props);
                },
            }
        }

        Ok(ObjectType {
            object_type: attrs,
            count: ensure_node_exists!(count, "ObjectType", "Count"),
            property_template: property_template,
        })
    }
}

child_attr_loader! { ObjectTypeChildAttrs {
    "Count" => Count(i32),
    "PropertyTemplate" => PropertyTemplate(String),
}}

fn load_property_template<R, P>(mut parser: P) -> Result<Properties70>
where
    R: ParserSource,
    P: Parser<R>,
{
    let mut props = None;

    loop {
        try_get_node_attrs!(parser, |name: &str, _| if name == "Properties70" {
            Ok(())
        } else {
            Err(Error::UnexpectedNode(name.to_owned()))
        });
        props = Some(Properties70::load(parser.subtree_parser())?);
    }
    Ok(ensure_node_exists!(
        props,
        "PropertyTemplate",
        "Properties70"
    ))
}
<commit_msg>Implement a utility function `Definitions::get_properties70`<commit_after>//! `Definitions` node and its children.

use fnv::FnvHashMap;
use parser::binary::{Parser, ParserSource, Attributes};
use loader::binary::simple::{Result, Error};
use loader::binary::simple::fbx7400::Properties70;

/// `Definitions` node.
#[derive(Debug, Clone, PartialEq)]
pub struct Definitions {
    /// Version of the node.
    pub version: i32,
    /// Reference count?
    pub count: i32,
    /// Property templates for object types.
    pub object_types: Vec<ObjectType>,
}

impl Definitions {
    /// Loads node contents from the parser.
    pub fn load<R, P>(mut parser: P) -> Result<Self>
    where
        R: ParserSource,
        P: Parser<R>,
    {
        let mut version = None;
        let mut count = None;
        let mut object_types = Vec::new();

        loop {
            let node_type = try_get_node_attrs!(parser, DefinitionsChildAttrs::load);
            match node_type {
                DefinitionsChildAttrs::Version(v) => {
                    version = Some(v);
                    parser.skip_current_node()?;
                },
                DefinitionsChildAttrs::Count(v) => {
                    count = Some(v);
                    parser.skip_current_node()?;
                },
                DefinitionsChildAttrs::ObjectType(attrs) => {
                    object_types.push(ObjectType::load(parser.subtree_parser(), attrs)?);
                },
            }
        }
        Ok(Definitions {
            version: ensure_node_exists!(version, "Definitions", "Version"),
            count: ensure_node_exists!(count, "Definitions", "Count"),
            object_types: object_types,
        })
    }

    /// Returns reference to `Properties70` object of the specified node.
    pub fn get_properties70(&self, object_type: &str, node_type: &str) -> Option<&Properties70> {
        self.object_types
            .iter()
            .find(|t| t.object_type == object_type)
            .and_then(|t| t.property_template.get(node_type))
    }
}

child_attr_loader! { DefinitionsChildAttrs {
    "Count" => Count(i32),
    "Version" => Version(i32),
    "ObjectType" => ObjectType(String),
}}

/// An object type and property template for it.
#[derive(Debug, Clone, PartialEq)]
pub struct ObjectType {
    /// Target object type.
    pub object_type: String,
    /// Reference count?
    pub count: i32,
    /// Property templates.
    pub property_template: FnvHashMap<String, Properties70>,
}

impl ObjectType {
    /// Loads node contents from the parser.
    pub fn load<R, P>(mut parser: P, attrs: String) -> Result<Self>
    where
        R: ParserSource,
        P: Parser<R>,
    {
        let mut count = None;
        let mut property_template = FnvHashMap::default();

        loop {
            let node_type = try_get_node_attrs!(parser, ObjectTypeChildAttrs::load);
            match node_type {
                ObjectTypeChildAttrs::Count(v) => {
                    count = Some(v);
                    parser.skip_current_node()?;
                },
                ObjectTypeChildAttrs::PropertyTemplate(attrs) => {
                    let props = load_property_template(parser.subtree_parser())?;
                    property_template.insert(attrs, props);
                },
            }
        }

        Ok(ObjectType {
            object_type: attrs,
            count: ensure_node_exists!(count, "ObjectType", "Count"),
            property_template: property_template,
        })
    }
}

child_attr_loader! { ObjectTypeChildAttrs {
    "Count" => Count(i32),
    "PropertyTemplate" => PropertyTemplate(String),
}}

fn load_property_template<R, P>(mut parser: P) -> Result<Properties70>
where
    R: ParserSource,
    P: Parser<R>,
{
    let mut props = None;

    loop {
        try_get_node_attrs!(parser, |name: &str, _| if name == "Properties70" {
            Ok(())
        } else {
            Err(Error::UnexpectedNode(name.to_owned()))
        });
        props = Some(Properties70::load(parser.subtree_parser())?);
    }
    Ok(ensure_node_exists!(
        props,
        "PropertyTemplate",
        "Properties70"
    ))
}
<|endoftext|>


<commit_before>use std::ptr;

use libc::{c_void, size_t};
use libc::funcs::c95::stdlib::{free, malloc};

use super::Options;

pub unsafe fn compress(options: *const Options, input: *const u8, insize: usize, out: *mut *mut u8, outsize: *mut usize) {
    *out = malloc(insize as u64) as *mut u8;
    ptr::copy_nonoverlapping(input, *out, insize);
    *outsize = insize;
}
<commit_msg>Add zlib_container.rs<commit_after>//! Functions to compress according to the Zlib specification.

use std::io::Write;

use super::Options;

use deflate::deflate;

/// Calculates the adler32 checksum of the data
unsafe fn adler32(mut data: *const u8, mut size: usize) -> u32 {
    const SUMS_OVERFLOW: u32 = 5550;
    let mut s1: u32 = 1;
    let mut s2: u32 = 1 >> 16;

    while size > 0 {
        let mut amount: usize = if size > SUMS_OVERFLOW as usize { SUMS_OVERFLOW as usize } else { size };
        size -= amount;
        while amount > 0 {
            s1 += *data as u32;
            data = data.offset(1);
            s2 += s1;
            amount -= 1;
        }
        s1 %= 65521;
        s2 %= 65521;
    }

    (s2 << 16) | s1
}

/**
 * Compresses according to the zlib specification and append the compressed
 * result to the output.
 *
 * options: global program options
 * out: pointer to the dynamic output array to which the result is appended. Must
 *   be freed after use.
 * outsize: pointer to the dynamic output array size.
 */
pub unsafe fn compress(options: *const Options, input: *const u8, insize: usize, out: *mut *mut u8, outsize: *mut usize) {
    let mut bitpointer: u8 = 0;
    let checksum: u32 = adler32(input, insize as u32 as usize);
    let cmf: u32 = 120; // CM 8, CINFO 7. See zlib spec.
    let flevel: u32 = 0;
    let fdict: u32 = 0;
    let mut cmfflg: u32 = 256 * cmf + fdict * 32 + flevel * 64;
    let fcheck: u32 = 31 - cmfflg % 31;
    cmfflg += fcheck;

    append_data!((cmfflg / 256) as u8, *out, *outsize);
    append_data!((cmfflg % 256) as u8, *out, *outsize);

    deflate(options, 2 /* dynamic block */, true /* final */, input, insize, &mut bitpointer, out, outsize);

    append_data!(((checksum >> 24) % 256) as u8, *out, *outsize);
    append_data!(((checksum >> 16) % 256) as u8, *out, *outsize);
    append_data!(((checksum >> 8) % 256) as u8, *out, *outsize);
    append_data!((checksum % 256) as u8, *out, *outsize);

    if (*options).verbose {
        println_err!("Original Size: {}, Zlib: {}, Compression: {}% Removed", insize, *outsize, 100.0 * (insize - *outsize) as f64 / insize as f64);
    }
}
<|endoftext|>


<commit_before>use std::hash::{Hash, Hasher, SipHasher};
use std::borrow::Borrow;

struct Node<K, V> {
    key: K,
    val: V,
    next: Option<Box<Node<K, V>>>
}

impl<K, V> Node<K, V> {
    pub fn size(&self) -> usize {
        if self.next.is_none() {
            1
        } else {
            1 + self.next.as_ref().unwrap().size()
        }
    }
}

fn delete<K: PartialEq, V>(x: Option<Box<Node<K, V>>> , key: &K) -> Option<Box<Node<K, V>>> {
    match x {
        None => None,
        Some(mut x) => {
            let next = x.next.take();
            if x.key == *key {
                next            // this will drop x
            } else {
                x.next = delete(next, key);
                Some(x)
            }
        }
    }
}

pub struct SeparateChainingHashST<K, V> {
    st: Vec<Option<Box<Node<K, V>>>>
}

const M: usize = 97;

impl<K: Hash + PartialEq, V> SeparateChainingHashST<K, V> {
    pub fn new() -> SeparateChainingHashST<K, V> {
        let mut st = Vec::with_capacity(M);
        for _ in 0 .. M {
            st.push(None);
        }
        SeparateChainingHashST {
            st: st
        }
    }

    fn hash(key: &K) -> usize {
        let mut hasher = SipHasher::new();
        key.hash(&mut hasher);
        hasher.finish() as usize % M
    }

    pub fn get<T: Borrow<K>>(&self, key: T) -> Option<&V> {
        let key = key.borrow();
        let i = Self::hash(key);
        let mut x = self.st[i].as_ref();
        while x.is_some() {
            if *key == x.unwrap().key {
                return Some(&x.unwrap().val)
            }
            x = x.unwrap().next.as_ref();
        }
        None
    }

    pub fn put(&mut self, key: K, val: V) {
        let i = Self::hash(&key);
        {
            let mut x = self.st[i].as_mut();
            while x.is_some() {
                if key.eq(&x.as_ref().unwrap().key) {
                    x.unwrap().val = val;
                    return;
                } else {
                    x = x.unwrap().next.as_mut();
                }
            }
        }
        let old = self.st[i].take();
        self.st[i] = Some(Box::new(Node { key: key, val: val, next: old }))
    }

    pub fn delete(&mut self, key: &K) {
        let i = Self::hash(&key);
        self.st[i] = delete(self.st[i].take(), key);
    }

    pub fn size(&self) -> usize {
        self.st.iter().filter(|n| n.is_some()).map(|h| h.as_ref().unwrap().size()).sum()
    }
}

#[test]
fn test_separate_chaining_st() {
    let mut m = SeparateChainingHashST::new();
    assert_eq!(m.size(), 0);
    m.put("Name", "Feather");
    m.put("Age", "25");
    m.put("Address", "Beijing");

    assert_eq!(m.size(), 3);
    assert_eq!(m.get("Age"), Some(&"25"));
    assert_eq!(m.get("Gender"), None);

    m.delete(&"Age");
    assert_eq!(m.size(), 2);
    assert_eq!(m.get("Age"), None);
}
<commit_msg>hash_tables/separate_chaining: trying avoid using unwrap()<commit_after>use std::hash::{Hash, Hasher, SipHasher};
use std::borrow::Borrow;

const M: usize = 97;

struct Node<K, V> {
    key: K,
    val: V,
    next: Option<Box<Node<K, V>>>
}

impl<K, V> Node<K, V> {
    pub fn size(&self) -> usize {
        match self.next {
            None => 1,
            Some(ref next) => 1 + next.size()
        }
    }
}

fn delete<K: PartialEq, V>(x: Option<Box<Node<K, V>>> , key: &K) -> Option<Box<Node<K, V>>> {
    if let Some(mut x) = x {
        let next = x.next.take();
        if x.key == *key {
            next            // this will drop x
        } else {
            x.next = delete(next, key);
            Some(x)
        }
    } else {
        None
    }
}

pub struct SeparateChainingHashST<K, V> {
    st: Vec<Option<Box<Node<K, V>>>>
}

impl<K: Hash + PartialEq, V> SeparateChainingHashST<K, V> {
    pub fn new() -> SeparateChainingHashST<K, V> {
        let mut st = Vec::with_capacity(M);
        (0..M).map(|_| st.push(None)).count();
        SeparateChainingHashST {
            st: st
        }
    }

    fn hash(key: &K) -> usize {
        let mut hasher = SipHasher::new();
        key.hash(&mut hasher);
        hasher.finish() as usize % M
    }

    pub fn get<T: Borrow<K>>(&self, key: T) -> Option<&V> {
        let key = key.borrow();
        let i = Self::hash(key);
        let mut x = self.st[i].as_ref();
        while x.is_some() {
            if *key == x.unwrap().key {
                return Some(&x.unwrap().val)
            }
            x = x.unwrap().next.as_ref();
        }
        None
    }

    pub fn put(&mut self, key: K, val: V) {
        let i = Self::hash(&key);
        {
            let mut x = self.st[i].as_mut();
            while x.is_some() {
                if x.as_ref().map(|x| x.key == key).unwrap_or(false) {
                    x.map(|x| x.val = val);
                    return;
                } else {
                    x = x.unwrap().next.as_mut();
                }
            }
        }
        let old = self.st[i].take();
        self.st[i] = Some(Box::new(Node { key: key, val: val, next: old }))
    }

    pub fn delete(&mut self, key: &K) {
        let i = Self::hash(&key);
        self.st[i] = delete(self.st[i].take(), key);
    }

    pub fn size(&self) -> usize {
        self.st.iter().filter(|n| n.is_some()).map(|h| h.as_ref().unwrap().size()).sum()
    }
}

#[test]
fn test_separate_chaining_st() {
    let mut m = SeparateChainingHashST::new();
    assert_eq!(m.size(), 0);
    m.put("Name", "Feather");
    m.put("Age", "25");
    m.put("Address", "Beijing");

    assert_eq!(m.size(), 3);
    assert_eq!(m.get("Age"), Some(&"25"));
    assert_eq!(m.get("Gender"), None);

    m.delete(&"Age");
    assert_eq!(m.size(), 2);
    assert_eq!(m.get("Age"), None);
}
<|endoftext|>


<commit_before>#![warn(clippy::needless_range_loop)]

fn calc_idx(i: usize) -> usize {
    (i + i + 20) % 4
}

fn main() {
    let ns = vec![2, 3, 5, 7];

    for i in 3..10 {
        println!("{}", ns[i]);
    }

    for i in 3..10 {
        println!("{}", ns[i % 4]);
    }

    for i in 3..10 {
        println!("{}", ns[i % ns.len()]);
    }

    for i in 3..10 {
        println!("{}", ns[calc_idx(i)]);
    }

    for i in 3..10 {
        println!("{}", ns[calc_idx(i) % 4]);
    }

    let mut ms = vec![1, 2, 3, 4, 5, 6];
    for i in 0..ms.len() {
        ms[i] *= 2;
    }
    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);

    let mut ms = vec![1, 2, 3, 4, 5, 6];
    for i in 0..ms.len() {
        let x = &mut ms[i];
        *x *= 2;
    }
    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);

    let g = vec![1, 2, 3, 4, 5, 6];
    let glen = g.len();
    for i in 0..glen {
        let x: u32 = g[i + 1..].iter().sum();
        println!("{}", g[i] + x);
    }
    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);

    let mut g = vec![1, 2, 3, 4, 5, 6];
    let glen = g.len();
    for i in 0..glen {
        g[i] = g[i + 1..].iter().sum();
    }
    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);

    let x = 5;
    let mut vec = vec![0; 9];

    for i in x..x + 4 {
        vec[i] += 1;
    }

    let x = 5;
    let mut vec = vec![0; 10];

    for i in x..=x + 4 {
        vec[i] += 1;
    }

    let arr = [1, 2, 3];

    for i in 0..3 {
        println!("{}", arr[i]);
    }

    for i in 0..2 {
        println!("{}", arr[i]);
    }

    for i in 1..3 {
        println!("{}", arr[i]);
    }
}
<commit_msg>Auto merge of #5798 - mikerite:fix-2277-2, r=yaahc<commit_after>#![warn(clippy::needless_range_loop)]

fn calc_idx(i: usize) -> usize {
    (i + i + 20) % 4
}

fn main() {
    let ns = vec![2, 3, 5, 7];

    for i in 3..10 {
        println!("{}", ns[i]);
    }

    for i in 3..10 {
        println!("{}", ns[i % 4]);
    }

    for i in 3..10 {
        println!("{}", ns[i % ns.len()]);
    }

    for i in 3..10 {
        println!("{}", ns[calc_idx(i)]);
    }

    for i in 3..10 {
        println!("{}", ns[calc_idx(i) % 4]);
    }

    let mut ms = vec![1, 2, 3, 4, 5, 6];
    for i in 0..ms.len() {
        ms[i] *= 2;
    }
    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);

    let mut ms = vec![1, 2, 3, 4, 5, 6];
    for i in 0..ms.len() {
        let x = &mut ms[i];
        *x *= 2;
    }
    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);

    let g = vec![1, 2, 3, 4, 5, 6];
    let glen = g.len();
    for i in 0..glen {
        let x: u32 = g[i + 1..].iter().sum();
        println!("{}", g[i] + x);
    }
    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);

    let mut g = vec![1, 2, 3, 4, 5, 6];
    let glen = g.len();
    for i in 0..glen {
        g[i] = g[i + 1..].iter().sum();
    }
    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);

    let x = 5;
    let mut vec = vec![0; 9];

    for i in x..x + 4 {
        vec[i] += 1;
    }

    let x = 5;
    let mut vec = vec![0; 10];

    for i in x..=x + 4 {
        vec[i] += 1;
    }

    let arr = [1, 2, 3];

    for i in 0..3 {
        println!("{}", arr[i]);
    }

    for i in 0..2 {
        println!("{}", arr[i]);
    }

    for i in 1..3 {
        println!("{}", arr[i]);
    }
}

mod issue2277 {
    pub fn example(list: &[[f64; 3]]) {
        let mut x: [f64; 3] = [10.; 3];

        for i in 0..3 {
            x[i] = list.iter().map(|item| item[i]).sum::<f64>();
        }
    }
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/largest-merge-of-two-strings/
pub fn largest_merge(word1: String, word2: String) -> String {
    todo!()
}

fn main() {
    println!(
        "{}",
        largest_merge(String::from("cabaa"), String::from("bcaaa"))
    ); // "cbcabaaaaa"
    println!(
        "{}",
        largest_merge(String::from("abcabc"), String::from("abdcaba"))
    ); // "abdcabcabcaba"
    println!(
        "{}",
        largest_merge(String::from("abb"), String::from("acde"))
    ); // "acdeabb"
}
<commit_msg>Solve problem 1754<commit_after>// https://leetcode.com/problems/largest-merge-of-two-strings/
pub fn largest_merge(word1: String, word2: String) -> String {
    let mut answer = String::from("");
    let chars1: Vec<char> = word1.chars().collect();
    let chars2: Vec<char> = word2.chars().collect();
    let mut i = 0;
    let mut j = 0;
    while i < chars1.len() && j < chars2.len() {
        if chars1[i] > chars2[j] {
            answer.push(chars1[i]);
            i += 1;
        } else if chars1[i] < chars2[j] {
            answer.push(chars2[j]);
            j += 1;
        } else {
            answer.push(chars1[i]);
            if word1[i..] >= word2[j..] {
                i += 1;
            } else {
                j += 1;
            }
        }
    }
    if i < chars1.len() {
        answer.push_str(&word1[i..]);
    } else {
        answer.push_str(&word2[j..]);
    }
    answer
}

fn main() {
    println!(
        "{}",
        largest_merge(String::from("cabaa"), String::from("bcaaa"))
    ); // "cbcabaaaaa"
    println!(
        "{}",
        largest_merge(String::from("abcabc"), String::from("abdcaba"))
    ); // "abdcabcabcaba"
    println!(
        "{}",
        largest_merge(String::from("abb"), String::from("acde"))
    ); // "acdeabb"
    println!(
        "{}",
        largest_merge(String::from("bbbaba"), String::from("bbbd"))
    ); // "bbbdbbbaba"
    println!(
        "{}",
        largest_merge(
            String::from("qqqqqqqqqeqeqqeeqqq"),
            String::from("qqqqqqqqeqqqeeqqeeqqqqqeq")
        )
    ); // "qqqqqqqqqqqqqqqqqeqqqeqeqqeeqqqeeqqeeqqqqqeq"
    println!(
        "{}",
        largest_merge(
            String::from("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
            String::from("bbbbbbbbbbbbbbbbbbbb")
        )
    ); // "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
<|endoftext|>


<commit_before>// 32-bit fixed point. Haven't decided on the fractional bits yet

extern crate int_traits;

use std::cmp::Ordering;
use std::cmp::PartialOrd;
use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use self::int_traits::IntTraits;

type Int = i32;
type DoubleInt = i64;

// Adjust this to balance between range and granularity
// 6 --> 20.12
// 8 --> 16.16
// 10 --> 12.20
pub const HALF_FRACTIONAL_BITS: Int = 8;

pub const FRACTIONAL_BITS: Int = HALF_FRACTIONAL_BITS * 2;
pub const DENOMINATOR: Int = 1 << FRACTIONAL_BITS;

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32 {
	pub x: Int,
}

impl Fx32 {
	pub fn new (x: Int) -> Fx32 {
		Fx32 {
			x: x,
		}
	}

	pub fn from_float (x: f32) -> Fx32 {
		Fx32::new ((x * DENOMINATOR as f32) as Int)
	}

	pub fn from_q (num: Int, den: Int) -> Fx32 {
		Fx32::new ((num << FRACTIONAL_BITS) / den)
	}

	pub fn from_int (x: Int) -> Fx32 {
		Fx32::from_q (x, 1)
	}

	pub fn to_f64 (&self) -> f64 {
		self.x as f64 / DENOMINATOR as f64
	}

	pub fn to_i32 (&self) -> i32 {
		self.x >> FRACTIONAL_BITS
	}
	/*
	pub fn to_small (self) -> Fx32Small {
		assert! (self.abs () < 2);
		Fx32Small {
			x: self,
		}
	}
	*/
	pub fn abs (&self) -> Fx32 {
		Fx32::new (self.x.abs ())
	}

	// More precise and automatic but requires a branch
	pub fn mul_precise (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		if a.abs () > b.abs () {
			Fx32::new ((a >> HALF_FRACTIONAL_BITS) * (b) >> HALF_FRACTIONAL_BITS)
		}
		else {
			Fx32::new ((a) * (b >> HALF_FRACTIONAL_BITS) >> HALF_FRACTIONAL_BITS)
		}
	}

	// For multiplying two numbers <= 1.0 such as
	// color mixing or dotting unit vectors
	pub fn mul_small (&self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		Fx32::new (((a / 2) * (b / 2)) >> (FRACTIONAL_BITS - 2))
	}

	pub fn mul_big (&self, o: Fx32) -> Fx32 {
		/*
		let c be the fixed point 'factor'
		a = 1.0
		b = 2.0
		c = 65536

		(a * c) * (b * c) ---> (a * b * c)

		We must end up dividing by c
		We can do this by dividing both a and b by root c
		*/

		Fx32::new ((self.x >> HALF_FRACTIONAL_BITS) * (o.x >> HALF_FRACTIONAL_BITS))
	}

	/*
	I think this is the canonical way to do it,
	but it does require i64. Will need performance testing
	on the Pandora.

	I would recommend starting with this as a reference,
	and dropping precision where we can afford it based on
	regression testing.
	*/
	pub fn mul_64 (self, o: Fx32) -> Fx32 {
		let c = self.x as DoubleInt * o.x as DoubleInt;
		Fx32::new ((c >> FRACTIONAL_BITS as DoubleInt) as Int)
	}

	pub fn div_64 (self, o: Fx32) -> Fx32 {
		let a2 = (self.x as DoubleInt) << FRACTIONAL_BITS as DoubleInt;
		Fx32::new ((a2 / o.x as DoubleInt) as Int)
	}

	pub fn square_64 (self) -> Fx32 {
		Fx32::mul_64 (self, self)
	}

	pub fn sqrt_64 (self) -> Fx32 {
		Fx32 {
			x: ((self.x as DoubleInt) << FRACTIONAL_BITS).sqrt () as Int,
		}
	}
}
/*
impl fmt::Debug for Fx32 {
    fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
        write! (f, "Fx32 ({})", self.to_f64 ())
    }
}
*/
impl Add <Fx32> for Fx32 {
	type Output = Fx32;

	fn add (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}
/*
// This is stupid
impl <'a, 'b> Add <&'a Fx32> for &'b Fx32 {
	type Output = Fx32;

	fn add (self, o: &'a Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}
*/
impl Sub <Fx32> for Fx32 {
	type Output = Fx32;

	fn sub (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x - o.x)
	}
}

impl Neg for Fx32 {
	type Output = Fx32;

	fn neg (self) -> Fx32 {
		Fx32::new (-self.x)
	}
}

impl Mul <Fx32> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		Fx32::mul_64 (self, o)
	}
}

impl Div <Fx32> for Fx32 {
	type Output = Fx32;

	fn div (self, o: Fx32) -> Fx32 {
		Fx32::div_64 (self, o)
	}
}

impl PartialOrd for Fx32 {
	fn partial_cmp (&self, o: &Fx32) -> Option <Ordering> {
		self.x.partial_cmp (&o.x)
	}
}

impl PartialEq <i32> for Fx32 {
	fn eq (&self, o: &i32) -> bool {
		self.x == Fx32::from_int (*o).x
	}
}

impl PartialOrd <i32> for Fx32 {
	fn partial_cmp (&self, o: &i32) -> Option <Ordering> {
		self.x.partial_cmp (&Fx32::from_int (*o).x)
	}
}

/*
A specialized fixed-point number with the same fractional bits,
but compile-time hints that it should fall in the range (-2.0, +2.0)
and asserts.

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32Small {
	pub x: Fx32,
}

impl Fx32Small {
	pub fn mul_by_big (o: Fx32) -> Fx32 {

	}
}

impl Mul <Fx32Small> for Fx32 {

}
*/
<commit_msg>Adding Fx32Small type for numbers near +/-1.0 or smaller<commit_after>// 32-bit fixed point. Haven't decided on the fractional bits yet

extern crate int_traits;

use std::cmp::Ordering;
use std::cmp::PartialOrd;
use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use self::int_traits::IntTraits;

type Int = i32;
type DoubleInt = i64;

// Adjust this to balance between range and granularity
// 6 --> 20.12
// 8 --> 16.16
// 10 --> 12.20
pub const HALF_FRACTIONAL_BITS: Int = 8;

pub const FRACTIONAL_BITS: Int = HALF_FRACTIONAL_BITS * 2;
pub const DENOMINATOR: Int = 1 << FRACTIONAL_BITS;

#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32 {
	pub x: Int,
}

impl Fx32 {
	pub fn new (x: Int) -> Fx32 {
		Fx32 {
			x: x,
		}
	}

	pub fn from_float (x: f32) -> Fx32 {
		Fx32::new ((x * DENOMINATOR as f32) as Int)
	}

	pub fn from_q (num: Int, den: Int) -> Fx32 {
		Fx32::new ((num << FRACTIONAL_BITS) / den)
	}

	pub fn from_int (x: Int) -> Fx32 {
		Fx32::from_q (x, 1)
	}

	pub fn to_f64 (&self) -> f64 {
		self.x as f64 / DENOMINATOR as f64
	}

	pub fn to_i32 (&self) -> i32 {
		self.x >> FRACTIONAL_BITS
	}

	pub fn to_small (self) -> Fx32Small {
		assert! (self.abs () < 2);
		Fx32Small {
			x: self,
		}
	}

	pub fn abs (&self) -> Fx32 {
		Fx32::new (self.x.abs ())
	}

	// More precise and automatic but requires a branch
	pub fn mul_precise (self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		if a.abs () > b.abs () {
			Fx32::new ((a >> HALF_FRACTIONAL_BITS) * (b) >> HALF_FRACTIONAL_BITS)
		}
		else {
			Fx32::new ((a) * (b >> HALF_FRACTIONAL_BITS) >> HALF_FRACTIONAL_BITS)
		}
	}

	// For multiplying two numbers <= 1.0 such as
	// color mixing or dotting unit vectors
	pub fn mul_small (&self, o: Fx32) -> Fx32 {
		let a = self.x;
		let b = o.x;

		Fx32::new (((a / 2) * (b / 2)) >> (FRACTIONAL_BITS - 2))
	}

	pub fn mul_big (&self, o: Fx32) -> Fx32 {
		/*
		let c be the fixed point 'factor'
		a = 1.0
		b = 2.0
		c = 65536

		(a * c) * (b * c) ---> (a * b * c)

		We must end up dividing by c
		We can do this by dividing both a and b by root c
		*/

		Fx32::new ((self.x >> HALF_FRACTIONAL_BITS) * (o.x >> HALF_FRACTIONAL_BITS))
	}

	/*
	I think this is the canonical way to do it,
	but it does require i64. Will need performance testing
	on the Pandora.

	I would recommend starting with this as a reference,
	and dropping precision where we can afford it based on
	regression testing.
	*/
	pub fn mul_64 (self, o: Fx32) -> Fx32 {
		let c = self.x as DoubleInt * o.x as DoubleInt;
		Fx32::new ((c >> FRACTIONAL_BITS as DoubleInt) as Int)
	}

	pub fn div_64 (self, o: Fx32) -> Fx32 {
		let a2 = (self.x as DoubleInt) << FRACTIONAL_BITS as DoubleInt;
		Fx32::new ((a2 / o.x as DoubleInt) as Int)
	}

	pub fn square_64 (self) -> Fx32 {
		Fx32::mul_64 (self, self)
	}

	pub fn sqrt_64 (self) -> Fx32 {
		Fx32 {
			x: ((self.x as DoubleInt) << FRACTIONAL_BITS).sqrt () as Int,
		}
	}
}
/*
impl fmt::Debug for Fx32 {
    fn fmt (&self, f: &mut fmt::Formatter) -> fmt::Result {
        write! (f, "Fx32 ({})", self.to_f64 ())
    }
}
*/
impl Add <Fx32> for Fx32 {
	type Output = Fx32;

	fn add (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x + o.x)
	}
}

impl Sub <Fx32> for Fx32 {
	type Output = Fx32;

	fn sub (self, o: Fx32) -> Fx32 {
		Fx32::new (self.x - o.x)
	}
}

impl Neg for Fx32 {
	type Output = Fx32;

	fn neg (self) -> Fx32 {
		Fx32::new (-self.x)
	}
}

impl Mul <Fx32> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		Fx32::mul_big (&self, o)
	}
}

impl Div <Fx32> for Fx32 {
	type Output = Fx32;

	fn div (self, o: Fx32) -> Fx32 {
		Fx32::div_64 (self, o)
	}
}

impl PartialOrd for Fx32 {
	fn partial_cmp (&self, o: &Fx32) -> Option <Ordering> {
		self.x.partial_cmp (&o.x)
	}
}

impl PartialEq <i32> for Fx32 {
	fn eq (&self, o: &i32) -> bool {
		self.x == Fx32::from_int (*o).x
	}
}

impl PartialOrd <i32> for Fx32 {
	fn partial_cmp (&self, o: &i32) -> Option <Ordering> {
		self.x.partial_cmp (&Fx32::from_int (*o).x)
	}
}
/*
A specialized fixed-point number with the same fractional bits,
but compile-time hints that it should fall in the range (-2.0, +2.0)
and asserts.
*/
#[derive (Clone, Copy, Debug, Eq, PartialEq)]
pub struct Fx32Small {
	pub x: Fx32,
}

impl Fx32Small {
	pub fn mul_by_big (self, o: Fx32) -> Fx32 {
		// Assert for headroom on the big number
		assert! (o.abs () < 1 << (FRACTIONAL_BITS - 2));

		Fx32 {
			x: (o.x >> (FRACTIONAL_BITS - 2) * self.x.x) >> 2
		}
	}
}

impl Mul <Fx32Small> for Fx32 {
	type Output = Fx32;

	fn mul (self, o: Fx32Small) -> Fx32 {
		o.mul_by_big (self)
	}
}

impl Mul <Fx32> for Fx32Small {
	type Output = Fx32;

	fn mul (self, o: Fx32) -> Fx32 {
		self.mul_by_big (o)
	}
}
<|endoftext|>


<commit_before>use engine::Game;
use gui::screens::{self, Screen, ScreenChange};
use gui::{Console, Colors, Key};
use gui::chars;
use util::units::{Direction, Point};

#[allow(missing_copy_implementations)]
pub struct GameScreen {
    map_location: Point,
    info_location: Point,
    message_location: Point,
}

impl GameScreen {
    pub fn new() -> Box<Screen> {
        Box::new(
            GameScreen {
                map_location: Point::new(16, 1),
                info_location: Point::new(1, 1),
                message_location: Point::new(16, 41),
            }
        )
    }
}

impl Screen for GameScreen {

    #[allow(unused)]
    fn input(&mut self, game: &mut Game, console: &mut Console) -> Option<ScreenChange> {
        if let Some(key) = console.check_for_keypress() {
            match key {
                Key::Up => {
                    game.world.walk(Direction::Up);
                },
                Key::Down => {
                    game.world.walk(Direction::Down);
                },
                Key::Left => {
                    game.world.walk(Direction::Left);
                },
                Key::Right => {
                    game.world.walk(Direction::Right);
                },
                Key::Escape => {
                    return Some(ScreenChange::AddScreen(screens::PauseScreen::new()));
                },
                _ => {}
            }
        }

        None
    }

    #[allow(unused)]
    fn update(&mut self, game: &mut Game, console: &mut Console) -> Option<ScreenChange> {
        return None;
    }

    #[allow(unused)]
    fn render(&mut self, game: &mut Game, console: &mut Console) {
        self.render_map(game, console);

        let repr = game.world.player.repr;
        let pos = game.world.player.pos;

        console.put_plain(self.map_location + pos, repr);

        self.draw_borders(game, console);
    }
}

impl GameScreen {

    #[allow(unused)]
    fn draw_borders(&self, game: &mut Game, console: &mut Console) {
        self.draw_box(console, self.map_location + Point::new(-1, -1), 64, 39);
        console.print_plain(self.map_location + Point::new(0, -1), "Map");

        self.draw_box(console, self.info_location + Point::new(-1, -1), 14, 49);
        console.print_plain(self.info_location + Point::new(0, -1), "Info");

        self.draw_box(console, self.message_location + Point::new(-1, -1), 64, 9);
        console.print_plain(self.message_location + Point::new(0, -1), "Messages");
    }

    fn draw_box(&self, console: &mut Console, loc: Point, width: i32, height: i32) {
        console.put_plain(loc + Point::new(0, 0), chars::NW as char);
        console.put_plain(loc + Point::new(width, 0), chars::NE as char);
        console.put_plain(loc + Point::new(0, height), chars::SW as char);
        console.put_plain(loc + Point::new(width, height), chars::SE as char);

        for x in 1..width {
            console.put_plain(loc + Point::new(x, 0), chars::HLINE as char);
            console.put_plain(loc + Point::new(x, height), chars::HLINE as char);
        }

        for y in 1..height {
            console.put_plain(loc + Point::new(0, y), chars::VLINE as char);
            console.put_plain(loc + Point::new(width, y), chars::VLINE as char);
        }
    }

    #[allow(unused)]
    fn render_map(&self, game: &mut Game, console: &mut Console) {
        let map = &(game.world.map);

        let (width, height) = (63, 38);

        for (y, line) in map.tiles[0..height].iter().enumerate() {
            for (x, cell) in line[0..width].iter().enumerate() {
                console.put(self.map_location + Point::new(x as i32, y as i32), ' ', Colors::white, cell.b_color());
            }
        }
    }

}
<commit_msg>Draw window borders using rectangles<commit_after>use engine::Game;
use gui::screens::{self, Screen, ScreenChange};
use gui::{Console, Colors, Key};
use gui::chars;
use util::Rectangle;
use util::units::{Direction, Point, Size};

#[allow(missing_copy_implementations)]
pub struct GameScreen {
    map_frame: Rectangle,
    info_frame: Rectangle,
    message_frame: Rectangle,
}

impl GameScreen {
    pub fn new() -> Box<Screen> {
        Box::new(
            GameScreen {
                map_frame: Rectangle::new(Point::new(16, 1), Size::new(63, 38)),
                info_frame: Rectangle::new(Point::new(1, 1), Size::new(13, 48)),
                message_frame: Rectangle::new(Point::new(16, 41), Size::new(63, 8)),
            }
        )
    }
}

impl Screen for GameScreen {

    #[allow(unused)]
    fn input(&mut self, game: &mut Game, console: &mut Console) -> Option<ScreenChange> {
        if let Some(key) = console.check_for_keypress() {
            match key {
                Key::Up => {
                    game.world.walk(Direction::Up);
                },
                Key::Down => {
                    game.world.walk(Direction::Down);
                },
                Key::Left => {
                    game.world.walk(Direction::Left);
                },
                Key::Right => {
                    game.world.walk(Direction::Right);
                },
                Key::Escape => {
                    return Some(ScreenChange::AddScreen(screens::PauseScreen::new()));
                },
                _ => {}
            }
        }

        None
    }

    #[allow(unused)]
    fn update(&mut self, game: &mut Game, console: &mut Console) -> Option<ScreenChange> {
        return None;
    }

    #[allow(unused)]
    fn render(&mut self, game: &mut Game, console: &mut Console) {
        self.render_map(game, console);

        let repr = game.world.player.repr;
        let pos = game.world.player.pos;

        console.put_plain(self.map_frame.location() + pos, repr);

        self.draw_borders(game, console);
    }
}

impl GameScreen {

    #[allow(unused)]
    fn draw_borders(&self, game: &mut Game, console: &mut Console) {
        self.draw_box(console, self.map_frame.move_dir(Point::new(-1, -1)).resize(Size::new(1, 1)));
        console.print_plain(self.map_frame.move_dir(Point::new(0, -1)).location(), "Map");

        self.draw_box(console, self.info_frame.move_dir(Point::new(-1, -1)).resize(Size::new(1, 1)));
        console.print_plain(self.info_frame.move_dir(Point::new(0, -1)).location(), "Info");

        self.draw_box(console, self.message_frame.move_dir(Point::new(-1, -1)).resize(Size::new(1, 1)));
        console.print_plain(self.message_frame.move_dir(Point::new(0, -1)).location(), "Messages");
    }

    fn draw_box(&self, console: &mut Console, rect: Rectangle) {
        console.put_plain(rect.location() + Point::new(0, 0), chars::NW as char);
        console.put_plain(rect.location() + Point::new(rect.width(), 0), chars::NE as char);
        console.put_plain(rect.location() + Point::new(0, rect.height()), chars::SW as char);
        console.put_plain(rect.location() + Point::new(rect.width(), rect.height()), chars::SE as char);

        for x in 1..rect.width() {
            console.put_plain(rect.location() + Point::new(x, 0), chars::HLINE as char);
            console.put_plain(rect.location() + Point::new(x, rect.height()), chars::HLINE as char);
        }

        for y in 1..rect.height() {
            console.put_plain(rect.location() + Point::new(0, y), chars::VLINE as char);
            console.put_plain(rect.location() + Point::new(rect.width(), y), chars::VLINE as char);
        }
    }

    #[allow(unused)]
    fn render_map(&self, game: &mut Game, console: &mut Console) {
        let map = &(game.world.map);

        let (width, height) = (63, 38);

        for (y, line) in map.tiles[0..height].iter().enumerate() {
            for (x, cell) in line[0..width].iter().enumerate() {
                console.put(self.map_frame.location() + Point::new(x as i32, y as i32), ' ', Colors::white, cell.b_color());
            }
        }
    }

}
<|endoftext|>